找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 2430|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

ad7705的單片機(jī)源程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:309907 發(fā)表于 2018-4-17 13:44 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
ad7705單片機(jī)源程序如下:
  1. ------------AD7705頭文件開始-------------------
  2. #ifndef _AD7705_H
  3. #define _AD7705_H

  4. //通訊寄存器地址定義
  5. #define     WR_SETUP_REG        0x10   //選中寫設(shè)置寄存器
  6. #define     RD_SETUP_REG        0x18   //選中寫設(shè)置寄存器
  7. #define     WR_CLOCK_REG     0x20   //選中寫時(shí)鐘寄存器
  8. #define RD_DATA_REG         0x38   //選中數(shù)據(jù)寄存器讀
  9. #define     WR_OFFSET_REG      0x60   //選中寫offset寄存器
  10. #define     RD_OFFSET_REG      0x68   //選中讀offset寄存器
  11. #define     WR_FULL_REG        0x70   //選中寫full scale寄存器
  12. #define     RD_FULL_REG        0x78   //選中讀full scale寄存器

  13. #define     SYS_ZERO_CALI     0x80   //系統(tǒng)零校準(zhǔn)模式
  14. #define     SYS_FULL_CALI     0xC0   //系統(tǒng)滿量程校準(zhǔn)模式

  15. #define ZERO_CALIBRATION    0x00 //系統(tǒng)零校準(zhǔn)
  16. #define FULL_CALIBRATION    0x01 //系統(tǒng)滿量程校準(zhǔn)

  17. //CLOCK寄存器設(shè)置,無分頻,50HZ輸出更新速率
  18. #define CLOCK_REG_SET    0X04

  19. //函數(shù)聲明
  20. void reset_AD7705(void);

  21. unsigned char read_AD7705_byte(void);
  22. unsigned int   read_AD7705_word(void);
  23. unsigned long int read_AD7705_dword(void);

  24. void write_AD7705_byte(unsigned char data);
  25. void write_AD7705_word(unsigned int data);
  26. void write_AD7705_dword(unsigned long int data);

  27. void ReadData7705(unsigned int *const pdata);
  28. void AD7705_calibration(void);
  29. void start_AD7705(void);

  30. #endif

  31. -----------AD7705主文件開始--------------
  32. #include <util/delay.h>
  33. #include <avr/eeprom.h>
  34. #include "ad7705.h"
  35. #include "main.h"
  36. #include "crc16.h"
  37. #include "Usart.h"

  38. //針對(duì)四個(gè)量程的設(shè)置寄存器的設(shè)置內(nèi)容
  39. //(1)對(duì)于單極性V級(jí)別輸入0-5V、0-20mA、0-10V這三個(gè)量程,輸入范圍為0-2V,無極性,增益為1,緩沖模式--0-2V
  40. //(2)對(duì)于雙極性V級(jí)別輸入+-2.5V、+-5V這兩個(gè)量程,輸入范圍為+-1V,雙極性,增益為2,緩沖模式--+-2V
  41. //(3)對(duì)于雙精度mV級(jí)別輸入+-500mV,增益為4,雙極性,緩沖模式--+-2V
  42. //(4)對(duì)雙精度mV級(jí)別+-50mV,增益為32,雙極性,緩沖模式--+-1.6V
  43. //----MD1(0)    MD0(0)    G2(0)    G1(0)    G0(0)    B/U(0)    BUF(0)    FSYNC(0)--------------------//
  44. const unsigned char text_of_setup[4]={0X06,0X0A,0X12,0X2A}; //緩沖模式,數(shù)字濾波同步

  45. extern volatile unsigned char   command[7];    //校準(zhǔn)命令全局?jǐn)?shù)組
  46. extern volatile unsigned char   scale;         //記錄系統(tǒng)量程
  47. extern volatile unsigned char   NO_CALI_TYPE; //未校準(zhǔn)類型
  48. extern volatile unsigned long   int ZS,GS;    //當(dāng)前量程的校準(zhǔn)系數(shù)
  49. extern volatile unsigned char   time_count;    //超時(shí)標(biāo)志

  50. //----------------------------------------------------------------------------
  51. //函數(shù):reset_AD7705
  52. //功能:AD7705串行接口失步后將其復(fù)位。復(fù)位后要延時(shí)500us再訪問
  53. //參數(shù):無
  54. //返回:無
  55. //變量:無
  56. //備注:無
  57. //----------------------------------------------------------------------------
  58. void reset_AD7705(void)
  59. {
  60.       unsigned char i;
  61.      
  62.       AD_DIN1;
  63.       for( i=0; i<36; i++ )
  64.       {
  65.           AD_CLK0;
  66.           asm("nop");
  67.           asm("nop");
  68.           asm("nop");         
  69.           AD_CLK1;
  70.           asm("nop");
  71.           asm("nop");
  72.           asm("nop");         
  73.       }     
  74.       _delay_us(30);
  75. }

  76. //------------------------------------------------------------------------------------------
  77. //函數(shù):read_AD7705_byte
  78. //功能:從AD7705讀一個(gè)字節(jié)的數(shù)據(jù)
  79. //參數(shù):無
  80. //返回:讀到的一字節(jié)數(shù)據(jù)
  81. //變量:無
  82. //備注:無
  83. //------------------------------------------------------------------------------------------
  84. unsigned char read_AD7705_byte(void)
  85. {
  86.       unsigned char data = 0;
  87.       unsigned char i = 0;
  88.      
  89.       for( i=0; i<8; i++ )
  90.       {
  91.           data <<= 1;
  92.           AD_CLK0;         
  93.           asm("nop");
  94.           asm("nop");
  95.           asm("nop");
  96.           if(AD_DOUT)
  97.           {
  98.               data++;
  99.           }
  100.           AD_CLK1;         
  101.           asm("nop");
  102.           asm("nop");
  103.           asm("nop");
  104.       }     
  105.       return data;   
  106. }

  107. //------------------------------------------------------------------------------------------
  108. //函數(shù):read_AD7705_word
  109. //功能:從AD7705讀一個(gè)字的數(shù)據(jù),共16bit
  110. //參數(shù):無
  111. //返回:讀到的一字節(jié)數(shù)據(jù)
  112. //變量:無
  113. //備注:無
  114. //------------------------------------------------------------------------------------------
  115. unsigned int read_AD7705_word(void)
  116. {
  117.       unsigned int data = 0;
  118.       unsigned char i = 0;
  119.      
  120.       for( i=0; i<16; i++ )
  121.       {
  122.           data <<= 1;
  123.           AD_CLK0;         
  124.           asm("nop");
  125.           asm("nop");
  126.           asm("nop");
  127.           if(AD_DOUT)
  128.           {
  129.               data++;
  130.           }
  131.           AD_CLK1;         
  132.           asm("nop");
  133.           asm("nop");
  134.           asm("nop");
  135.       }     
  136.       return data;   
  137. }


  138. //------------------------------------------------------------------------------------------
  139. //函數(shù):read_AD7705_dword
  140. //功能:從AD7705讀一個(gè)24的數(shù)據(jù)
  141. //參數(shù):無
  142. //返回:讀到的一字節(jié)數(shù)據(jù)
  143. //變量:無
  144. //備注:AD7705是一個(gè)16位AD
  145. //------------------------------------------------------------------------------------------
  146. unsigned long int read_AD7705_dword(void)
  147. {
  148.       unsigned long data = 0;
  149.       unsigned char i = 0;
  150.      
  151.       for( i=0; i<24; i++ )
  152.       {
  153.           data <<= 1;
  154.           AD_CLK0;         
  155.           asm("nop");
  156.           asm("nop");
  157.           asm("nop");
  158.           if(AD_DOUT)
  159.           {
  160.                data++;
  161.           }
  162.           AD_CLK1;         
  163.           asm("nop");
  164.           asm("nop");
  165.           asm("nop");
  166.       }     
  167.       return data;   
  168. }


  169. //------------------------------------------------------------------------------------------
  170. //函數(shù):write_AD7705_byte
  171. //功能:往AD7705寫8位數(shù)據(jù)
  172. //參數(shù):IN - uint8_t   data,要寫入AD7705的數(shù)據(jù)
  173. //返回:無
  174. //變量:無
  175. //備注:無
  176. //------------------------------------------------------------------------------------------
  177. void write_AD7705_byte(unsigned char data)
  178. {
  179.       for(unsigned char i=0; i<8; i++)
  180.       {
  181.           AD_CLK0;
  182.           if(data&0x80)
  183.               AD_DIN1;
  184.           else
  185.               AD_DIN0;         
  186.           asm("nop");
  187.           asm("nop");
  188.           asm("nop");
  189.           AD_CLK1;         
  190.           asm("nop");
  191.           asm("nop");
  192.           asm("nop");
  193.           data <<= 1;
  194.       }     
  195.       AD_DIN1;     
  196. }

  197. //------------------------------------------------------------------------------------------
  198. //函數(shù):write_AD7705_dword
  199. //功能:往AD7705寫24位數(shù)據(jù),因?yàn)锳D7705是24位的器件
  200. //參數(shù):IN - int32_t   data,要寫入AD7705的數(shù)據(jù)
  201. //返回:無
  202. //變量:無
  203. //備注:無
  204. //------------------------------------------------------------------------------------------
  205. void write_AD7705_dword(unsigned long int data)
  206. {
  207.      for(unsigned char i = 0; i<24; i++)
  208.      {
  209.           AD_CLK0;
  210.           if(data&0x800000)
  211.               AD_DIN1;
  212.           else
  213.               AD_DIN0;         
  214.           asm("nop");
  215.           asm("nop");
  216.           asm("nop");
  217.           AD_CLK1;         
  218.           asm("nop");
  219.           asm("nop");
  220.           asm("nop");
  221.           data <<= 1;
  222.       }     
  223.       AD_DIN1;
  224. }

  225. //------------------------------------------------------------------------------------------
  226. //函數(shù):AD7705_calibration
  227. //功能:根據(jù)cali_type的值對(duì)AD7705進(jìn)行系統(tǒng)0校正或系統(tǒng)滿量程校正,并將各校正值和校正標(biāo)志存入
  228. //       EEPROM,數(shù)據(jù)保存為雙備份。數(shù)據(jù)塊格式為: 內(nèi)部0校正值(4byte), 內(nèi)部滿量程校正值(4byte),
  229. //          系統(tǒng)0校正值(4byte), 系統(tǒng)滿量程校正值(4byte), 系統(tǒng)0校正標(biāo)志(1byte),系統(tǒng)滿量程校正標(biāo)志
  230. //       (1byte),CRC16校驗(yàn)值(2byte),共20byte。
  231. //參數(shù):IN - uint8_t board, 0 - 對(duì)主板進(jìn)行校正,1-對(duì)副板進(jìn)行校正
  232. //         IN - uint8_t range, 需要校正的量程
  233. //       IN - uint8_t cali_type, 校正類型,ZERO_CALIBRATION- 0校正;
  234. //            FULL_CALIBRATION - 滿量程校正
  235. //返回:返回-1表示校準(zhǔn)失敗,非0表示校正成功,并返回相應(yīng)的索引值
  236. //變量:無
  237. //備注:做滿量程校正前必須先做零校正
  238. //------------------------------------------------------------------------------------------
  239. //校準(zhǔn)命令格式   
  240. //STX     Data Long     Command Code     Parameter     CheckSum     ETX
  241. //0x55     數(shù)據(jù)長(zhǎng)度(2)     量程指示     00H/01H         CRC16(2)     0x0D
  242. //
  243. //校準(zhǔn)過程中要用到Command[]的數(shù)據(jù),所以校準(zhǔn)之前要關(guān)掉串口接收中斷

  244. void AD7705_calibration(void)
  245. {
  246.       //記錄讀取EEPROM的次數(shù)
  247.       unsigned char readtimes =0;
  248.      
  249.       //記錄上位機(jī)發(fā)送的校準(zhǔn)量程類型
  250.       unsigned char cali_scale =0;
  251.      
  252.       //讀取24位校準(zhǔn)系數(shù)的臨時(shí)變量
  253.       unsigned long int temp =0;
  254.      
  255.       //臨時(shí)的校準(zhǔn)系數(shù)數(shù)組,存放格式ZSL、ZSM、ZSH;GSL、GSM、GSH;CRCL、CRCH
  256.       //并在校準(zhǔn)結(jié)束時(shí)作為參數(shù)傳遞給TXOUT()函數(shù),發(fā)送校準(zhǔn)系數(shù)給上位機(jī)
  257.       unsigned char coefficient[8] ={0}; //test[8]={0};
  258.      
  259.       //16位校驗(yàn)和的臨時(shí)變量
  260.       unsigned int crcvalue =0;
  261.      
  262.       AD_CS1;
  263.      
  264.       cali_scale = command[2]; //獲取上位機(jī)發(fā)送的要校準(zhǔn)的量程類型
  265.       
  266.       //讀取EEPROM的第一份校準(zhǔn)系數(shù)
  267.       eeprom_busy_wait();
  268.       eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_1+(cali_scale-1)*10), 8 );
  269.       crcvalue = checksum( &coefficient[0], 6 ); //將6個(gè)值調(diào)用CRC校驗(yàn)函數(shù)得到校驗(yàn)
  270.       if( (coefficient[7]*256+coefficient[6]) != crcvalue )
  271.       {
  272.           readtimes++;        
  273.       }
  274.      
  275.       //如果校準(zhǔn)系數(shù)不可用則讀取第二份
  276.       if( 1 == readtimes )
  277.       {
  278.           eeprom_busy_wait();
  279.           eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_2+(cali_scale-1)*10), 8 );
  280.           crcvalue = checksum( &coefficient[0], 6 ); //將6個(gè)值調(diào)用CRC校驗(yàn)函數(shù)得到校驗(yàn)
  281.           if( (coefficient[7]*256+coefficient[6]) != crcvalue )
  282.           {
  283.               readtimes++;            
  284.           }
  285.       }
  286.      
  287.       //如果校準(zhǔn)系數(shù)不可用則讀取第三份
  288.       if( 2 == readtimes )
  289.       {
  290.           eeprom_busy_wait();
  291.           eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_3+(cali_scale-1)*10), 8 );         
  292.       }
  293.      
  294.       ADDR409_MASK; //切換到第一通道進(jìn)行校準(zhǔn)
  295.      
  296.       AD_CS0;
  297.       _delay_us(5);
  298.       reset_AD7705();
  299.      
  300.       //CLOCK寄存器設(shè)置,無分頻,50HZ輸出更新速率
  301.       write_AD7705_byte( WR_CLOCK_REG );
  302.       write_AD7705_byte( CLOCK_REG_SET );
  303.      
  304.       if( ZERO_CALIBRATION == command[3] ) //校準(zhǔn)命令為零校準(zhǔn)
  305.       {
  306.           //寫設(shè)置寄存器,選擇零校準(zhǔn)
  307.           write_AD7705_byte( WR_SETUP_REG );
  308.           write_AD7705_byte( text_of_setup[cali_scale-1] | SYS_ZERO_CALI );
  309.          
  310.           //等待校準(zhǔn)完成,系統(tǒng)校準(zhǔn)延時(shí)時(shí)間
  311.           start_timer0();
  312.           while( time_count < time_sys_cali );
  313.           stop_timer0();
  314.          
  315.           while( AD_DRDY );//若將濾波器同步位FSYNC置為1,AD_DRDY信號(hào)將不會(huì)變低,這里將一直是死循環(huán)
  316.          
  317.           //讀OFFSET寄存器
  318.           write_AD7705_byte( RD_OFFSET_REG );
  319.           temp = read_AD7705_dword();
  320.          
  321.           if( cali_scale == scale)
  322.           {
  323.               ZS = temp; //如果是當(dāng)前量程零校準(zhǔn)還要更新ZS
  324.               //如果是當(dāng)前量程的校準(zhǔn),還要將NO_CALI_TYPE賦值為1表示已經(jīng)經(jīng)過零校準(zhǔn)
  325.               //更新上電沒有校準(zhǔn)時(shí)readEEPROM()函數(shù)的運(yùn)行狀態(tài)
  326.               NO_CALI_TYPE = NO_FULL_CALIBRATION;            
  327.           }     
  328.          
  329.           coefficient[0] = (unsigned char)( temp%256 );
  330.           coefficient[1] = (unsigned char)( (temp/256)%256 );
  331.           coefficient[2] = (unsigned char)( (temp/65536)%256 );
  332.       }
  333.       else if( FULL_CALIBRATION == command[3] )//系統(tǒng)滿量程校準(zhǔn)
  334.       {
  335.          
  336.           //計(jì)算ZS,一定要作強(qiáng)制類型轉(zhuǎn)換,否則將出現(xiàn)錯(cuò)誤
  337.           temp = (unsigned long int)(coefficient[0]) + (unsigned long int)(coefficient[1])*256
  338.                + (unsigned long int)(coefficient[2])*65536;         
  339.          
  340.           //將ZS寫入到AD7705的OFFSET寄存器         
  341.           write_AD7705_byte( WR_OFFSET_REG );
  342.           write_AD7705_dword( temp );         
  343.          
  344.           //寫設(shè)置寄存器,選擇滿量程校準(zhǔn)
  345.           write_AD7705_byte( WR_SETUP_REG );
  346.           write_AD7705_byte( text_of_setup[cali_scale-1] | SYS_FULL_CALI );         
  347.          
  348.           //等待校準(zhǔn)完成,系統(tǒng)校準(zhǔn)延時(shí)時(shí)間
  349.           start_timer0();
  350.           while( time_count < time_sys_cali );
  351.           stop_timer0();
  352.          
  353.           while( AD_DRDY );//若將濾波器同步位FSYNC置為1,AD_DRDY信號(hào)將不會(huì)變低,這里將一直是死循環(huán)
  354.          
  355.           //讀FULL寄存器
  356.           write_AD7705_byte( RD_FULL_REG );
  357.           temp = read_AD7705_dword();
  358.          
  359.           if( cali_scale == scale )
  360.           {
  361.               GS = temp; //如果是當(dāng)前量程滿量程校準(zhǔn)還要更新GS
  362.               //如果是當(dāng)前量程的校準(zhǔn),還要將NO_CALI_TYPE賦值為2表示已經(jīng)經(jīng)過零校準(zhǔn)
  363.               //更新上電沒有校準(zhǔn)的情況,讓readEEPROM()函數(shù)退出循環(huán)狀態(tài)
  364.               NO_CALI_TYPE = ALREADY_CALIBRATION;            
  365.           }     
  366.          
  367.           coefficient[3] = (unsigned char)( temp%256 );
  368.           coefficient[4] = (unsigned char)( (temp/256)%256 );
  369.           coefficient[5] = (unsigned char)( (temp/65536)%256 );
  370.       }
  371.       else
  372.       {
  373.           AD_CS1;
  374.           _delay_us(5);
  375.           return;
  376.       }
  377.      
  378.       AD_CS1;
  379.       _delay_us(5);
  380.       
  381.       crcvalue = checksum(&coefficient[0],6); //將6個(gè)校準(zhǔn)值調(diào)用CRC校驗(yàn)函數(shù)得到校驗(yàn)碼     
  382.       coefficient[6] = (unsigned char)(crcvalue%256);//取校驗(yàn)值的高8位和低8位
  383.       coefficient[7] = (unsigned char)(crcvalue/256);
  384.      
  385.       //保存第一份校準(zhǔn)系數(shù)
  386.       eeprom_busy_wait();
  387. ……………………

  388. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
ad7705源程序.rar (3.5 KB, 下載次數(shù): 27)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表