[DemoCode下载] AD7705程序

[复制链接]
909|3
 楼主| secretuniverse 发表于 2016-3-28 20:48 | 显示全部楼层 |阅读模式
AD7705应用注意要点:
   (1) DRDY逻辑不要搞反,高电平时等待转换状态,低电平为可以读取转换数据
   (2) 系统校准时输入信号要大于所选量程的4/5,否则校准不到32767。
   (3) 校准时要等待一定的时间,读取数据也一样,不能超过转换速率。
   (4) 一般的应用只要内部校准,这个很简单,只要初始化就可以。如果测量范围不是芯片的范围,可以通过系统校准来实现,满量程校准电压要大于量程的4/5
  1. #include <util/delay.h>
  2. #include <avr/eeprom.h>
  3. #include "ad7705.h"
  4. #include "main.h"
  5. #include "crc16.h"
  6. #include "Usart.h"

  7. //针对四个量程的设置寄存器的设置内容
  8. //(1)对于单极性V级别输入0-5V、0-20mA、0-10V这三个量程,输入范围为0-2V,无极性,增益为1,缓冲模式--0-2V
  9. //(2)对于双极性V级别输入+-2.5V、+-5V这两个量程,输入范围为+-1V,双极性,增益为2,缓冲模式--+-2V
  10. //(3)对于双精度mV级别输入+-500mV,增益为4,双极性,缓冲模式--+-2V
  11. //(4)对双精度mV级别+-50mV,增益为32,双极性,缓冲模式--+-1.6V
  12. //------MD1(0)   MD0(0)   G2(0)   G1(0)   G0(0)   B/U(0)   BUF(0)   FSYNC(0)--------------------------//   
  13. const unsigned char text_of_setup[4]={0X04,0X08,0X10,0X28}; //非缓冲模式,数字滤波同步
  14. //const unsigned char text_of_setup[4]={0X06,0X0A,0X12,0X2A}; //缓冲模式,数字滤波同步

  15. extern volatile unsigned char  command[7];   //校准命令全局数组
  16. extern volatile unsigned char  scale;        //记录系统量程
  17. extern volatile unsigned char  NO_CALI_TYPE; //未校准类型
  18. extern volatile unsigned long  int ZS,GS;   //当前量程的校准系数
  19. extern volatile unsigned char  time_count;   //超时标志

  20. //----------------------------------------------------------------------------
  21. //函数:reset_AD7705
  22. //功能:AD7705串行接口失步后将其复位。复位后要延时500us再访问
  23. //参数:无
  24. //返回:无
  25. //变量:无
  26. //备注:无
  27. //----------------------------------------------------------------------------
  28. void reset_AD7705(void)
  29. {
  30.          unsigned char i;
  31.          
  32.          AD_DIN1;
  33.          for( i=0; i<36; i++ )
  34.          {
  35.                  AD_CLK0;
  36.                  asm("nop");
  37.                  asm("nop");
  38.                       asm("nop");                 
  39.                  AD_CLK1;
  40.                  asm("nop");
  41.                  asm("nop");
  42.                        asm("nop");                 
  43.          }
  44.          
  45.          _delay_ms(1);
  46. }

  47. //------------------------------------------------------------------------------------------
  48. //函数:read_AD7705_byte
  49. //功能:从AD7705读一个字节的数据
  50. //参数:无
  51. //返回:读到的一字节数据
  52. //变量:无
  53. //备注:无
  54. //------------------------------------------------------------------------------------------
  55. unsigned char read_AD7705_byte(void)
  56. {
  57.          unsigned char data = 0;
  58.          unsigned char i = 0;
  59.          
  60.          for( i=0; i<8; i++ )
  61.          {
  62.                  data <<= 1;
  63.                  AD_CLK0;                 
  64.                  asm("nop");
  65.                  asm("nop");
  66.                  asm("nop");
  67.                  if(AD_DOUT)
  68.                  {
  69.                    data++;
  70.                  }
  71.                       AD_CLK1;                 
  72.                  asm("nop");
  73.                  asm("nop");
  74.                  asm("nop");
  75.          }
  76.          
  77.          return data;        
  78. }


 楼主| secretuniverse 发表于 2016-3-28 20:48 | 显示全部楼层
  1. //------------------------------------------------------------------------------------------
  2. //函数:read_AD7705_word
  3. //功能:从AD7705读一个字的数据,共16bit
  4. //参数:无
  5. //返回:读到的一字节数据
  6. //变量:无
  7. //备注:无
  8. //------------------------------------------------------------------------------------------
  9. unsigned int read_AD7705_word(void)
  10. {
  11.          unsigned int data = 0;
  12.          unsigned char i = 0;
  13.          
  14.          for( i=0; i<16; i++ )
  15.          {
  16.                  data <<= 1;
  17.                  AD_CLK0;                 
  18.                  asm("nop");
  19.                  asm("nop");
  20.                  asm("nop");
  21.                  if(AD_DOUT)
  22.                  {
  23.                     data++;
  24.                  }
  25.                       AD_CLK1;                 
  26.                  asm("nop");
  27.                  asm("nop");
  28.                  asm("nop");
  29.          }     
  30.          
  31.          return data;        
  32. }


  33. //------------------------------------------------------------------------------------------
  34. //函数:read_AD7705_dword
  35. //功能:从AD7705读一个24的数据
  36. //参数:无
  37. //返回:读到的一字节数据
  38. //变量:无
  39. //备注:AD7705是一个24位AD,选定刷新频率在16.7HZ下,有效位是19位,暂时读出全部24位数据
  40. //------------------------------------------------------------------------------------------
  41. unsigned long int read_AD7705_dword(void)
  42. {
  43.          unsigned long data = 0;
  44.          unsigned char i = 0;
  45.          
  46.          for( i=0; i<24; i++ )
  47.          {
  48.                  data <<= 1;
  49.                  AD_CLK0;                 
  50.                  asm("nop");
  51.                  asm("nop");
  52.                  asm("nop");
  53.                  if(AD_DOUT)
  54.                  {
  55.                     data++;
  56.                  }
  57.                       AD_CLK1;                 
  58.                  asm("nop");
  59.                  asm("nop");
  60.                  asm("nop");
  61.          }
  62.      
  63.          return data;        
  64. }


  65. //------------------------------------------------------------------------------------------
  66. //函数:write_AD7705_byte
  67. //功能:往AD7705写8位数据
  68. //参数:IN - uint8_t  data,要写入AD7705的数据
  69. //返回:无
  70. //变量:无
  71. //备注:无
  72. //------------------------------------------------------------------------------------------
  73. void write_AD7705_byte(unsigned char data)
  74. {
  75.          for(unsigned char i=0; i<8; i++)
  76.          {
  77.                  AD_CLK0;
  78.                  if(data&0x80)
  79.                          AD_DIN1;
  80.                  else
  81.                          AD_DIN0;                 
  82.                       asm("nop");
  83.                  asm("nop");
  84.                  asm("nop");
  85.                  AD_CLK1;                 
  86.                  asm("nop");
  87.                       asm("nop");
  88.                  asm("nop");
  89.                  data <<= 1;
  90.          }
  91.          
  92.          AD_DIN1;         
  93. }

  94. //------------------------------------------------------------------------------------------
  95. //函数:write_AD7705_dword
  96. //功能:往AD7705写24位数据,因为AD7705是24位的器件
  97. //参数:IN - int32_t  data,要写入AD7705的数据
  98. //返回:无
  99. //变量:无
  100. //备注:无
  101. //------------------------------------------------------------------------------------------
  102. void write_AD7705_dword(unsigned long int data)
  103. {
  104.         for(unsigned char i = 0; i<24; i++)
  105.         {
  106.                  AD_CLK0;
  107.                  if(data&0x800000)
  108.                          AD_DIN1;
  109.                  else
  110.                          AD_DIN0;                 
  111.                       asm("nop");
  112.                  asm("nop");
  113.                  asm("nop");
  114.                  AD_CLK1;                 
  115.                  asm("nop");
  116.                        asm("nop");
  117.                  asm("nop");
  118.                  data <<= 1;
  119.          }
  120.          
  121.          AD_DIN1;
  122. }


 楼主| secretuniverse 发表于 2016-3-28 20:49 | 显示全部楼层
  1. //--------------------------------------------------------------------------
  2. //-------------------------读取AD7705转换数据函数--------------------------
  3. //入口参数:指向main()主函数定义的ad_data变量的常量指针
  4. //--------------------------------------------------------------------------
  5. void ReadData7705(unsigned int *const pdata)
  6. {
  7.      unsigned int data=0, fiter[5]={0};
  8.          unsigned long int temp=0;
  9.          unsigned char i=0, sort_flag=1;
  10.      
  11.          AD_CS0;
  12.          _delay_us(5);
  13.          
  14.          start_AD7705();
  15.          
  16.          for( i=0; i<5; i++ )
  17.          {
  18.                start_timer0();
  19.              _delay_ms(2);
  20.              while( AD_DRDY )
  21.              {
  22.                      if( time_count >= time_read_data )
  23.                      {
  24.                              stop_timer0();
  25.                              AD_CS1;
  26.                              return;
  27.                      }
  28.                  }
  29.              stop_timer0();
  30.                  
  31.                write_AD7705_byte( RD_DATA_REG );
  32.                fiter[i] = read_AD7705_word();
  33.          }         
  34.          AD_CS1;
  35.          
  36.          sort_flag = 1;
  37.          while( sort_flag )
  38.          {
  39.              sort_flag = 0;
  40.              for( i=0; i<4; i++ )
  41.                  {
  42.                      if( fiter[i] > fiter[i+1] )
  43.                          {
  44.                              data = fiter[i];
  45.                                  fiter[i] = fiter[i+1];
  46.                                  fiter[i+1] = data;
  47.                                  sort_flag = 1;
  48.                          }
  49.                  }         
  50.          }
  51.          
  52.          temp = ( (unsigned long int)fiter[1] + (unsigned long int)fiter[2]
  53.                   + (unsigned long int)fiter[3] )/3;
  54.          
  55.          data = (unsigned int)temp;
  56.      
  57.                   if( (data<0xfff0) && (data&0x000f)>0x0008 )
  58.          {
  59.              data >>= 4;
  60.                  data++;
  61.          }
  62.          else
  63.          {
  64.              data >>= 4;
  65.          }
  66.          
  67.      if( 1 != scale )
  68.      {   
  69.                  data -= 0x0800;  
  70.      }
  71.          
  72.      *pdata = data & 0x0fff;         
  73. }

  74. //---------------------------------------------------------------------------------------
  75. //校准命令格式   
  76. //STX        Data Long        Command Code        Parameter        CheckSum        ETX
  77. //0x55        数据长度(2)        量程指示        00H/01H            CRC16(2)        0x0D

  78. void AD7705_calibration(void)
  79. {
  80.               unsigned char readtimes =0;
  81.          
  82.          unsigned char cali_scale =0;
  83.      
  84.           unsigned long int temp =0;
  85.          
  86.           unsigned char coefficient[8] ={0}; //test[8]={0};
  87.      
  88.          //16位校验和的临时变量
  89.          unsigned int crcvalue =0;
  90.          
  91.          AD_CS1;         
  92.          
  93.          cali_scale = command[2]; //获取上位机发送的要校准的量程类型
  94.            
  95.       eeprom_busy_wait();
  96.      eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_1+(cali_scale-1)*10), 8 );
  97.      crcvalue = checksum( &coefficient[0], 6 );
  98.          if( (coefficient[7]*256+coefficient[6]) != crcvalue )
  99.          {
  100.               readtimes++;               
  101.          }
  102.          
  103.          if( 1 == readtimes )
  104.          {
  105.              eeprom_busy_wait();
  106.                 eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_2+(cali_scale-1)*10), 8 );
  107.                crcvalue = checksum( &coefficient[0], 6 ); //
  108.              if( (coefficient[7]*256+coefficient[6]) != crcvalue )
  109.              {
  110.                      readtimes++;                        
  111.              }
  112.          }
  113.          
  114.          if( 2 == readtimes )
  115.          {
  116.              eeprom_busy_wait();
  117.          eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_3+(cali_scale-1)*10), 8 );         
  118.          }
  119.      
  120.          ADDR409_MASK;         
  121.          AD_CS0;
  122.            _delay_us(5);
  123.          reset_AD7705();
  124.          
  125.          write_AD7705_byte( WR_CLOCK_REG );
  126.          write_AD7705_byte( CLOCK_REG_SET );
  127.      
  128.          if( ZERO_CALIBRATION == command[3] ) //校准命令为零校准
  129.          {
  130.              write_AD7705_byte( WR_SETUP_REG );
  131.              write_AD7705_byte( text_of_setup[cali_scale-1] | SYS_ZERO_CALI);
  132.                  
  133.                  //等待校准完成
  134.                  start_timer0();
  135.                  while( time_count < time_sys_cali );
  136.                  stop_timer0();
  137.                  
  138.                  while( AD_DRDY );
  139.                   
  140.                  //读OFFSET寄存器
  141.                  write_AD7705_byte( RD_OFFSET_REG );
  142.                  temp = read_AD7705_dword();
  143.                   
  144.                  if( cali_scale == scale)
  145.                  {
  146.                      ZS = temp;                                                          NO_CALI_TYPE = NO_FULL_CALIBRATION;                        
  147.                  }         
  148.                  
  149.                  coefficient[0] = (unsigned char)( temp%256 );
  150.                  coefficient[1] = (unsigned char)( (temp/256)%256 );
  151.                  coefficient[2] = (unsigned char)( (temp/65536)%256 );
  152.          }
  153.      else if( FULL_CALIBRATION == command[3] )
  154.      {
  155.             
  156.            temp = (unsigned long int)(coefficient[0]) + (unsigned long int)(coefficient[1])*256
  157.                       + (unsigned long int)(coefficient[2])*65536;                 
  158.                                  
  159.              write_AD7705_byte( WR_OFFSET_REG );
  160.              write_AD7705_dword( temp );                 
  161.                  
  162.             write_AD7705_byte( WR_SETUP_REG );
  163.              write_AD7705_byte( text_of_setup[cali_scale-1] | SYS_FULL_CALI );                 
  164.             
  165.                  //等待校准完成
  166.                  start_timer0();
  167.                  while( time_count < time_sys_cali );
  168.                  stop_timer0();
  169.                  
  170.                  while( AD_DRDY );//         
  171.                  //读FULL寄存器
  172.                  write_AD7705_byte( RD_FULL_REG );
  173.                  temp = read_AD7705_dword();
  174.                  
  175.                  if( cali_scale == scale )
  176.                  {
  177.                      GS = temp;
  178.                           NO_CALI_TYPE = ALREADY_CALIBRATION;            
  179.                  }         
  180.                  
  181.                  coefficient[3] = (unsigned char)( temp%256 );
  182.                  coefficient[4] = (unsigned char)( (temp/256)%256 );
  183.                  coefficient[5] = (unsigned char)( (temp/65536)%256 );
  184.          }
  185.      else
  186.      {
  187.              AD_CS1;
  188.                  _delay_us(5);
  189.                  return;
  190.          }
  191.          
  192.      AD_CS1;
  193.          _delay_us(5);
  194.       
  195.          crcvalue = checksum(&coefficient[0],6);
  196.          coefficient[6] = (unsigned char)(crcvalue%256);//
  197.             coefficient[7] = (unsigned char)(crcvalue/256);
  198.      
  199.               eeprom_busy_wait();
  200.      eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_1+(cali_scale-1)*10), 8 );
  201.          
  202.               eeprom_busy_wait();
  203.      eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_2+(cali_scale-1)*10), 8 );  
  204.      
  205.                  eeprom_busy_wait();
  206.          eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_3+(cali_scale-1)*10), 8 );
  207.          
  208.      Txout( &coefficient[0] );//输出校准数据给上位机
  209.          
  210.          return;         
  211. }
 楼主| secretuniverse 发表于 2016-3-28 20:50 | 显示全部楼层
  1. //
  2. void start_AD7705(void)
  3. {
  4.      reset_AD7705();
  5.      
  6.          //写OFFSET寄存器
  7.          write_AD7705_byte( WR_OFFSET_REG );
  8.          write_AD7705_dword( ZS );
  9.          
  10.          //写满量程校准寄存器
  11.          write_AD7705_byte( WR_FULL_REG );
  12.          write_AD7705_dword( GS );
  13.          
  14.          //CLOCK寄存器设置,无分频,50HZ输出更新速率
  15.          write_AD7705_byte( WR_CLOCK_REG );
  16.          write_AD7705_byte( CLOCK_REG_SET );
  17.          
  18.          //写设置寄存器
  19.          write_AD7705_byte( WR_SETUP_REG );
  20.          write_AD7705_byte( text_of_setup[scale-1] );
  21.          
  22.          start_timer0();
  23.          while( time_count < time_read_data );
  24.          stop_timer0();
  25. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

55

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部