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

QQ登錄

只需一步,快速開始

搜索
查看: 6498|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

STM32 AD7799驅(qū)動(dòng)程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:283625 發(fā)表于 2018-2-11 09:31 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
STM32 對(duì)于AD7799的驅(qū)動(dòng)程序,詳見附件。
本文為STM32AD7799操作函數(shù)。全文共分為二部分,第一部分為.c文件包含AD7799的配置與操作原函數(shù)。第二部分為.h文件,方便其它文件對(duì)AD7799操作函數(shù)進(jìn)行調(diào)用。代碼親測(cè)可用,只要在主函數(shù)中引用ADC_Auto_Conversion();便可得到AD轉(zhuǎn)換結(jié)果。

第一部分:.c文件操作函數(shù)
  1. ***********************************************************************************
  2. * @file                ~/USER/TM7711.c
  3. * @author        TianYu
  4. * @version        V0.9
  5. * @date                29-Aug-2011
  6. * @brief        This file contains all of the initialization function for this project
  7. ***********************************************************************************
  8. **/

  9. //Defined necessary head file and CONST flag
  10. #include"stm32f10x_conf.h"
  11. #include"stm32f10x.h"
  12. #include "AD7799.h"
  13. #include "main.h"


  14. ADC_VAL_Def  AD_Value[AD7799_CHANN_USE];      //各通道(含所有芯片)的ADC值,經(jīng)數(shù)字濾波后的ADC值
  15. ADC_RUN_Def  AD_Work_Info[AD7799_CHANN_USE];  //各通道(含所有芯片)的工作信息

  16. u8   ADC_Chn[AD7799_PCS] = {0};               //各芯片 ADC轉(zhuǎn)換通道號(hào):0~2
  17. #define  SPI_PULSE_WIDE            20                //SPI模擬通信中,時(shí)鐘信號(hào)的延時(shí)

  18. /*******************************************************************************
  19. * Function Name  : auto_gain
  20. * Description    : 根據(jù)采樣的AD值,自動(dòng)調(diào)整AD7799的增益
  21. * Input          : chn - ADC的采樣通道(AD7799_CHANN_USE以內(nèi))
  22. * Output         : 全局變量AD_Work_Info[chn].SetGain,其值為0~7,對(duì)應(yīng)增益為1~128
  23. * Return         : None
  24. * 算法說明       : 在增益未達(dá)最大和最小時(shí),自動(dòng)控制增益后的AD值在%40~80%之間
  25. *******************************************************************************/
  26. void auto_gain(u8 chn)
  27. {
  28.   u32 xd,xcv;
  29.   
  30.   chn = chn & 0x03;
  31.   
  32.   if(AD_Work_Info[chn].CurrValue < 0) xcv = -AD_Work_Info[chn].CurrValue;
  33.   else xcv = AD_Work_Info[chn].CurrValue;
  34.   
  35.   if(xcv > (REF_FULL_VAL * 81 / 100))  //大于81%,則在增益系數(shù)值不為0時(shí),增益系數(shù)-1(即增益降低2倍)
  36.   {
  37.     if(AD_Work_Info[chn].CurrGain)
  38.     { AD_Work_Info[chn].SetGain = AD_Work_Info[chn].CurrGain - 1;}
  39.   }
  40.   else if(xcv < (REF_FULL_VAL * 39/ 100))  //小于39%時(shí),直接把增益增大N倍,使其達(dá)到50%以內(nèi)。
  41.   {
  42.     xd = REF_FULL_VAL / xcv;
  43.     xd = xd  / 2;
  44.     if(xd)
  45.     {
  46.       xd--;
  47.     }
  48.     AD_Work_Info[chn].SetGain = AD_Work_Info[chn].CurrGain + xd;
  49.     if(AD_Work_Info[chn].SetGain >= 7)   //限制最大增益系數(shù)為7,即128倍
  50.     {
  51.       AD_Work_Info[chn].SetGain = 7;
  52.     }
  53.   }
  54.   
  55. }
  56. /*******************************************************************************
  57. * Function Name  : ADC7799_Init
  58. * Description    : AD7799初始化: GPIO,配置啟動(dòng),變量清0
  59. * Input          : None
  60. * Output         : None
  61. * Return         : None
  62. *******************************************************************************/
  63. void ADC7799_Init(void)  
  64. {
  65.   u8 i;
  66.   for(i = 0; i < AD7799_CHANN_USE; i++)
  67.   {
  68.     AD_Value[i].Status = 0;
  69.     AD_Value[i].Value = 0;
  70.    
  71.     AD_Work_Info[i].RefMode = 0;
  72.     AD_Work_Info[i].SetGain = 0;
  73.     AD_Work_Info[i].CurrGain = 0;
  74.     AD_Work_Info[i].CurrValue = 0;
  75.   }
  76.   
  77.   for(i = 0; i < AD7799_PCS; i++)
  78.   {
  79.     AD7799_CS_Pin_Configuration(i);
  80.     AD7799_SCLK_Pin_Configuration(i);
  81.     AD7799_DIN_Pin_Configuration(i);
  82.     AD7799_DOUT_Pin_Configuration(i);
  83.     ADC_Chn[i] = 0;
  84.     Config_AD7799(i,ADC_Chn[i]);   
  85.   }
  86. }

  87. /*******************************************************************************
  88. * Function Name  : AD7799_SCLK_Pin_Configuration
  89. * Description    : 配置MCU與各AD7799的CS連接的引腳 (OUT)
  90. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  91. * Output         : None
  92. * Return         : None
  93. *******************************************************************************/
  94. void AD7799_CS_Pin_Configuration(u8 chipn)
  95. {
  96.   GPIO_InitTypeDef GPIO_InitStructure;
  97.   GPIO_TypeDef *AD7799_PORT[4] = {ADC1_CS_PORT,ADC2_CS_PORT,ADC3_CS_PORT,ADC4_CS_PORT};   //端口
  98.   uint16_t      AD7799_PINx[4] = {ADC1_CS_PIN, ADC2_CS_PIN, ADC3_CS_PIN, ADC4_CS_PIN };    //Pin
  99.   
  100.   if(AD7799_PORT[chipn] && (chipn < AD7799_PCS))   //端口和芯片有效,才對(duì)端口進(jìn)行配置
  101.   {  
  102.     GPIO_InitStructure.GPIO_Pin = AD7799_PINx[chipn];
  103.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  104.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //  推挽輸出
  105.     GPIO_Init(AD7799_PORT[chipn], &GPIO_InitStructure);  
  106.   }
  107. }
  108. /*******************************************************************************
  109. * Function Name  : AD7799_SCLK_Pin_Configuration
  110. * Description    : 配置MCU與各AD7799的SCLK連接的引腳 (OUT)
  111. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  112. * Output         : None
  113. * Return         : None
  114. *******************************************************************************/
  115. void AD7799_SCLK_Pin_Configuration(u8 chipn)
  116. {
  117.   GPIO_InitTypeDef GPIO_InitStructure;
  118.   GPIO_TypeDef *AD7799_PORT[4] = {ADC1_SCLK_PORT,ADC2_SCLK_PORT,ADC3_SCLK_PORT,ADC4_SCLK_PORT};   //端口
  119.   uint16_t      AD7799_PINx[4] = {ADC1_SCLK_PIN, ADC2_SCLK_PIN, ADC3_SCLK_PIN, ADC4_SCLK_PIN };    //Pin
  120.   
  121.   if(AD7799_PORT[chipn] && (chipn < AD7799_PCS))   //端口和芯片有效,才對(duì)端口進(jìn)行配置
  122.   {  
  123.     GPIO_InitStructure.GPIO_Pin = AD7799_PINx[chipn];
  124.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  125.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //  推挽輸出
  126.     GPIO_Init(AD7799_PORT[chipn], &GPIO_InitStructure);  
  127.   }
  128. }
  129. /*******************************************************************************
  130. * Function Name  : AD7799_SCLK_Pin_Configuration
  131. * Description    : 配置MCU與各AD7799的DIN連接的引腳 (OUT)
  132. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  133. * Output         : None
  134. * Return         : None
  135. *******************************************************************************/
  136. void AD7799_DIN_Pin_Configuration(u8 chipn)
  137. {
  138.   GPIO_InitTypeDef GPIO_InitStructure;
  139.   GPIO_TypeDef *AD7799_PORT[4] = {ADC1_DIN_PORT,ADC2_DIN_PORT,ADC3_DIN_PORT,ADC4_DIN_PORT};   //端口
  140.   uint16_t      AD7799_PINx[4] = {ADC1_DIN_PIN, ADC2_DIN_PIN, ADC3_DIN_PIN, ADC4_DIN_PIN };    //Pin
  141.   
  142.   if(AD7799_PORT[chipn] && (chipn < AD7799_PCS))   //端口和芯片有效,才對(duì)端口進(jìn)行配置
  143.   {  
  144.     GPIO_InitStructure.GPIO_Pin = AD7799_PINx[chipn];
  145.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  146.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //  推挽輸出
  147.     GPIO_Init(AD7799_PORT[chipn], &GPIO_InitStructure);  
  148.   }
  149. }
  150. /*******************************************************************************
  151. * Function Name  : AD7799_SCLK_Pin_Configuration
  152. * Description    : 配置MCU與各AD7799的DOUT連接的引腳 (IN)
  153. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  154. * Output         : None
  155. * Return         : None
  156. *******************************************************************************/
  157. void AD7799_DOUT_Pin_Configuration(u8 chipn)
  158. {
  159.   GPIO_InitTypeDef GPIO_InitStructure;
  160.   GPIO_TypeDef *AD7799_PORT[4] = {ADC1_DOUT_PORT,ADC2_DOUT_PORT,ADC3_DOUT_PORT,ADC4_DOUT_PORT};   //端口
  161.   uint16_t      AD7799_PINx[4] = {ADC1_DOUT_PIN, ADC2_DOUT_PIN, ADC3_DOUT_PIN, ADC4_DOUT_PIN };    //Pin
  162.   
  163.   if(AD7799_PORT[chipn] && (chipn < AD7799_PCS))   //端口和芯片有效,才對(duì)端口進(jìn)行配置
  164.   {  
  165.     GPIO_InitStructure.GPIO_Pin = AD7799_PINx[chipn];
  166.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  167.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    //  上接輸入
  168.     GPIO_Init(AD7799_PORT[chipn], &GPIO_InitStructure);  
  169.   }
  170. }

  171. /*******************************************************************************
  172. * Function Name  : Delay_7799
  173. * Description    : 延時(shí)函數(shù)
  174. * Input          : timecount - 延時(shí)參數(shù)(0~65535)
  175. * Output         : None
  176. * Return         : None
  177. *******************************************************************************/
  178. void Delay_7799(u16 timecount)
  179. {
  180.   while(timecount>0)
  181.     timecount--;
  182. }

  183. /*******************************************************************************
  184. * Function Name  : Wr1Byte7799
  185. * Description    : 向AD7799寫入1字節(jié)(MSB在前,即左移)上沿鎖存
  186. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  187. *                  data - 寫入的8bit數(shù)據(jù)
  188. * Output         : None
  189. * Return         : None
  190. *******************************************************************************/
  191. void Wr1Byte7799(u8 chipn,u8 data)  //模擬SPI
  192. {
  193.   GPIO_TypeDef *AD7799_DIN_PORT[4] =  {ADC1_DIN_PORT,ADC2_DIN_PORT,ADC3_DIN_PORT,ADC4_DIN_PORT};   //端口
  194.   uint16_t      AD7799_DIN_PINx[4] =  {ADC1_DIN_PIN, ADC2_DIN_PIN, ADC3_DIN_PIN, ADC4_DIN_PIN };    //Pin
  195.   GPIO_TypeDef *AD7799_SCLK_PORT[4] = {ADC1_SCLK_PORT,ADC2_SCLK_PORT,ADC3_SCLK_PORT,ADC4_SCLK_PORT};   //端口
  196.   uint16_t      AD7799_SCLK_PINx[4] = {ADC1_SCLK_PIN, ADC2_SCLK_PIN, ADC3_SCLK_PIN, ADC4_SCLK_PIN };    //Pin
  197.   
  198.   u8 xi;
  199.   for(xi = 0; xi < 8; xi++)
  200.   {  GPIO_ResetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]);    //AD7799_CLK_L;
  201.   if((data & 0x80) == 0x80 )
  202.   {
  203.     GPIO_SetBits(AD7799_DIN_PORT[chipn],AD7799_DIN_PINx[chipn]);  //AD7799_DIN_H;  
  204.   }  
  205.   else
  206.   {
  207.     GPIO_ResetBits(AD7799_DIN_PORT[chipn],AD7799_DIN_PINx[chipn]); //AD7799_DIN_L;  
  208.   }  
  209.   Delay_7799(SPI_PULSE_WIDE);
  210.   data = data << 1;  //左移1位
  211.   GPIO_SetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]);    //AD7799_CLK_H;   
  212.   Delay_7799(SPI_PULSE_WIDE);
  213.   }
  214. }

  215. /*******************************************************************************
  216. * Function Name  : Rd1Byte7799
  217. * Description    : 讀1字節(jié), AD7799在下沿輸出數(shù)據(jù),上升沿時(shí)數(shù)據(jù)有效,MSB在前
  218. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  219. * Output         : None
  220. * Return         : 8位數(shù)據(jù)
  221. *******************************************************************************/
  222. u8 Rd1Byte7799(u8 chipn)  //模擬SPI
  223. {         
  224.   GPIO_TypeDef *AD7799_DOUT_PORT[4] = {ADC1_DOUT_PORT,ADC2_DOUT_PORT,ADC3_DOUT_PORT,ADC4_DOUT_PORT};   //端口
  225.   uint16_t      AD7799_DOUT_PINx[4] = {ADC1_DOUT_PIN, ADC2_DOUT_PIN, ADC3_DOUT_PIN, ADC4_DOUT_PIN };    //Pin
  226.   GPIO_TypeDef *AD7799_SCLK_PORT[4] = {ADC1_SCLK_PORT,ADC2_SCLK_PORT,ADC3_SCLK_PORT,ADC4_SCLK_PORT};   //端口
  227.   uint16_t      AD7799_SCLK_PINx[4] = {ADC1_SCLK_PIN, ADC2_SCLK_PIN, ADC3_SCLK_PIN, ADC4_SCLK_PIN };    //Pin
  228.   u8 xi,xd = 0;
  229.   
  230.   GPIO_SetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]);    //        AD7799_CLK_H;
  231.   for(xi = 0,xd = 0; xi < 8; xi++)
  232.   {
  233.     Delay_7799(SPI_PULSE_WIDE);
  234.     GPIO_ResetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]);    //AD7799_CLK_L;   
  235.     Delay_7799(SPI_PULSE_WIDE);
  236.     xd = xd * 2;   //左移一位
  237.     // if(AD7799_DOUT) xd++;
  238.     if(GPIO_ReadInputDataBit(AD7799_DOUT_PORT[chipn],AD7799_DOUT_PINx[chipn]))
  239.     {xd++;}
  240.     GPIO_SetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]);    //AD7799_CLK_H;
  241.   }
  242.   return xd;
  243. }

  244. /*******************************************************************************
  245. * Function Name  : Set_CS_7799
  246. * Description    : 設(shè)置AD7799的CS為高電平(1)或低電平(0)
  247. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  248. *                    val - CS的電平值: 0=低電平; 1=高電平
  249. * Output         : None
  250. * Return         : None
  251. *******************************************************************************/
  252. void Set_CS_7799(u8 chipn,u8 val)  
  253. {
  254.   GPIO_TypeDef *AD7799_CS_PORT[4] = {ADC1_CS_PORT,ADC2_CS_PORT,ADC3_CS_PORT,ADC4_CS_PORT};   //端口
  255.   uint16_t      AD7799_CS_PINx[4] = {ADC1_CS_PIN, ADC2_CS_PIN, ADC3_CS_PIN, ADC4_CS_PIN };    //Pin
  256.   
  257.   if(val == 0)
  258.   {
  259.     GPIO_ResetBits(AD7799_CS_PORT[chipn],AD7799_CS_PINx[chipn]); //AD7799_CS_L;
  260.   }
  261.   else
  262.   {
  263.     GPIO_SetBits(AD7799_CS_PORT[chipn],AD7799_CS_PINx[chipn]);   //AD7799_CS_H;  
  264.   }
  265. }

  266. /*******************************************************************************
  267. * Function Name  : read_status_reg7799
  268. * Description    : 讀AD7799的狀態(tài)寄存器
  269. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  270. * Output         : None
  271. * Return         : 8位狀態(tài)值
  272. *******************************************************************************/
  273. u8 read_status_reg7799(u8 chipn)  //模擬SPI
  274. {
  275.   u8 xa;
  276.   
  277.   Set_CS_7799(chipn,0);      //AD7799_CS_L;
  278.   Wr1Byte7799(chipn,0x40);
  279.   xa = Rd1Byte7799(chipn);
  280.   Set_CS_7799(chipn,1);      //AD7799_CS_H;  
  281.   return(xa);
  282. }

  283. /*******************************************************************************
  284. * Function Name  : write_reg7799
  285. * Description    : 向AD7799的任意寄存器寫入指定長(zhǎng)度的數(shù)據(jù)
  286. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  287. *                  xcomm - 命令
  288. *                   xlen - 要寫入的字節(jié)長(zhǎng)度
  289. *                     *s  -  要寫入的數(shù)據(jù)
  290. * Output         : None
  291. * Return         : None
  292. *******************************************************************************/
  293. void write_reg7799(u8 chipn,u8 xcomm, u8 xlen, u8 *s)  //模擬SPI
  294. {
  295.   u8 xi;
  296.   
  297.   Set_CS_7799(chipn,0);    //AD7799_CS_L;  
  298.   Wr1Byte7799(chipn,xcomm & 0xbf);        //bit6置為0 (0=寫)
  299.   for(xi = 0; xi < xlen; xi++)
  300.     Wr1Byte7799(chipn,s[xi]);
  301.   Set_CS_7799(chipn,1);      //AD7799_CS_H;  
  302. }

  303. /*******************************************************************************
  304. * Function Name  : read_data_reg7799
  305. * Description    : 讀AD7799的24位數(shù)據(jù)寄存器
  306. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  307. * Output         : None
  308. * Return         : 24位AD值
  309. *******************************************************************************/
  310. u32 read_data_reg7799(u8 chipn)  //模擬SPI
  311. {
  312.   u32 xa;
  313.   
  314.   xa = 0;       
  315.   Set_CS_7799(chipn,0);       //AD7799_CS_L;   
  316.   Wr1Byte7799(chipn,0x58);
  317.   xa = Rd1Byte7799(chipn);
  318.   xa = (xa << 8) & 0xffffff00;   //最低8bit清為0,準(zhǔn)備下一字節(jié)的填入
  319.   xa = xa + Rd1Byte7799(chipn);
  320.   xa = (xa << 8) & 0xffffff00;   //最低8bit清為0,準(zhǔn)備下一字節(jié)的填入
  321.   xa = xa + Rd1Byte7799(chipn);
  322.   
  323.   Set_CS_7799(chipn,1);      //AD7799_CS_H;   
  324.   return(xa);
  325. }

  326. /*******************************************************************************
  327. * Function Name  : Reset_AD7799
  328. * Description    : AD7799復(fù)位: 發(fā)送32個(gè)1,即可對(duì)AD7799復(fù)位
  329. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  330. * Output         : None
  331. * Return         : None
  332. *******************************************************************************/
  333. void Reset_AD7799(u8 chipn)  
  334. {
  335.   u8 xi;
  336.   
  337.   Set_CS_7799(chipn,0);    //AD7799_CS_L;  
  338.   for(xi = 0; xi < 4; xi++)      //發(fā)送32個(gè)
  339.   {
  340.     Wr1Byte7799(chipn,0xff);
  341.   }
  342.   Set_CS_7799(chipn,1);    //AD7799_CS_H;  
  343. }

  344. /*******************************************************************************
  345. * Function Name  : Config_AD7799
  346. * Description    : 配置AD7799
  347. * Input          : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
  348. *                  chn   - 各芯片各自的通道編號(hào)(0~2)
  349. * Output         : None
  350. * Return         : None
  351. *******************************************************************************/
  352. void Config_AD7799(u8 chipn,u8 chn)   //xchann-通道號(hào)
  353. {
  354.   u8 xwork[2];
  355.   u16 mode,config;
  356.   u8 i,chnbase;
  357.   u8  Ad7799ChnS[4] = {AD7799_CHANN_USE1,AD7799_CHANN_USE2,AD7799_CHANN_USE3,AD7799_CHANN_USE4};  //各芯片對(duì)應(yīng)的通道數(shù)
  358.   chnbase = 0;   
  359.   for(i = 0; i < chipn; i++)
  360.   {  
  361.     if(chipn > 0)
  362.     { chnbase += Ad7799ChnS[chipn-1];}
  363.   }
  364.   mode = 0; config = 0;
  365.   //MODE寄存器配置值
  366.   // 連續(xù)轉(zhuǎn)換模式      //轉(zhuǎn)換速率-用戶在AD7799.H文件中定義
  367.   mode = mode | AD7799_MODE_CONTINUE | AD7799_RATE;
  368.   
  369.   chn = chn & 0x07;
  370.   //config寄存器配置值
  371.   //雙/單極性編碼            //緩沖工作模式     //通道號(hào)
  372. #ifdef  AD7799_BIPOLAR
  373.   config = config | AD7799_CONFIG_BIPOLAR | AD7799_CONFIG_BUF_EN |chn;
  374. #else
  375.   config = config | AD7799_CONFIG_UNIPOLAR | AD7799_CONFIG_BUF_EN |chn;
  376. #endif        
  377.   //增益-用戶在AD7799.H文件中定義
  378.   if(AD7799_GAIN== AD7799_CONFIG_GAIN_AUTO)  //自動(dòng)增益
  379.   {
  380.     auto_gain(chnbase+chn);   
  381.     config = config | (AD_Work_Info[chnbase+chn].SetGain << 8);   
  382.     AD_Work_Info[chnbase+chn].CurrGain = AD_Work_Info[chnbase+chn].SetGain;
  383.   }
  384.   else   //固定增益
  385.   {  
  386.     config = config | AD7799_GAIN;   //增益128
  387.     AD_Work_Info[chnbase+chn].SetGain = (AD7799_GAIN >> 8) & 0x07;
  388.     AD_Work_Info[chnbase+chn].CurrGain = AD_Work_Info[chnbase+chn].SetGain;
  389.   }
  390.   xwork[0] = mode >> 8;   //H8
  391.   xwork[1] = mode;        //L8
  392.   write_reg7799(chipn,0x08,2,xwork);        //寫MODE寄存器:
  393.   
  394.   //寫config寄存器
  395.   xwork[0] = config >> 8;   //H8
  396.   xwork[1] = config;        //L8
  397.   write_reg7799(chipn,0x10,2,xwork);        //寫config寄存器
  398.   
  399.   //io寄存器
  400.   xwork[0] = 0x00;                //<6:4>:可用,在AIN3引腳輸出數(shù)字信號(hào)。此處為0,禁用數(shù)字輸出功能
  401.   write_reg7799(chipn,0x28,1,xwork);        //寫IO寄存器(電流源控制寄存器)
  402.   
  403. }

  404. /*******************************************************************************
  405. * Function Name  : ADC_Auto_Conversion
  406. * Description    : 輪詢各片AD7799,把最新的AD值經(jīng)濾波處理后裝入相應(yīng)的AD_Value[]通道中
  407. * Input          : None
  408. * Output         : AD_Value[](全局) - 經(jīng)濾波處理后的AD值
  409. * Return         : None
  410. *******************************************************************************/
  411. void ADC_Auto_Conversion(void)
  412. {  //滑動(dòng)平均濾波 - 與總的通道數(shù)匹配
  413.   static u8  MovingAv_Fill[AD7799_CHANN_USE] = {0};   //1=滑動(dòng)平均濾波時(shí),采集的數(shù)據(jù)已達(dá)到滿隊(duì)列的(最多3個(gè)隊(duì)列)的標(biāo)志
  414.   static float MovingAv_Buf[AD7799_CHANN_USE][MOVING_AVERAGE_BUFSIZE];   //滑動(dòng)平均濾波 - 各通道的數(shù)據(jù)緩存
  415.   static u8  MovingAv_Cnt[AD7799_CHANN_USE] = {0};   
  416.   //中位值濾波 - 與芯片數(shù)匹配
  417.   static u8  MedianFilt_Cnt[AD7799_PCS] = {0};    //中位值濾波 - 數(shù)據(jù)計(jì)數(shù)器
  418.   static s32 MedianFilt_Buf[AD7799_PCS][MEDIAN_FILTERING_BUFSIZE];   //中位值濾波 - 數(shù)據(jù)緩存
  419.   static u16  ADC_Read_Cnt = 0;                   //輪詢AD7799轉(zhuǎn)換結(jié)果的時(shí)間間隔計(jì)數(shù)器
  420.   static u32 adcerr_cnt[AD7799_PCS] = {0};        //AD7799異常計(jì)數(shù)器
  421.   
  422.   u8  Ad7799ChnS[4] = {AD7799_CHANN_USE1,AD7799_CHANN_USE2,AD7799_CHANN_USE3,AD7799_CHANN_USE4};  //各芯片對(duì)應(yīng)的通道數(shù)
  423.   s32 xd,tmp;
  424.   float xf;
  425.   u8  i,chipn;
  426.   u8  chnbase = 0;   //將各芯片的各個(gè)通道轉(zhuǎn)為全局通道時(shí),其基址編號(hào)
  427.   
  428.   ADC_Read_Cnt++;
  429.   if(ADC_Read_Cnt < ADC7799_RD_CYCLE) return;  //延時(shí)
  430.   
  431.   ADC_Read_Cnt = 0;
  432.   
  433.   for(chipn = 0; chipn < AD7799_PCS; chipn++)
  434.   {  
  435.     if(chipn == 0)
  436.     { chnbase = 0;}
  437.     else
  438.     { chnbase += Ad7799ChnS[chipn-1];}
  439.    
  440.     xd = read_status_reg7799(chipn);
  441.     ADC_Read_Cnt = 0;
  442.     adcerr_cnt[chipn]++;      //ADC異常超時(shí)計(jì)數(shù)器,為ADC_Read_Cnt的1000倍
  443.    
  444.     //在ADC轉(zhuǎn)換完成后,讀取ADC的值.(同時(shí)檢測(cè)IO口的狀態(tài)
  445.     if((xd & 0x80) == 0)  //最高位(bit7)為0,表示ADC轉(zhuǎn)換完成,則讀取轉(zhuǎn)換結(jié)果并且進(jìn)行濾波處理
  446.     {   
  447.       adcerr_cnt[chipn] = 0;
  448.       ADC_Read_Cnt = 0;
  449.       xd = xd & 0x03;  //AD7799當(dāng)前的轉(zhuǎn)換通道
  450.       if(xd >= AD7799_CHANN_USE) //通道不正確
  451.       {
  452.         ADC_Chn[chipn] = 0;
  453.         Config_AD7799(chipn,ADC_Chn[chipn]);   
  454.         return;
  455.       }
  456.       xd = read_data_reg7799(chipn);   //讀取轉(zhuǎn)換結(jié)果
  457. #ifdef  AD7799_BIPOLAR
  458.       //雙極性: 負(fù)差分輸入的AD值:0~0x7fffff;0v電壓的AD值:0x800000;正差分輸入的AD值:0x800001~0xffffff;
  459.       xd = xd - 0x800000;
  460. #endif
  461.       //中位值濾波 - 排序:把最新采集的AD值按從小到大插入到排序緩存中
  462.       if(MedianFilt_Cnt[chipn] > 0)  //中位值濾波緩存中有數(shù)據(jù),則排序
  463.       {
  464.         for(i = 0; i < MedianFilt_Cnt[chipn]; i++) //排序
  465.         {
  466.           if(MedianFilt_Buf[chipn][i] > xd)
  467.           {tmp = MedianFilt_Buf[chipn][i];
  468.           MedianFilt_Buf[chipn][i] = xd;
  469.           xd = tmp;
  470.           }
  471.         }
  472.       }
  473.       MedianFilt_Buf[chipn][MedianFilt_Cnt[chipn]] = xd;
  474.       MedianFilt_Cnt[chipn]++;
  475.       
  476.       if(MedianFilt_Cnt[chipn] >= MEDIAN_FILTERING_BUFSIZE) //連續(xù)采集完一組中位值濾波所的數(shù)據(jù), 取中值,且切換到下一個(gè)通道
  477.       {
  478.         xd = MedianFilt_Buf[chipn][MEDIAN_FILTERING_BUFSIZE/2];  //取中位值,如果總個(gè)數(shù)為偶數(shù),則取中間偏后面的數(shù)
  479.         MedianFilt_Cnt[chipn] = 0;
  480.         AD_Work_Info[chnbase+ADC_Chn[chipn]].CurrValue = xd;  //AD當(dāng)前條件(GAIN等)下的采集值,是計(jì)算自動(dòng)增益的依據(jù)
  481.         
  482.         //自動(dòng)增益與固定增益處理:
  483.         xf = (float)xd / (float)(1 << AD_Work_Info[chnbase+ADC_Chn[chipn]].SetGain);   //還原為無增益時(shí)的AD值-小數(shù)
  484.         
  485.         //滑動(dòng)平均濾波
  486.         MovingAv_Buf[chnbase+ADC_Chn[chipn]][MovingAv_Cnt[chnbase+ADC_Chn[chipn]]] = xf;
  487.         MovingAv_Cnt[chnbase+ADC_Chn[chipn]]++;
  488.         
  489.         if(MovingAv_Cnt[chnbase+ADC_Chn[chipn]]>= MOVING_AVERAGE_BUFSIZE )
  490.         {
  491.           MovingAv_Cnt[chnbase+ADC_Chn[chipn]] = 0;    //新數(shù)據(jù)循環(huán)放入緩存,且覆蓋最舊的數(shù)據(jù)
  492.           MovingAv_Fill[chnbase+ADC_Chn[chipn]] = 1;   //緩存已填滿標(biāo)志
  493.         }
  494.         //判斷用來計(jì)算平均值的緩存數(shù)據(jù)個(gè)數(shù):
  495.         if(MovingAv_Fill[chnbase+ADC_Chn[chipn]]) //數(shù)據(jù)已填滿"滑動(dòng)平均濾波"器的緩存,即按最大數(shù)據(jù)計(jì)算平均值
  496.         {tmp = MOVING_AVERAGE_BUFSIZE;}
  497.         else //數(shù)據(jù)還未填滿"滑動(dòng)平均濾波"器的緩存,則按實(shí)際個(gè)數(shù)(小于緩存的最大個(gè)數(shù))計(jì)算平均值
  498.         {tmp = MovingAv_Cnt[chnbase+ADC_Chn[chipn]];}
  499.         //求平均值
  500.         for(xf = 0.0, i = 0; i < tmp; i++)
  501.         { xf += MovingAv_Buf[chnbase+ADC_Chn[chipn]][i]; }
  502.         xf = xf / (float)tmp;
  503.         AD_Value[chnbase+ADC_Chn[chipn]].Value = xf;   
  504.         AD_Value[chnbase+ADC_Chn[chipn]].Status = 1;      //數(shù)據(jù)有效
  505.         //切換到下一通道
  506.         ADC_Chn[chipn]++;
  507.         if(ADC_Chn[chipn] >= Ad7799ChnS[chipn])
  508.         {ADC_Chn[chipn] = 0;}
  509.         if(Ad7799ChnS[chipn] > 1)  Config_AD7799(chipn,ADC_Chn[chipn]); //當(dāng)只有一個(gè)通道時(shí),不對(duì)AD7799重新初始化
  510.       }
  511.     }
  512.     else
  513.     {
  514.       if(adcerr_cnt[chipn] > 10000) //約3~10S, ADC超時(shí),未產(chǎn)生新的轉(zhuǎn)換結(jié)果,則重新初始化
  515.       {   
  516.         Reset_AD7799(chipn);
  517.         Config_AD7799(chipn,ADC_Chn[chipn]);   
  518.         adcerr_cnt[chipn] = 0;
  519.       }
  520.     }
  521.   }
  522.   
  523. }
復(fù)制代碼


第二部分.h文件
單片機(jī)源程序如下:
  1. #ifndef __user_AD7799_H
  2. #define __user_AD7799_H

  3. /************* 定義相關(guān)工作參數(shù)的結(jié)構(gòu)體    *******************************/
  4. typedef struct    //運(yùn)行參數(shù)結(jié)構(gòu)體 - 適用于每個(gè)通道
  5. {
  6.     u8    RefMode;   //1=基準(zhǔn)與信號(hào)互換;0=未互換
  7.     u8    SetGain;    //下一次ADC的設(shè)定增益:0~7 (= 1~128)
  8.     u8    CurrGain;   //當(dāng)前AD值的增益:0~7 (= 1~128)
  9.     s32   CurrValue;  //當(dāng)前最新的AD值,含GAIN,用于自動(dòng)增益
  10. }ADC_RUN_Def;

  11. typedef struct    //外部接口結(jié)構(gòu)體 - 適用于每個(gè)通道
  12. {
  13.     u8    Status;     //0=AD值無效;1=得到最新的ADC轉(zhuǎn)換結(jié)果,用戶獲取ADC值后,需清0該標(biāo)志
  14.     float Value;      //最新的AD值:1)經(jīng)過了濾波處理;2)已除以放大倍數(shù),即原始信號(hào)的AD值
  15. }ADC_VAL_Def;


  16. /**************  AD7799的MODE寄存器的相關(guān)參數(shù)定義 ********************/
  17. //轉(zhuǎn)換模式控制位: bit15,14,13
  18. #define AD7799_MODE_CONTINUE  0x0000    //v連續(xù)轉(zhuǎn)換模式(默認(rèn))
  19. #define AD7799_MODE_SINGLE    0x2000    //單次轉(zhuǎn)換模式
  20. //PSW開關(guān)控制位: bit12
  21. #define AD7799_MODE_PSW_ON    0x1000    //打開PSW開關(guān)
  22. #define AD7799_MODE_PSW_OFF   0x0000    //關(guān)閉PSW開關(guān)
  23. //bit<12:4>未使用,必須置為0
  24. //轉(zhuǎn)換速率控制位:bit3,2,1,0
  25. #define AD7799_MODE_4_17HZ    0x000f    //轉(zhuǎn)換速率=4.17hz;  抑制:74db(50,60hz)
  26. #define AD7799_MODE_6_25HZ    0x000e    //轉(zhuǎn)換速率=6.25hz;  抑制:72db(50,60hz)
  27. #define AD7799_MODE_8_33HZ    0x000d    //轉(zhuǎn)換速率=8.33hz;  抑制:70db(50,60hz)
  28. #define AD7799_MODE_10HZ      0x000c    //轉(zhuǎn)換速率=10hz  ;  抑制:69db(50,60hz)
  29. #define AD7799_MODE_12_5HZ    0x000b    //轉(zhuǎn)換速率=12.5hz;  抑制:66db(50,60hz)
  30. #define AD7799_MODE_16_7HZ    0x000a    //轉(zhuǎn)換速率=16.7hz;  抑制:65db(50,60hz)
  31. #define AD7799_MODE_16_50HZ   0x0009    //轉(zhuǎn)換速率=16.7hz;  抑制:80db(僅50hz)
  32. #define AD7799_MODE_19_6HZ    0x0008    //轉(zhuǎn)換速率=19.6hz;  抑制:90db(僅60hz)
  33. #define AD7799_MODE_50HZ      0x0005    //轉(zhuǎn)換速率=50hz;    抑制:-
  34. #define AD7799_MODE_470HZ     0x0001    //轉(zhuǎn)換速率=470hz;   抑制:-

  35. /**************  AD7799的CONFIG寄存器的相關(guān)參數(shù)定義 ********************/
  36. //bit15,14,11,7,6,3未使用;
  37. //BIT13-為100nA電流源使能(=1),默認(rèn)為0(關(guān)閉),所以未定義
  38. //差分輸入信號(hào)的單/雙極性編碼控制: bit12
  39. #define AD7799_CONFIG_BIPOLAR     0x0000    //雙極性編碼(默認(rèn))
  40. #define AD7799_CONFIG_UNIPOLAR    0x1000    //v單極性編碼
  41. //增益選擇位: bit10,9,8
  42. #define AD7799_CONFIG_GAIN_1      0x0000    //增益=1(儀表放大器不用)
  43. #define AD7799_CONFIG_GAIN_2      0x0100    //增益=2(儀表放大器不用)
  44. #define AD7799_CONFIG_GAIN_4      0x0200    //增益=4
  45. #define AD7799_CONFIG_GAIN_8      0x0300    //增益=8
  46. #define AD7799_CONFIG_GAIN_16     0x0400    //增益=16
  47. #define AD7799_CONFIG_GAIN_32     0x0500    //增益=32
  48. #define AD7799_CONFIG_GAIN_64     0x0600    //增益=64
  49. #define AD7799_CONFIG_GAIN_128    0x0700    //增益=128
  50. #define AD7799_CONFIG_GAIN_AUTO   0X5A5A    //自動(dòng)增益 - AD7799硬件無該功能,該功能由軟件自動(dòng)實(shí)現(xiàn)
  51. //基準(zhǔn)電壓檢測(cè)位: bit5
  52. #define AD7799_CONFIG_REFDET_EN   0x0020    //基準(zhǔn)電壓檢測(cè)功能有效:當(dāng)外部基準(zhǔn)電壓開路或小于0.5V時(shí),狀態(tài)寄存器的NOXREF位置位
  53. #define AD7799_CONFIG_REFDET_DIS  0x0000    //基準(zhǔn)電壓檢測(cè)功能禁用
  54. //BUF位: bit4
  55. #define AD7799_CONFIG_BUF_EN      0x0010    //v緩沖工作模式
  56. #define AD7799_CONFIG_BUF_DIS     0x0000    //無緩沖工作模式
  57. //通道選擇位: bit2,1,0
  58. #define AD7799_CONFIG_AIN1        0x0000    //AIN1差分輸入
  59. #define AD7799_CONFIG_AIN2        0x0001    //AIN2差分輸入
  60. #define AD7799_CONFIG_AIN3        0x0002    //AIN3差分輸入



  61. void AD7799_CS_Pin_Configuration(u8 chipn);
  62. void AD7799_SCLK_Pin_Configuration(u8 chipn);
  63. void AD7799_DIN_Pin_Configuration(u8 chipn);
  64. void AD7799_DOUT_Pin_Configuration(u8 chipn);
  65. void Wr1Byte7799(u8 chipn,u8 data);
  66. void Delay_7799(u16 timecount);

  67. u8 Rd1Byte7799(u8 chipn);
  68. u8 read_status_reg7799(u8 chipn);
  69. void write_reg7799(u8 chipn,u8 xcomm, u8 xlen, u8 *s);
  70. u32 read_data_reg7799(u8 chipn);
  71. void Config_AD7799(u8 chipn,u8 chn);
  72. void auto_gain(u8 chn);

  73. /************* 外部用戶接口    *******************************/

  74. /**************** AD7799使用數(shù)據(jù)及每片ADC的通道數(shù)  **********/
  75. #define AD7799_PCS                 2                       //AD7799芯片數(shù)量(1~4)
  76. #define AD7799_CHANN_USE1          2                       //第1片AD7799的通道數(shù)(1~3)
  77. #define AD7799_CHANN_USE2          2                       //第2片AD7799的通道數(shù)(0~3,該芯片未使用時(shí)必須置為0)
  78. #define AD7799_CHANN_USE3          0                       //第3片AD7799的通道數(shù)(0~3,該芯片未使用時(shí)必須置為0)
  79. #define AD7799_CHANN_USE4          0                       //第4片AD7799的通道數(shù)(0~3,該芯片未使用時(shí)必須置為0)
  80. #define AD7799_CHANN_USE           4        //總的通道數(shù):各AD7799通道數(shù)之和
  81. //#define AD7799_CHANN_USE  AD7799_CHANN_USE1+AD7799_CHANN_USE2+AD7799_CHANN_USE3+AD7799_CHANN_USE4

  82. //定義AD_Value[]變量的通道編號(hào),從0開始編號(hào)。注意:包括第二片的編號(hào)
  83. typedef enum   
  84. {
  85.   ADSF = 0,   //
  86.   ADSB,       //
  87.   ADBP,       //
  88.   ADOTH,      //
  89. }AdcChName;

  90. /**************** ADC片選引腳CS 輸出GPIO  --可修改 --必須為4個(gè) **********/
  91. #define  ADC1_CS_PORT    GPIOA   //PA4
  92. #define  ADC2_CS_PORT    GPIOB   //PB12
  93. #define  ADC3_CS_PORT    0   //
  94. #define  ADC4_CS_PORT    0   //
  95. #define  ADC1_CS_PIN     GPIO_Pin_4
  96. #define  ADC2_CS_PIN     GPIO_Pin_12
  97. #define  ADC3_CS_PIN     0
  98. #define  ADC4_CS_PIN     0
  99. /**************** ADC SPI時(shí)鐘引腳SCLK 輸出GPIO  --可修改 --必須為4個(gè) **********/
  100. #define  ADC1_SCLK_PORT    GPIOA   //PA5
  101. #define  ADC2_SCLK_PORT    GPIOB   //PB13
  102. #define  ADC3_SCLK_PORT    0   //
  103. #define  ADC4_SCLK_PORT    0   //
  104. #define  ADC1_SCLK_PIN     GPIO_Pin_5
  105. #define  ADC2_SCLK_PIN     GPIO_Pin_13
  106. #define  ADC3_SCLK_PIN     0
  107. #define  ADC4_SCLK_PIN     0
  108. /**************** ADC數(shù)據(jù)輸入引腳DIN 輸出GPIO  --可修改 --必須為4個(gè) **********/
  109. #define  ADC1_DIN_PORT    GPIOA   //PA7
  110. #define  ADC2_DIN_PORT    GPIOB   //PB15
  111. #define  ADC3_DIN_PORT    0   //
  112. #define  ADC4_DIN_PORT    0   //
  113. #define  ADC1_DIN_PIN     GPIO_Pin_7
  114. #define  ADC2_DIN_PIN     GPIO_Pin_15
  115. #define  ADC3_DIN_PIN     0
  116. #define  ADC4_DIN_PIN     0
  117. /**************** ADC數(shù)據(jù)輸出引腳DOUT 輸入GPIO  --可修改 --必須為4個(gè) **********/
  118. #define  ADC1_DOUT_PORT    GPIOA   //PA6
  119. #define  ADC2_DOUT_PORT    GPIOB   //PB14
  120. #define  ADC3_DOUT_PORT    0   //
  121. #define  ADC4_DOUT_PORT    0   //
  122. #define  ADC1_DOUT_PIN     GPIO_Pin_6
  123. #define  ADC2_DOUT_PIN     GPIO_Pin_14
  124. #define  ADC3_DOUT_PIN     0
  125. #define  ADC4_DOUT_PIN     0

  126. /***********  定義ADC采樣的濾波參數(shù)      **********
  127. * 2種濾波算法結(jié)合:中位值濾波法和遞推平均濾波法(又稱滑動(dòng)平均濾波法)
  128. */
  129. #define  MEDIAN_FILTERING_BUFSIZE 4     //中位值濾波的(連續(xù))數(shù)據(jù)采集次數(shù).
  130. #define  MOVING_AVERAGE_BUFSIZE   3     //遞推平均濾波的隊(duì)列長(zhǎng)度.

  131. #define AD7799_RATE               AD7799_MODE_10HZ //AD7799_MODE_10HZ        //設(shè)定ADC的轉(zhuǎn)換速率
  132. #define AD7799_GAIN               AD7799_CONFIG_GAIN_128  //設(shè)定ADC的增益
  133. ……………………

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

所有資料51hei提供下載:
STM32 .AD7799程序.doc (134 KB, 下載次數(shù): 125)


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

使用道具 舉報(bào)

沙發(fā)
ID:289512 發(fā)表于 2018-3-31 09:54 | 只看該作者
好東西。。。。。。。。。。。。
回復(fù)

使用道具 舉報(bào)

板凳
ID:586345 發(fā)表于 2019-7-18 14:20 | 只看該作者
好東西,下載學(xué)習(xí)一下。
回復(fù)

使用道具 舉報(bào)

地板
ID:601877 發(fā)表于 2020-1-14 15:13 | 只看該作者
自動(dòng)掃描頻率多少,怎么更改
回復(fù)

使用道具 舉報(bào)

5#
ID:718766 發(fā)表于 2020-10-28 15:17 | 只看該作者
正好在用這個(gè),頂一下
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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