ad7705单片机源程序如下:
- ------------AD7705头文件开始-------------------
- #ifndef _AD7705_H
- #define _AD7705_H
- //通讯寄存器地址定义
- #define WR_SETUP_REG 0x10 //选中写设置寄存器
- #define RD_SETUP_REG 0x18 //选中写设置寄存器
- #define WR_CLOCK_REG 0x20 //选中写时钟寄存器
- #define RD_DATA_REG 0x38 //选中数据寄存器读
- #define WR_OFFSET_REG 0x60 //选中写offset寄存器
- #define RD_OFFSET_REG 0x68 //选中读offset寄存器
- #define WR_FULL_REG 0x70 //选中写full scale寄存器
- #define RD_FULL_REG 0x78 //选中读full scale寄存器
- #define SYS_ZERO_CALI 0x80 //系统零校准模式
- #define SYS_FULL_CALI 0xC0 //系统满量程校准模式
- #define ZERO_CALIBRATION 0x00 //系统零校准
- #define FULL_CALIBRATION 0x01 //系统满量程校准
- //CLOCK寄存器设置,无分频,50HZ输出更新速率
- #define CLOCK_REG_SET 0X04
- //函数声明
- void reset_AD7705(void);
- unsigned char read_AD7705_byte(void);
- unsigned int read_AD7705_word(void);
- unsigned long int read_AD7705_dword(void);
- void write_AD7705_byte(unsigned char data);
- void write_AD7705_word(unsigned int data);
- void write_AD7705_dword(unsigned long int data);
- void ReadData7705(unsigned int *const pdata);
- void AD7705_calibration(void);
- void start_AD7705(void);
- #endif
- -----------AD7705主文件开始--------------
- #include <util/delay.h>
- #include <avr/eeprom.h>
- #include "ad7705.h"
- #include "main.h"
- #include "crc16.h"
- #include "Usart.h"
- //针对四个量程的设置寄存器的设置内容
- //(1)对于单极性V级别输入0-5V、0-20mA、0-10V这三个量程,输入范围为0-2V,无极性,增益为1,缓冲模式--0-2V
- //(2)对于双极性V级别输入+-2.5V、+-5V这两个量程,输入范围为+-1V,双极性,增益为2,缓冲模式--+-2V
- //(3)对于双精度mV级别输入+-500mV,增益为4,双极性,缓冲模式--+-2V
- //(4)对双精度mV级别+-50mV,增益为32,双极性,缓冲模式--+-1.6V
- //----MD1(0) MD0(0) G2(0) G1(0) G0(0) B/U(0) BUF(0) FSYNC(0)--------------------//
- const unsigned char text_of_setup[4]={0X06,0X0A,0X12,0X2A}; //缓冲模式,数字滤波同步
- extern volatile unsigned char command[7]; //校准命令全局数组
- extern volatile unsigned char scale; //记录系统量程
- extern volatile unsigned char NO_CALI_TYPE; //未校准类型
- extern volatile unsigned long int ZS,GS; //当前量程的校准系数
- extern volatile unsigned char time_count; //超时标志
- //----------------------------------------------------------------------------
- //函数:reset_AD7705
- //功能:AD7705串行接口失步后将其复位。复位后要延时500us再访问
- //参数:无
- //返回:无
- //变量:无
- //备注:无
- //----------------------------------------------------------------------------
- void reset_AD7705(void)
- {
- unsigned char i;
-
- AD_DIN1;
- for( i=0; i<36; i++ )
- {
- AD_CLK0;
- asm("nop");
- asm("nop");
- asm("nop");
- AD_CLK1;
- asm("nop");
- asm("nop");
- asm("nop");
- }
- _delay_us(30);
- }
- //------------------------------------------------------------------------------------------
- //函数:read_AD7705_byte
- //功能:从AD7705读一个字节的数据
- //参数:无
- //返回:读到的一字节数据
- //变量:无
- //备注:无
- //------------------------------------------------------------------------------------------
- unsigned char read_AD7705_byte(void)
- {
- unsigned char data = 0;
- unsigned char i = 0;
-
- for( i=0; i<8; i++ )
- {
- data <<= 1;
- AD_CLK0;
- asm("nop");
- asm("nop");
- asm("nop");
- if(AD_DOUT)
- {
- data++;
- }
- AD_CLK1;
- asm("nop");
- asm("nop");
- asm("nop");
- }
- return data;
- }
- //------------------------------------------------------------------------------------------
- //函数:read_AD7705_word
- //功能:从AD7705读一个字的数据,共16bit
- //参数:无
- //返回:读到的一字节数据
- //变量:无
- //备注:无
- //------------------------------------------------------------------------------------------
- unsigned int read_AD7705_word(void)
- {
- unsigned int data = 0;
- unsigned char i = 0;
-
- for( i=0; i<16; i++ )
- {
- data <<= 1;
- AD_CLK0;
- asm("nop");
- asm("nop");
- asm("nop");
- if(AD_DOUT)
- {
- data++;
- }
- AD_CLK1;
- asm("nop");
- asm("nop");
- asm("nop");
- }
- return data;
- }
- //------------------------------------------------------------------------------------------
- //函数:read_AD7705_dword
- //功能:从AD7705读一个24的数据
- //参数:无
- //返回:读到的一字节数据
- //变量:无
- //备注:AD7705是一个16位AD
- //------------------------------------------------------------------------------------------
- unsigned long int read_AD7705_dword(void)
- {
- unsigned long data = 0;
- unsigned char i = 0;
-
- for( i=0; i<24; i++ )
- {
- data <<= 1;
- AD_CLK0;
- asm("nop");
- asm("nop");
- asm("nop");
- if(AD_DOUT)
- {
- data++;
- }
- AD_CLK1;
- asm("nop");
- asm("nop");
- asm("nop");
- }
- return data;
- }
- //------------------------------------------------------------------------------------------
- //函数:write_AD7705_byte
- //功能:往AD7705写8位数据
- //参数:IN - uint8_t data,要写入AD7705的数据
- //返回:无
- //变量:无
- //备注:无
- //------------------------------------------------------------------------------------------
- void write_AD7705_byte(unsigned char data)
- {
- for(unsigned char i=0; i<8; i++)
- {
- AD_CLK0;
- if(data&0x80)
- AD_DIN1;
- else
- AD_DIN0;
- asm("nop");
- asm("nop");
- asm("nop");
- AD_CLK1;
- asm("nop");
- asm("nop");
- asm("nop");
- data <<= 1;
- }
- AD_DIN1;
- }
- //------------------------------------------------------------------------------------------
- //函数:write_AD7705_dword
- //功能:往AD7705写24位数据,因为AD7705是24位的器件
- //参数:IN - int32_t data,要写入AD7705的数据
- //返回:无
- //变量:无
- //备注:无
- //------------------------------------------------------------------------------------------
- void write_AD7705_dword(unsigned long int data)
- {
- for(unsigned char i = 0; i<24; i++)
- {
- AD_CLK0;
- if(data&0x800000)
- AD_DIN1;
- else
- AD_DIN0;
- asm("nop");
- asm("nop");
- asm("nop");
- AD_CLK1;
- asm("nop");
- asm("nop");
- asm("nop");
- data <<= 1;
- }
- AD_DIN1;
- }
- //------------------------------------------------------------------------------------------
- //函数:AD7705_calibration
- //功能:根据cali_type的值对AD7705进行系统0校正或系统满量程校正,并将各校正值和校正标志存入
- // EEPROM,数据保存为双备份。数据块格式为: 内部0校正值(4byte), 内部满量程校正值(4byte),
- // 系统0校正值(4byte), 系统满量程校正值(4byte), 系统0校正标志(1byte),系统满量程校正标志
- // (1byte),CRC16校验值(2byte),共20byte。
- //参数:IN - uint8_t board, 0 - 对主板进行校正,1-对副板进行校正
- // IN - uint8_t range, 需要校正的量程
- // IN - uint8_t cali_type, 校正类型,ZERO_CALIBRATION- 0校正;
- // FULL_CALIBRATION - 满量程校正
- //返回:返回-1表示校准失败,非0表示校正成功,并返回相应的索引值
- //变量:无
- //备注:做满量程校正前必须先做零校正
- //------------------------------------------------------------------------------------------
- //校准命令格式
- //STX Data Long Command Code Parameter CheckSum ETX
- //0x55 数据长度(2) 量程指示 00H/01H CRC16(2) 0x0D
- //
- //校准过程中要用到Command[]的数据,所以校准之前要关掉串口接收中断
- void AD7705_calibration(void)
- {
- //记录读取EEPROM的次数
- unsigned char readtimes =0;
-
- //记录上位机发送的校准量程类型
- unsigned char cali_scale =0;
-
- //读取24位校准系数的临时变量
- unsigned long int temp =0;
-
- //临时的校准系数数组,存放格式ZSL、ZSM、ZSH;GSL、GSM、GSH;CRCL、CRCH
- //并在校准结束时作为参数传递给TXOUT()函数,发送校准系数给上位机
- unsigned char coefficient[8] ={0}; //test[8]={0};
-
- //16位校验和的临时变量
- unsigned int crcvalue =0;
-
- AD_CS1;
-
- cali_scale = command[2]; //获取上位机发送的要校准的量程类型
-
- //读取EEPROM的第一份校准系数
- eeprom_busy_wait();
- eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_1+(cali_scale-1)*10), 8 );
- crcvalue = checksum( &coefficient[0], 6 ); //将6个值调用CRC校验函数得到校验
- if( (coefficient[7]*256+coefficient[6]) != crcvalue )
- {
- readtimes++;
- }
-
- //如果校准系数不可用则读取第二份
- if( 1 == readtimes )
- {
- eeprom_busy_wait();
- eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_2+(cali_scale-1)*10), 8 );
- crcvalue = checksum( &coefficient[0], 6 ); //将6个值调用CRC校验函数得到校验
- if( (coefficient[7]*256+coefficient[6]) != crcvalue )
- {
- readtimes++;
- }
- }
-
- //如果校准系数不可用则读取第三份
- if( 2 == readtimes )
- {
- eeprom_busy_wait();
- eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_3+(cali_scale-1)*10), 8 );
- }
-
- ADDR409_MASK; //切换到第一通道进行校准
-
- AD_CS0;
- _delay_us(5);
- reset_AD7705();
-
- //CLOCK寄存器设置,无分频,50HZ输出更新速率
- write_AD7705_byte( WR_CLOCK_REG );
- write_AD7705_byte( CLOCK_REG_SET );
-
- if( ZERO_CALIBRATION == command[3] ) //校准命令为零校准
- {
- //写设置寄存器,选择零校准
- write_AD7705_byte( WR_SETUP_REG );
- write_AD7705_byte( text_of_setup[cali_scale-1] | SYS_ZERO_CALI );
-
- //等待校准完成,系统校准延时时间
- start_timer0();
- while( time_count < time_sys_cali );
- stop_timer0();
-
- while( AD_DRDY );//若将滤波器同步位FSYNC置为1,AD_DRDY信号将不会变低,这里将一直是死循环
-
- //读OFFSET寄存器
- write_AD7705_byte( RD_OFFSET_REG );
- temp = read_AD7705_dword();
-
- if( cali_scale == scale)
- {
- ZS = temp; //如果是当前量程零校准还要更新ZS
- //如果是当前量程的校准,还要将NO_CALI_TYPE赋值为1表示已经经过零校准
- //更新上电没有校准时readEEPROM()函数的运行状态
- NO_CALI_TYPE = NO_FULL_CALIBRATION;
- }
-
- coefficient[0] = (unsigned char)( temp%256 );
- coefficient[1] = (unsigned char)( (temp/256)%256 );
- coefficient[2] = (unsigned char)( (temp/65536)%256 );
- }
- else if( FULL_CALIBRATION == command[3] )//系统满量程校准
- {
-
- //计算ZS,一定要作强制类型转换,否则将出现错误
- temp = (unsigned long int)(coefficient[0]) + (unsigned long int)(coefficient[1])*256
- + (unsigned long int)(coefficient[2])*65536;
-
- //将ZS写入到AD7705的OFFSET寄存器
- write_AD7705_byte( WR_OFFSET_REG );
- write_AD7705_dword( temp );
-
- //写设置寄存器,选择满量程校准
- write_AD7705_byte( WR_SETUP_REG );
- write_AD7705_byte( text_of_setup[cali_scale-1] | SYS_FULL_CALI );
-
- //等待校准完成,系统校准延时时间
- start_timer0();
- while( time_count < time_sys_cali );
- stop_timer0();
-
- while( AD_DRDY );//若将滤波器同步位FSYNC置为1,AD_DRDY信号将不会变低,这里将一直是死循环
-
- //读FULL寄存器
- write_AD7705_byte( RD_FULL_REG );
- temp = read_AD7705_dword();
-
- if( cali_scale == scale )
- {
- GS = temp; //如果是当前量程满量程校准还要更新GS
- //如果是当前量程的校准,还要将NO_CALI_TYPE赋值为2表示已经经过零校准
- //更新上电没有校准的情况,让readEEPROM()函数退出循环状态
- NO_CALI_TYPE = ALREADY_CALIBRATION;
- }
-
- coefficient[3] = (unsigned char)( temp%256 );
- coefficient[4] = (unsigned char)( (temp/256)%256 );
- coefficient[5] = (unsigned char)( (temp/65536)%256 );
- }
- else
- {
- AD_CS1;
- _delay_us(5);
- return;
- }
-
- AD_CS1;
- _delay_us(5);
-
- crcvalue = checksum(&coefficient[0],6); //将6个校准值调用CRC校验函数得到校验码
- coefficient[6] = (unsigned char)(crcvalue%256);//取校验值的高8位和低8位
- coefficient[7] = (unsigned char)(crcvalue/256);
-
- //保存第一份校准系数
- eeprom_busy_wait();
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
ad7705源程序.rar
(3.5 KB, 下载次数: 27)
|