|
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ù)
- ***********************************************************************************
- * @file ~/USER/TM7711.c
- * @author TianYu
- * @version V0.9
- * @date 29-Aug-2011
- * @brief This file contains all of the initialization function for this project
- ***********************************************************************************
- **/
- //Defined necessary head file and CONST flag
- #include"stm32f10x_conf.h"
- #include"stm32f10x.h"
- #include "AD7799.h"
- #include "main.h"
- ADC_VAL_Def AD_Value[AD7799_CHANN_USE]; //各通道(含所有芯片)的ADC值,經(jīng)數(shù)字濾波后的ADC值
- ADC_RUN_Def AD_Work_Info[AD7799_CHANN_USE]; //各通道(含所有芯片)的工作信息
- u8 ADC_Chn[AD7799_PCS] = {0}; //各芯片 ADC轉(zhuǎn)換通道號(hào):0~2
- #define SPI_PULSE_WIDE 20 //SPI模擬通信中,時(shí)鐘信號(hào)的延時(shí)
- /*******************************************************************************
- * Function Name : auto_gain
- * Description : 根據(jù)采樣的AD值,自動(dòng)調(diào)整AD7799的增益
- * Input : chn - ADC的采樣通道(AD7799_CHANN_USE以內(nèi))
- * Output : 全局變量AD_Work_Info[chn].SetGain,其值為0~7,對(duì)應(yīng)增益為1~128
- * Return : None
- * 算法說明 : 在增益未達(dá)最大和最小時(shí),自動(dòng)控制增益后的AD值在%40~80%之間
- *******************************************************************************/
- void auto_gain(u8 chn)
- {
- u32 xd,xcv;
-
- chn = chn & 0x03;
-
- if(AD_Work_Info[chn].CurrValue < 0) xcv = -AD_Work_Info[chn].CurrValue;
- else xcv = AD_Work_Info[chn].CurrValue;
-
- if(xcv > (REF_FULL_VAL * 81 / 100)) //大于81%,則在增益系數(shù)值不為0時(shí),增益系數(shù)-1(即增益降低2倍)
- {
- if(AD_Work_Info[chn].CurrGain)
- { AD_Work_Info[chn].SetGain = AD_Work_Info[chn].CurrGain - 1;}
- }
- else if(xcv < (REF_FULL_VAL * 39/ 100)) //小于39%時(shí),直接把增益增大N倍,使其達(dá)到50%以內(nèi)。
- {
- xd = REF_FULL_VAL / xcv;
- xd = xd / 2;
- if(xd)
- {
- xd--;
- }
- AD_Work_Info[chn].SetGain = AD_Work_Info[chn].CurrGain + xd;
- if(AD_Work_Info[chn].SetGain >= 7) //限制最大增益系數(shù)為7,即128倍
- {
- AD_Work_Info[chn].SetGain = 7;
- }
- }
-
- }
- /*******************************************************************************
- * Function Name : ADC7799_Init
- * Description : AD7799初始化: GPIO,配置啟動(dòng),變量清0
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void ADC7799_Init(void)
- {
- u8 i;
- for(i = 0; i < AD7799_CHANN_USE; i++)
- {
- AD_Value[i].Status = 0;
- AD_Value[i].Value = 0;
-
- AD_Work_Info[i].RefMode = 0;
- AD_Work_Info[i].SetGain = 0;
- AD_Work_Info[i].CurrGain = 0;
- AD_Work_Info[i].CurrValue = 0;
- }
-
- for(i = 0; i < AD7799_PCS; i++)
- {
- AD7799_CS_Pin_Configuration(i);
- AD7799_SCLK_Pin_Configuration(i);
- AD7799_DIN_Pin_Configuration(i);
- AD7799_DOUT_Pin_Configuration(i);
- ADC_Chn[i] = 0;
- Config_AD7799(i,ADC_Chn[i]);
- }
- }
- /*******************************************************************************
- * Function Name : AD7799_SCLK_Pin_Configuration
- * Description : 配置MCU與各AD7799的CS連接的引腳 (OUT)
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * Output : None
- * Return : None
- *******************************************************************************/
- void AD7799_CS_Pin_Configuration(u8 chipn)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_TypeDef *AD7799_PORT[4] = {ADC1_CS_PORT,ADC2_CS_PORT,ADC3_CS_PORT,ADC4_CS_PORT}; //端口
- uint16_t AD7799_PINx[4] = {ADC1_CS_PIN, ADC2_CS_PIN, ADC3_CS_PIN, ADC4_CS_PIN }; //Pin
-
- if(AD7799_PORT[chipn] && (chipn < AD7799_PCS)) //端口和芯片有效,才對(duì)端口進(jìn)行配置
- {
- GPIO_InitStructure.GPIO_Pin = AD7799_PINx[chipn];
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽輸出
- GPIO_Init(AD7799_PORT[chipn], &GPIO_InitStructure);
- }
- }
- /*******************************************************************************
- * Function Name : AD7799_SCLK_Pin_Configuration
- * Description : 配置MCU與各AD7799的SCLK連接的引腳 (OUT)
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * Output : None
- * Return : None
- *******************************************************************************/
- void AD7799_SCLK_Pin_Configuration(u8 chipn)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_TypeDef *AD7799_PORT[4] = {ADC1_SCLK_PORT,ADC2_SCLK_PORT,ADC3_SCLK_PORT,ADC4_SCLK_PORT}; //端口
- uint16_t AD7799_PINx[4] = {ADC1_SCLK_PIN, ADC2_SCLK_PIN, ADC3_SCLK_PIN, ADC4_SCLK_PIN }; //Pin
-
- if(AD7799_PORT[chipn] && (chipn < AD7799_PCS)) //端口和芯片有效,才對(duì)端口進(jìn)行配置
- {
- GPIO_InitStructure.GPIO_Pin = AD7799_PINx[chipn];
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽輸出
- GPIO_Init(AD7799_PORT[chipn], &GPIO_InitStructure);
- }
- }
- /*******************************************************************************
- * Function Name : AD7799_SCLK_Pin_Configuration
- * Description : 配置MCU與各AD7799的DIN連接的引腳 (OUT)
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * Output : None
- * Return : None
- *******************************************************************************/
- void AD7799_DIN_Pin_Configuration(u8 chipn)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_TypeDef *AD7799_PORT[4] = {ADC1_DIN_PORT,ADC2_DIN_PORT,ADC3_DIN_PORT,ADC4_DIN_PORT}; //端口
- uint16_t AD7799_PINx[4] = {ADC1_DIN_PIN, ADC2_DIN_PIN, ADC3_DIN_PIN, ADC4_DIN_PIN }; //Pin
-
- if(AD7799_PORT[chipn] && (chipn < AD7799_PCS)) //端口和芯片有效,才對(duì)端口進(jìn)行配置
- {
- GPIO_InitStructure.GPIO_Pin = AD7799_PINx[chipn];
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽輸出
- GPIO_Init(AD7799_PORT[chipn], &GPIO_InitStructure);
- }
- }
- /*******************************************************************************
- * Function Name : AD7799_SCLK_Pin_Configuration
- * Description : 配置MCU與各AD7799的DOUT連接的引腳 (IN)
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * Output : None
- * Return : None
- *******************************************************************************/
- void AD7799_DOUT_Pin_Configuration(u8 chipn)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_TypeDef *AD7799_PORT[4] = {ADC1_DOUT_PORT,ADC2_DOUT_PORT,ADC3_DOUT_PORT,ADC4_DOUT_PORT}; //端口
- uint16_t AD7799_PINx[4] = {ADC1_DOUT_PIN, ADC2_DOUT_PIN, ADC3_DOUT_PIN, ADC4_DOUT_PIN }; //Pin
-
- if(AD7799_PORT[chipn] && (chipn < AD7799_PCS)) //端口和芯片有效,才對(duì)端口進(jìn)行配置
- {
- GPIO_InitStructure.GPIO_Pin = AD7799_PINx[chipn];
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上接輸入
- GPIO_Init(AD7799_PORT[chipn], &GPIO_InitStructure);
- }
- }
- /*******************************************************************************
- * Function Name : Delay_7799
- * Description : 延時(shí)函數(shù)
- * Input : timecount - 延時(shí)參數(shù)(0~65535)
- * Output : None
- * Return : None
- *******************************************************************************/
- void Delay_7799(u16 timecount)
- {
- while(timecount>0)
- timecount--;
- }
- /*******************************************************************************
- * Function Name : Wr1Byte7799
- * Description : 向AD7799寫入1字節(jié)(MSB在前,即左移)上沿鎖存
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * data - 寫入的8bit數(shù)據(jù)
- * Output : None
- * Return : None
- *******************************************************************************/
- void Wr1Byte7799(u8 chipn,u8 data) //模擬SPI
- {
- GPIO_TypeDef *AD7799_DIN_PORT[4] = {ADC1_DIN_PORT,ADC2_DIN_PORT,ADC3_DIN_PORT,ADC4_DIN_PORT}; //端口
- uint16_t AD7799_DIN_PINx[4] = {ADC1_DIN_PIN, ADC2_DIN_PIN, ADC3_DIN_PIN, ADC4_DIN_PIN }; //Pin
- GPIO_TypeDef *AD7799_SCLK_PORT[4] = {ADC1_SCLK_PORT,ADC2_SCLK_PORT,ADC3_SCLK_PORT,ADC4_SCLK_PORT}; //端口
- uint16_t AD7799_SCLK_PINx[4] = {ADC1_SCLK_PIN, ADC2_SCLK_PIN, ADC3_SCLK_PIN, ADC4_SCLK_PIN }; //Pin
-
- u8 xi;
- for(xi = 0; xi < 8; xi++)
- { GPIO_ResetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]); //AD7799_CLK_L;
- if((data & 0x80) == 0x80 )
- {
- GPIO_SetBits(AD7799_DIN_PORT[chipn],AD7799_DIN_PINx[chipn]); //AD7799_DIN_H;
- }
- else
- {
- GPIO_ResetBits(AD7799_DIN_PORT[chipn],AD7799_DIN_PINx[chipn]); //AD7799_DIN_L;
- }
- Delay_7799(SPI_PULSE_WIDE);
- data = data << 1; //左移1位
- GPIO_SetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]); //AD7799_CLK_H;
- Delay_7799(SPI_PULSE_WIDE);
- }
- }
- /*******************************************************************************
- * Function Name : Rd1Byte7799
- * Description : 讀1字節(jié), AD7799在下沿輸出數(shù)據(jù),上升沿時(shí)數(shù)據(jù)有效,MSB在前
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * Output : None
- * Return : 8位數(shù)據(jù)
- *******************************************************************************/
- u8 Rd1Byte7799(u8 chipn) //模擬SPI
- {
- GPIO_TypeDef *AD7799_DOUT_PORT[4] = {ADC1_DOUT_PORT,ADC2_DOUT_PORT,ADC3_DOUT_PORT,ADC4_DOUT_PORT}; //端口
- uint16_t AD7799_DOUT_PINx[4] = {ADC1_DOUT_PIN, ADC2_DOUT_PIN, ADC3_DOUT_PIN, ADC4_DOUT_PIN }; //Pin
- GPIO_TypeDef *AD7799_SCLK_PORT[4] = {ADC1_SCLK_PORT,ADC2_SCLK_PORT,ADC3_SCLK_PORT,ADC4_SCLK_PORT}; //端口
- uint16_t AD7799_SCLK_PINx[4] = {ADC1_SCLK_PIN, ADC2_SCLK_PIN, ADC3_SCLK_PIN, ADC4_SCLK_PIN }; //Pin
- u8 xi,xd = 0;
-
- GPIO_SetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]); // AD7799_CLK_H;
- for(xi = 0,xd = 0; xi < 8; xi++)
- {
- Delay_7799(SPI_PULSE_WIDE);
- GPIO_ResetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]); //AD7799_CLK_L;
- Delay_7799(SPI_PULSE_WIDE);
- xd = xd * 2; //左移一位
- // if(AD7799_DOUT) xd++;
- if(GPIO_ReadInputDataBit(AD7799_DOUT_PORT[chipn],AD7799_DOUT_PINx[chipn]))
- {xd++;}
- GPIO_SetBits(AD7799_SCLK_PORT[chipn],AD7799_SCLK_PINx[chipn]); //AD7799_CLK_H;
- }
- return xd;
- }
- /*******************************************************************************
- * Function Name : Set_CS_7799
- * Description : 設(shè)置AD7799的CS為高電平(1)或低電平(0)
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * val - CS的電平值: 0=低電平; 1=高電平
- * Output : None
- * Return : None
- *******************************************************************************/
- void Set_CS_7799(u8 chipn,u8 val)
- {
- GPIO_TypeDef *AD7799_CS_PORT[4] = {ADC1_CS_PORT,ADC2_CS_PORT,ADC3_CS_PORT,ADC4_CS_PORT}; //端口
- uint16_t AD7799_CS_PINx[4] = {ADC1_CS_PIN, ADC2_CS_PIN, ADC3_CS_PIN, ADC4_CS_PIN }; //Pin
-
- if(val == 0)
- {
- GPIO_ResetBits(AD7799_CS_PORT[chipn],AD7799_CS_PINx[chipn]); //AD7799_CS_L;
- }
- else
- {
- GPIO_SetBits(AD7799_CS_PORT[chipn],AD7799_CS_PINx[chipn]); //AD7799_CS_H;
- }
- }
- /*******************************************************************************
- * Function Name : read_status_reg7799
- * Description : 讀AD7799的狀態(tài)寄存器
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * Output : None
- * Return : 8位狀態(tài)值
- *******************************************************************************/
- u8 read_status_reg7799(u8 chipn) //模擬SPI
- {
- u8 xa;
-
- Set_CS_7799(chipn,0); //AD7799_CS_L;
- Wr1Byte7799(chipn,0x40);
- xa = Rd1Byte7799(chipn);
- Set_CS_7799(chipn,1); //AD7799_CS_H;
- return(xa);
- }
- /*******************************************************************************
- * Function Name : write_reg7799
- * Description : 向AD7799的任意寄存器寫入指定長(zhǎng)度的數(shù)據(jù)
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * xcomm - 命令
- * xlen - 要寫入的字節(jié)長(zhǎng)度
- * *s - 要寫入的數(shù)據(jù)
- * Output : None
- * Return : None
- *******************************************************************************/
- void write_reg7799(u8 chipn,u8 xcomm, u8 xlen, u8 *s) //模擬SPI
- {
- u8 xi;
-
- Set_CS_7799(chipn,0); //AD7799_CS_L;
- Wr1Byte7799(chipn,xcomm & 0xbf); //bit6置為0 (0=寫)
- for(xi = 0; xi < xlen; xi++)
- Wr1Byte7799(chipn,s[xi]);
- Set_CS_7799(chipn,1); //AD7799_CS_H;
- }
- /*******************************************************************************
- * Function Name : read_data_reg7799
- * Description : 讀AD7799的24位數(shù)據(jù)寄存器
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * Output : None
- * Return : 24位AD值
- *******************************************************************************/
- u32 read_data_reg7799(u8 chipn) //模擬SPI
- {
- u32 xa;
-
- xa = 0;
- Set_CS_7799(chipn,0); //AD7799_CS_L;
- Wr1Byte7799(chipn,0x58);
- xa = Rd1Byte7799(chipn);
- xa = (xa << 8) & 0xffffff00; //最低8bit清為0,準(zhǔn)備下一字節(jié)的填入
- xa = xa + Rd1Byte7799(chipn);
- xa = (xa << 8) & 0xffffff00; //最低8bit清為0,準(zhǔn)備下一字節(jié)的填入
- xa = xa + Rd1Byte7799(chipn);
-
- Set_CS_7799(chipn,1); //AD7799_CS_H;
- return(xa);
- }
- /*******************************************************************************
- * Function Name : Reset_AD7799
- * Description : AD7799復(fù)位: 發(fā)送32個(gè)1,即可對(duì)AD7799復(fù)位
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * Output : None
- * Return : None
- *******************************************************************************/
- void Reset_AD7799(u8 chipn)
- {
- u8 xi;
-
- Set_CS_7799(chipn,0); //AD7799_CS_L;
- for(xi = 0; xi < 4; xi++) //發(fā)送32個(gè)
- {
- Wr1Byte7799(chipn,0xff);
- }
- Set_CS_7799(chipn,1); //AD7799_CS_H;
- }
- /*******************************************************************************
- * Function Name : Config_AD7799
- * Description : 配置AD7799
- * Input : chipn - AD7799芯片編號(hào):0~(AD7799_PCS-1),最大3
- * chn - 各芯片各自的通道編號(hào)(0~2)
- * Output : None
- * Return : None
- *******************************************************************************/
- void Config_AD7799(u8 chipn,u8 chn) //xchann-通道號(hào)
- {
- u8 xwork[2];
- u16 mode,config;
- u8 i,chnbase;
- u8 Ad7799ChnS[4] = {AD7799_CHANN_USE1,AD7799_CHANN_USE2,AD7799_CHANN_USE3,AD7799_CHANN_USE4}; //各芯片對(duì)應(yīng)的通道數(shù)
- chnbase = 0;
- for(i = 0; i < chipn; i++)
- {
- if(chipn > 0)
- { chnbase += Ad7799ChnS[chipn-1];}
- }
- mode = 0; config = 0;
- //MODE寄存器配置值
- // 連續(xù)轉(zhuǎn)換模式 //轉(zhuǎn)換速率-用戶在AD7799.H文件中定義
- mode = mode | AD7799_MODE_CONTINUE | AD7799_RATE;
-
- chn = chn & 0x07;
- //config寄存器配置值
- //雙/單極性編碼 //緩沖工作模式 //通道號(hào)
- #ifdef AD7799_BIPOLAR
- config = config | AD7799_CONFIG_BIPOLAR | AD7799_CONFIG_BUF_EN |chn;
- #else
- config = config | AD7799_CONFIG_UNIPOLAR | AD7799_CONFIG_BUF_EN |chn;
- #endif
- //增益-用戶在AD7799.H文件中定義
- if(AD7799_GAIN== AD7799_CONFIG_GAIN_AUTO) //自動(dòng)增益
- {
- auto_gain(chnbase+chn);
- config = config | (AD_Work_Info[chnbase+chn].SetGain << 8);
- AD_Work_Info[chnbase+chn].CurrGain = AD_Work_Info[chnbase+chn].SetGain;
- }
- else //固定增益
- {
- config = config | AD7799_GAIN; //增益128
- AD_Work_Info[chnbase+chn].SetGain = (AD7799_GAIN >> 8) & 0x07;
- AD_Work_Info[chnbase+chn].CurrGain = AD_Work_Info[chnbase+chn].SetGain;
- }
- xwork[0] = mode >> 8; //H8
- xwork[1] = mode; //L8
- write_reg7799(chipn,0x08,2,xwork); //寫MODE寄存器:
-
- //寫config寄存器
- xwork[0] = config >> 8; //H8
- xwork[1] = config; //L8
- write_reg7799(chipn,0x10,2,xwork); //寫config寄存器
-
- //io寄存器
- xwork[0] = 0x00; //<6:4>:可用,在AIN3引腳輸出數(shù)字信號(hào)。此處為0,禁用數(shù)字輸出功能
- write_reg7799(chipn,0x28,1,xwork); //寫IO寄存器(電流源控制寄存器)
-
- }
- /*******************************************************************************
- * Function Name : ADC_Auto_Conversion
- * Description : 輪詢各片AD7799,把最新的AD值經(jīng)濾波處理后裝入相應(yīng)的AD_Value[]通道中
- * Input : None
- * Output : AD_Value[](全局) - 經(jīng)濾波處理后的AD值
- * Return : None
- *******************************************************************************/
- void ADC_Auto_Conversion(void)
- { //滑動(dòng)平均濾波 - 與總的通道數(shù)匹配
- static u8 MovingAv_Fill[AD7799_CHANN_USE] = {0}; //1=滑動(dòng)平均濾波時(shí),采集的數(shù)據(jù)已達(dá)到滿隊(duì)列的(最多3個(gè)隊(duì)列)的標(biāo)志
- static float MovingAv_Buf[AD7799_CHANN_USE][MOVING_AVERAGE_BUFSIZE]; //滑動(dòng)平均濾波 - 各通道的數(shù)據(jù)緩存
- static u8 MovingAv_Cnt[AD7799_CHANN_USE] = {0};
- //中位值濾波 - 與芯片數(shù)匹配
- static u8 MedianFilt_Cnt[AD7799_PCS] = {0}; //中位值濾波 - 數(shù)據(jù)計(jì)數(shù)器
- static s32 MedianFilt_Buf[AD7799_PCS][MEDIAN_FILTERING_BUFSIZE]; //中位值濾波 - 數(shù)據(jù)緩存
- static u16 ADC_Read_Cnt = 0; //輪詢AD7799轉(zhuǎn)換結(jié)果的時(shí)間間隔計(jì)數(shù)器
- static u32 adcerr_cnt[AD7799_PCS] = {0}; //AD7799異常計(jì)數(shù)器
-
- u8 Ad7799ChnS[4] = {AD7799_CHANN_USE1,AD7799_CHANN_USE2,AD7799_CHANN_USE3,AD7799_CHANN_USE4}; //各芯片對(duì)應(yīng)的通道數(shù)
- s32 xd,tmp;
- float xf;
- u8 i,chipn;
- u8 chnbase = 0; //將各芯片的各個(gè)通道轉(zhuǎn)為全局通道時(shí),其基址編號(hào)
-
- ADC_Read_Cnt++;
- if(ADC_Read_Cnt < ADC7799_RD_CYCLE) return; //延時(shí)
-
- ADC_Read_Cnt = 0;
-
- for(chipn = 0; chipn < AD7799_PCS; chipn++)
- {
- if(chipn == 0)
- { chnbase = 0;}
- else
- { chnbase += Ad7799ChnS[chipn-1];}
-
- xd = read_status_reg7799(chipn);
- ADC_Read_Cnt = 0;
- adcerr_cnt[chipn]++; //ADC異常超時(shí)計(jì)數(shù)器,為ADC_Read_Cnt的1000倍
-
- //在ADC轉(zhuǎn)換完成后,讀取ADC的值.(同時(shí)檢測(cè)IO口的狀態(tài)
- if((xd & 0x80) == 0) //最高位(bit7)為0,表示ADC轉(zhuǎn)換完成,則讀取轉(zhuǎn)換結(jié)果并且進(jìn)行濾波處理
- {
- adcerr_cnt[chipn] = 0;
- ADC_Read_Cnt = 0;
- xd = xd & 0x03; //AD7799當(dāng)前的轉(zhuǎn)換通道
- if(xd >= AD7799_CHANN_USE) //通道不正確
- {
- ADC_Chn[chipn] = 0;
- Config_AD7799(chipn,ADC_Chn[chipn]);
- return;
- }
- xd = read_data_reg7799(chipn); //讀取轉(zhuǎn)換結(jié)果
- #ifdef AD7799_BIPOLAR
- //雙極性: 負(fù)差分輸入的AD值:0~0x7fffff;0v電壓的AD值:0x800000;正差分輸入的AD值:0x800001~0xffffff;
- xd = xd - 0x800000;
- #endif
- //中位值濾波 - 排序:把最新采集的AD值按從小到大插入到排序緩存中
- if(MedianFilt_Cnt[chipn] > 0) //中位值濾波緩存中有數(shù)據(jù),則排序
- {
- for(i = 0; i < MedianFilt_Cnt[chipn]; i++) //排序
- {
- if(MedianFilt_Buf[chipn][i] > xd)
- {tmp = MedianFilt_Buf[chipn][i];
- MedianFilt_Buf[chipn][i] = xd;
- xd = tmp;
- }
- }
- }
- MedianFilt_Buf[chipn][MedianFilt_Cnt[chipn]] = xd;
- MedianFilt_Cnt[chipn]++;
-
- if(MedianFilt_Cnt[chipn] >= MEDIAN_FILTERING_BUFSIZE) //連續(xù)采集完一組中位值濾波所的數(shù)據(jù), 取中值,且切換到下一個(gè)通道
- {
- xd = MedianFilt_Buf[chipn][MEDIAN_FILTERING_BUFSIZE/2]; //取中位值,如果總個(gè)數(shù)為偶數(shù),則取中間偏后面的數(shù)
- MedianFilt_Cnt[chipn] = 0;
- AD_Work_Info[chnbase+ADC_Chn[chipn]].CurrValue = xd; //AD當(dāng)前條件(GAIN等)下的采集值,是計(jì)算自動(dòng)增益的依據(jù)
-
- //自動(dòng)增益與固定增益處理:
- xf = (float)xd / (float)(1 << AD_Work_Info[chnbase+ADC_Chn[chipn]].SetGain); //還原為無增益時(shí)的AD值-小數(shù)
-
- //滑動(dòng)平均濾波
- MovingAv_Buf[chnbase+ADC_Chn[chipn]][MovingAv_Cnt[chnbase+ADC_Chn[chipn]]] = xf;
- MovingAv_Cnt[chnbase+ADC_Chn[chipn]]++;
-
- if(MovingAv_Cnt[chnbase+ADC_Chn[chipn]]>= MOVING_AVERAGE_BUFSIZE )
- {
- MovingAv_Cnt[chnbase+ADC_Chn[chipn]] = 0; //新數(shù)據(jù)循環(huán)放入緩存,且覆蓋最舊的數(shù)據(jù)
- MovingAv_Fill[chnbase+ADC_Chn[chipn]] = 1; //緩存已填滿標(biāo)志
- }
- //判斷用來計(jì)算平均值的緩存數(shù)據(jù)個(gè)數(shù):
- if(MovingAv_Fill[chnbase+ADC_Chn[chipn]]) //數(shù)據(jù)已填滿"滑動(dòng)平均濾波"器的緩存,即按最大數(shù)據(jù)計(jì)算平均值
- {tmp = MOVING_AVERAGE_BUFSIZE;}
- else //數(shù)據(jù)還未填滿"滑動(dòng)平均濾波"器的緩存,則按實(shí)際個(gè)數(shù)(小于緩存的最大個(gè)數(shù))計(jì)算平均值
- {tmp = MovingAv_Cnt[chnbase+ADC_Chn[chipn]];}
- //求平均值
- for(xf = 0.0, i = 0; i < tmp; i++)
- { xf += MovingAv_Buf[chnbase+ADC_Chn[chipn]][i]; }
- xf = xf / (float)tmp;
- AD_Value[chnbase+ADC_Chn[chipn]].Value = xf;
- AD_Value[chnbase+ADC_Chn[chipn]].Status = 1; //數(shù)據(jù)有效
- //切換到下一通道
- ADC_Chn[chipn]++;
- if(ADC_Chn[chipn] >= Ad7799ChnS[chipn])
- {ADC_Chn[chipn] = 0;}
- if(Ad7799ChnS[chipn] > 1) Config_AD7799(chipn,ADC_Chn[chipn]); //當(dāng)只有一個(gè)通道時(shí),不對(duì)AD7799重新初始化
- }
- }
- else
- {
- if(adcerr_cnt[chipn] > 10000) //約3~10S, ADC超時(shí),未產(chǎn)生新的轉(zhuǎn)換結(jié)果,則重新初始化
- {
- Reset_AD7799(chipn);
- Config_AD7799(chipn,ADC_Chn[chipn]);
- adcerr_cnt[chipn] = 0;
- }
- }
- }
-
- }
復(fù)制代碼
第二部分.h文件
單片機(jī)源程序如下:
- #ifndef __user_AD7799_H
- #define __user_AD7799_H
- /************* 定義相關(guān)工作參數(shù)的結(jié)構(gòu)體 *******************************/
- typedef struct //運(yùn)行參數(shù)結(jié)構(gòu)體 - 適用于每個(gè)通道
- {
- u8 RefMode; //1=基準(zhǔn)與信號(hào)互換;0=未互換
- u8 SetGain; //下一次ADC的設(shè)定增益:0~7 (= 1~128)
- u8 CurrGain; //當(dāng)前AD值的增益:0~7 (= 1~128)
- s32 CurrValue; //當(dāng)前最新的AD值,含GAIN,用于自動(dòng)增益
- }ADC_RUN_Def;
- typedef struct //外部接口結(jié)構(gòu)體 - 適用于每個(gè)通道
- {
- u8 Status; //0=AD值無效;1=得到最新的ADC轉(zhuǎn)換結(jié)果,用戶獲取ADC值后,需清0該標(biāo)志
- float Value; //最新的AD值:1)經(jīng)過了濾波處理;2)已除以放大倍數(shù),即原始信號(hào)的AD值
- }ADC_VAL_Def;
- /************** AD7799的MODE寄存器的相關(guān)參數(shù)定義 ********************/
- //轉(zhuǎn)換模式控制位: bit15,14,13
- #define AD7799_MODE_CONTINUE 0x0000 //v連續(xù)轉(zhuǎn)換模式(默認(rèn))
- #define AD7799_MODE_SINGLE 0x2000 //單次轉(zhuǎn)換模式
- //PSW開關(guān)控制位: bit12
- #define AD7799_MODE_PSW_ON 0x1000 //打開PSW開關(guān)
- #define AD7799_MODE_PSW_OFF 0x0000 //關(guān)閉PSW開關(guān)
- //bit<12:4>未使用,必須置為0
- //轉(zhuǎn)換速率控制位:bit3,2,1,0
- #define AD7799_MODE_4_17HZ 0x000f //轉(zhuǎn)換速率=4.17hz; 抑制:74db(50,60hz)
- #define AD7799_MODE_6_25HZ 0x000e //轉(zhuǎn)換速率=6.25hz; 抑制:72db(50,60hz)
- #define AD7799_MODE_8_33HZ 0x000d //轉(zhuǎn)換速率=8.33hz; 抑制:70db(50,60hz)
- #define AD7799_MODE_10HZ 0x000c //轉(zhuǎn)換速率=10hz ; 抑制:69db(50,60hz)
- #define AD7799_MODE_12_5HZ 0x000b //轉(zhuǎn)換速率=12.5hz; 抑制:66db(50,60hz)
- #define AD7799_MODE_16_7HZ 0x000a //轉(zhuǎn)換速率=16.7hz; 抑制:65db(50,60hz)
- #define AD7799_MODE_16_50HZ 0x0009 //轉(zhuǎn)換速率=16.7hz; 抑制:80db(僅50hz)
- #define AD7799_MODE_19_6HZ 0x0008 //轉(zhuǎn)換速率=19.6hz; 抑制:90db(僅60hz)
- #define AD7799_MODE_50HZ 0x0005 //轉(zhuǎn)換速率=50hz; 抑制:-
- #define AD7799_MODE_470HZ 0x0001 //轉(zhuǎn)換速率=470hz; 抑制:-
- /************** AD7799的CONFIG寄存器的相關(guān)參數(shù)定義 ********************/
- //bit15,14,11,7,6,3未使用;
- //BIT13-為100nA電流源使能(=1),默認(rèn)為0(關(guān)閉),所以未定義
- //差分輸入信號(hào)的單/雙極性編碼控制: bit12
- #define AD7799_CONFIG_BIPOLAR 0x0000 //雙極性編碼(默認(rèn))
- #define AD7799_CONFIG_UNIPOLAR 0x1000 //v單極性編碼
- //增益選擇位: bit10,9,8
- #define AD7799_CONFIG_GAIN_1 0x0000 //增益=1(儀表放大器不用)
- #define AD7799_CONFIG_GAIN_2 0x0100 //增益=2(儀表放大器不用)
- #define AD7799_CONFIG_GAIN_4 0x0200 //增益=4
- #define AD7799_CONFIG_GAIN_8 0x0300 //增益=8
- #define AD7799_CONFIG_GAIN_16 0x0400 //增益=16
- #define AD7799_CONFIG_GAIN_32 0x0500 //增益=32
- #define AD7799_CONFIG_GAIN_64 0x0600 //增益=64
- #define AD7799_CONFIG_GAIN_128 0x0700 //增益=128
- #define AD7799_CONFIG_GAIN_AUTO 0X5A5A //自動(dòng)增益 - AD7799硬件無該功能,該功能由軟件自動(dòng)實(shí)現(xiàn)
- //基準(zhǔn)電壓檢測(cè)位: bit5
- #define AD7799_CONFIG_REFDET_EN 0x0020 //基準(zhǔn)電壓檢測(cè)功能有效:當(dāng)外部基準(zhǔn)電壓開路或小于0.5V時(shí),狀態(tài)寄存器的NOXREF位置位
- #define AD7799_CONFIG_REFDET_DIS 0x0000 //基準(zhǔn)電壓檢測(cè)功能禁用
- //BUF位: bit4
- #define AD7799_CONFIG_BUF_EN 0x0010 //v緩沖工作模式
- #define AD7799_CONFIG_BUF_DIS 0x0000 //無緩沖工作模式
- //通道選擇位: bit2,1,0
- #define AD7799_CONFIG_AIN1 0x0000 //AIN1差分輸入
- #define AD7799_CONFIG_AIN2 0x0001 //AIN2差分輸入
- #define AD7799_CONFIG_AIN3 0x0002 //AIN3差分輸入
- void AD7799_CS_Pin_Configuration(u8 chipn);
- void AD7799_SCLK_Pin_Configuration(u8 chipn);
- void AD7799_DIN_Pin_Configuration(u8 chipn);
- void AD7799_DOUT_Pin_Configuration(u8 chipn);
- void Wr1Byte7799(u8 chipn,u8 data);
- void Delay_7799(u16 timecount);
- u8 Rd1Byte7799(u8 chipn);
- u8 read_status_reg7799(u8 chipn);
- void write_reg7799(u8 chipn,u8 xcomm, u8 xlen, u8 *s);
- u32 read_data_reg7799(u8 chipn);
- void Config_AD7799(u8 chipn,u8 chn);
- void auto_gain(u8 chn);
- /************* 外部用戶接口 *******************************/
- /**************** AD7799使用數(shù)據(jù)及每片ADC的通道數(shù) **********/
- #define AD7799_PCS 2 //AD7799芯片數(shù)量(1~4)
- #define AD7799_CHANN_USE1 2 //第1片AD7799的通道數(shù)(1~3)
- #define AD7799_CHANN_USE2 2 //第2片AD7799的通道數(shù)(0~3,該芯片未使用時(shí)必須置為0)
- #define AD7799_CHANN_USE3 0 //第3片AD7799的通道數(shù)(0~3,該芯片未使用時(shí)必須置為0)
- #define AD7799_CHANN_USE4 0 //第4片AD7799的通道數(shù)(0~3,該芯片未使用時(shí)必須置為0)
- #define AD7799_CHANN_USE 4 //總的通道數(shù):各AD7799通道數(shù)之和
- //#define AD7799_CHANN_USE AD7799_CHANN_USE1+AD7799_CHANN_USE2+AD7799_CHANN_USE3+AD7799_CHANN_USE4
- //定義AD_Value[]變量的通道編號(hào),從0開始編號(hào)。注意:包括第二片的編號(hào)
- typedef enum
- {
- ADSF = 0, //
- ADSB, //
- ADBP, //
- ADOTH, //
- }AdcChName;
- /**************** ADC片選引腳CS 輸出GPIO --可修改 --必須為4個(gè) **********/
- #define ADC1_CS_PORT GPIOA //PA4
- #define ADC2_CS_PORT GPIOB //PB12
- #define ADC3_CS_PORT 0 //
- #define ADC4_CS_PORT 0 //
- #define ADC1_CS_PIN GPIO_Pin_4
- #define ADC2_CS_PIN GPIO_Pin_12
- #define ADC3_CS_PIN 0
- #define ADC4_CS_PIN 0
- /**************** ADC SPI時(shí)鐘引腳SCLK 輸出GPIO --可修改 --必須為4個(gè) **********/
- #define ADC1_SCLK_PORT GPIOA //PA5
- #define ADC2_SCLK_PORT GPIOB //PB13
- #define ADC3_SCLK_PORT 0 //
- #define ADC4_SCLK_PORT 0 //
- #define ADC1_SCLK_PIN GPIO_Pin_5
- #define ADC2_SCLK_PIN GPIO_Pin_13
- #define ADC3_SCLK_PIN 0
- #define ADC4_SCLK_PIN 0
- /**************** ADC數(shù)據(jù)輸入引腳DIN 輸出GPIO --可修改 --必須為4個(gè) **********/
- #define ADC1_DIN_PORT GPIOA //PA7
- #define ADC2_DIN_PORT GPIOB //PB15
- #define ADC3_DIN_PORT 0 //
- #define ADC4_DIN_PORT 0 //
- #define ADC1_DIN_PIN GPIO_Pin_7
- #define ADC2_DIN_PIN GPIO_Pin_15
- #define ADC3_DIN_PIN 0
- #define ADC4_DIN_PIN 0
- /**************** ADC數(shù)據(jù)輸出引腳DOUT 輸入GPIO --可修改 --必須為4個(gè) **********/
- #define ADC1_DOUT_PORT GPIOA //PA6
- #define ADC2_DOUT_PORT GPIOB //PB14
- #define ADC3_DOUT_PORT 0 //
- #define ADC4_DOUT_PORT 0 //
- #define ADC1_DOUT_PIN GPIO_Pin_6
- #define ADC2_DOUT_PIN GPIO_Pin_14
- #define ADC3_DOUT_PIN 0
- #define ADC4_DOUT_PIN 0
- /*********** 定義ADC采樣的濾波參數(shù) **********
- * 2種濾波算法結(jié)合:中位值濾波法和遞推平均濾波法(又稱滑動(dòng)平均濾波法)
- */
- #define MEDIAN_FILTERING_BUFSIZE 4 //中位值濾波的(連續(xù))數(shù)據(jù)采集次數(shù).
- #define MOVING_AVERAGE_BUFSIZE 3 //遞推平均濾波的隊(duì)列長(zhǎng)度.
- #define AD7799_RATE AD7799_MODE_10HZ //AD7799_MODE_10HZ //設(shè)定ADC的轉(zhuǎn)換速率
- #define AD7799_GAIN AD7799_CONFIG_GAIN_128 //設(shè)定ADC的增益
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
STM32 .AD7799程序.doc
(134 KB, 下載次數(shù): 125)
2018-2-11 09:30 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|