⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ad7705源程序.txt

📁 这是在用的AD7705源程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
         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();
     eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_1+(cali_scale-1)*10), 8 );
     
     //保存第二份校准系数
     eeprom_busy_wait();
     eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_2+(cali_scale-1)*10), 8 );  
     
     //保存第三份校准系数
     eeprom_busy_wait();
     eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_3+(cali_scale-1)*10), 8 );
     
     Txout( &coefficient[0] );//输出校准数据给上位机
     
     return;     
}


//------------------------------------------------------------------------------------------
//函数:start_AD7705
//功能:先写offset寄存器,再写full scale寄存器,然后启动7705进行单次转换
//参数:uint8_t channel  -- 要进行A/D转换的通道号
//      uint8_t cali     -- 是第几次测量,电阻需要测量2次
//返回:无
//变量:无
//备注:
//------------------------------------------------------------------------------------------
void start_AD7705(void)
{
     reset_AD7705();
     
     //写OFFSET寄存器
     write_AD7705_byte( WR_OFFSET_REG );
     write_AD7705_dword( ZS );
     
     //写满量程校准寄存器
     write_AD7705_byte( WR_FULL_REG );
     write_AD7705_dword( GS );
     
     //CLOCK寄存器设置,无分频,50HZ输出更新速率
     write_AD7705_byte( WR_CLOCK_REG );
     write_AD7705_byte( CLOCK_REG_SET );
     
     //写设置寄存器
     write_AD7705_byte( WR_SETUP_REG );
     write_AD7705_byte( text_of_setup[scale-1] );
     
     start_timer0();
     while( time_count < time_read_data );//读取数据延时20ms左右,
     stop_timer0();
}
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -