单片机学习小组
直播中

王晶

7年用户 148经验值
私信 关注

STM32 AD7799驱动程序

STM32 对于AD7799的驱动程序,详见附件。
本文为STM32AD7799操作函数。全文共分为二部分,第一部分为.c文件包含AD7799的配置与操作原函数。第二部分为.h文件,方便其它文件对AD7799操作函数进行调用。代码亲测可用,只要在主函数中引用ADC_Auto_Conversion();便可得到AD转换结果。

第一部分:.c文件操作函数
  • ***********************************************************************************
  • * @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值,经数字滤波后的ADC值
  • ADC_RUN_Def  AD_Work_Info[AD7799_CHANN_USE];  //各通道(含所有芯片)的工作信息
  • u8   ADC_Chn[AD7799_PCS] = {0};               //各芯片 ADC转换通道号:0~2
  • #define  SPI_PULSE_WIDE            20                //SPI模拟通信中,时钟信号的延时
  • /*******************************************************************************
  • * Function Name  : auto_gain
  • * Description    : 根据采样的AD值,自动调整AD7799的增益
  • * Input          : chn - ADC的采样通道(AD7799_CHANN_USE以内)
  • * Output         : 全局变量AD_Work_Info[chn].SetGain,其值为0~7,对应增益为1~128
  • * Return         : None
  • * 算法说明       : 在增益未达最大和最小时,自动控制增益后的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%,则在增益系数值不为0时,增益系数-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%时,直接把增益增大N倍,使其达到50%以内。
  •   {
  •     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)   //限制最大增益系数为7,即128倍
  •     {
  •       AD_Work_Info[chn].SetGain = 7;
  •     }
  •   }
  • }
  • /*******************************************************************************
  • * Function Name  : ADC7799_Init
  • * Description    : AD7799初始化: GPIO,配置启动,变量清0
  • * Input          : None
  • * Output         : None
  • * Return         : None
  • *******************************************************************************/
  • void ADC7799_Init(void)
  • {
  •   u8 i;
  •   for(i = 0; i < AD7799_CHANN_USE; i++)
  •   {
  •     AD_Value.Status = 0;
  •     AD_Value.Value = 0;
  •     AD_Work_Info.RefMode = 0;
  •     AD_Work_Info.SetGain = 0;
  •     AD_Work_Info.CurrGain = 0;
  •     AD_Work_Info.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 = 0;
  •     Config_AD7799(i,ADC_Chn);   
  •   }
  • }
  • /*******************************************************************************
  • * Function Name  : AD7799_SCLK_Pin_Configuration
  • * Description    : 配置MCU与各AD7799的CS连接的引脚 (OUT)
  • * Input          : chipn - AD7799芯片编号: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))   //端口和芯片有效,才对端口进行配置
  •   {  
  •     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芯片编号: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))   //端口和芯片有效,才对端口进行配置
  •   {  
  •     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芯片编号: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))   //端口和芯片有效,才对端口进行配置
  •   {  
  •     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芯片编号: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))   //端口和芯片有效,才对端口进行配置
  •   {  
  •     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    : 延时函数
  • * Input          : timecount - 延时参数(0~65535)
  • * Output         : None
  • * Return         : None
  • *******************************************************************************/
  • void Delay_7799(u16 timecount)
  • {
  •   while(timecount>0)
  •     timecount--;
  • }
  • /*******************************************************************************
  • * Function Name  : Wr1Byte7799
  • * Description    : 向AD7799写入1字节(MSB在前,即左移)上沿锁存
  • * Input          : chipn - AD7799芯片编号:0~(AD7799_PCS-1),最大3
  • *                  data - 写入的8bit数据
  • * 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字节, AD7799在下沿输出数据,上升沿时数据有效,MSB在前
  • * Input          : chipn - AD7799芯片编号:0~(AD7799_PCS-1),最大3
  • * Output         : None
  • * Return         : 8位数据
  • *******************************************************************************/
  • 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    : 设置AD7799的CS为高电平(1)或低电平(0)
  • * Input          : chipn - AD7799芯片编号: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的状态寄存器
  • * Input          : chipn - AD7799芯片编号:0~(AD7799_PCS-1),最大3
  • * Output         : None
  • * Return         : 8位状态值
  • *******************************************************************************/
  • 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的任意寄存器写入指定长度的数据
  • * Input          : chipn - AD7799芯片编号:0~(AD7799_PCS-1),最大3
  • *                  xcomm - 命令
  • *                   xlen - 要写入的字节长度
  • *                     *s  -  要写入的数据
  • * 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位数据寄存器
  • * Input          : chipn - AD7799芯片编号: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,准备下一字节的填入
  •   xa = xa + Rd1Byte7799(chipn);
  •   xa = (xa << 8) & 0xffffff00;   //最低8bit清为0,准备下一字节的填入
  •   xa = xa + Rd1Byte7799(chipn);
  •   Set_CS_7799(chipn,1);      //AD7799_CS_H;   
  •   return(xa);
  • }
  • /*******************************************************************************
  • * Function Name  : Reset_AD7799
  • * Description    : AD7799复位: 发送32个1,即可对AD7799复位
  • * Input          : chipn - AD7799芯片编号: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++)      //发送32个
  •   {
  •     Wr1Byte7799(chipn,0xff);
  •   }
  •   Set_CS_7799(chipn,1);    //AD7799_CS_H;  
  • }
  • /*******************************************************************************
  • * Function Name  : Config_AD7799
  • * Description    : 配置AD7799
  • * Input          : chipn - AD7799芯片编号:0~(AD7799_PCS-1),最大3
  • *                  chn   - 各芯片各自的通道编号(0~2)
  • * Output         : None
  • * Return         : None
  • *******************************************************************************/
  • void Config_AD7799(u8 chipn,u8 chn)   //xchann-通道号
  • {
  •   u8 xwork[2];
  •   u16 mode,config;
  •   u8 i,chnbase;
  •   u8  Ad7799ChnS[4] = {AD7799_CHANN_USE1,AD7799_CHANN_USE2,AD7799_CHANN_USE3,AD7799_CHANN_USE4};  //各芯片对应的通道数
  •   chnbase = 0;   
  •   for(i = 0; i < chipn; i++)
  •   {  
  •     if(chipn > 0)
  •     { chnbase += Ad7799ChnS[chipn-1];}
  •   }
  •   mode = 0; config = 0;
  •   //MODE寄存器配置值
  •   // 连续转换模式      //转换速率-用户在AD7799.H文件中定义
  •   mode = mode | AD7799_MODE_CONTINUE | AD7799_RATE;
  •   chn = chn & 0x07;
  •   //config寄存器配置值
  •   //双/单极性编码            //缓冲工作模式     //通道号
  • #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)  //自动增益
  •   {
  •     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引脚输出数字信号。此处为0,禁用数字输出功能
  •   write_reg7799(chipn,0x28,1,xwork);        //写IO寄存器(电流源控制寄存器)
  • }
  • /*******************************************************************************
  • * Function Name  : ADC_Auto_Conversion
  • * Description    : 轮询各片AD7799,把最新的AD值经滤波处理后装入相应的AD_Value[]通道中
  • * Input          : None
  • * Output         : AD_Value[](全局) - 经滤波处理后的AD值
  • * Return         : None
  • *******************************************************************************/
  • void ADC_Auto_Conversion(void)
  • {  //滑动平均滤波 - 与总的通道数匹配
  •   static u8  MovingAv_Fill[AD7799_CHANN_USE] = {0};   //1=滑动平均滤波时,采集的数据已达到满队列的(最多3个队列)的标志
  •   static float MovingAv_Buf[AD7799_CHANN_USE][MOVING_AVERAGE_BUFSIZE];   //滑动平均滤波 - 各通道的数据缓存
  •   static u8  MovingAv_Cnt[AD7799_CHANN_USE] = {0};   
  •   //中位值滤波 - 与芯片数匹配
  •   static u8  MedianFilt_Cnt[AD7799_PCS] = {0};    //中位值滤波 - 数据计数器
  •   static s32 MedianFilt_Buf[AD7799_PCS][MEDIAN_FILTERING_BUFSIZE];   //中位值滤波 - 数据缓存
  •   static u16  ADC_Read_Cnt = 0;                   //轮询AD7799转换结果的时间间隔计数器
  •   static u32 adcerr_cnt[AD7799_PCS] = {0};        //AD7799异常计数器
  •   u8  Ad7799ChnS[4] = {AD7799_CHANN_USE1,AD7799_CHANN_USE2,AD7799_CHANN_USE3,AD7799_CHANN_USE4};  //各芯片对应的通道数
  •   s32 xd,tmp;
  •   float xf;
  •   u8  i,chipn;
  •   u8  chnbase = 0;   //将各芯片的各个通道转为全局通道时,其基址编号
  •   ADC_Read_Cnt++;
  •   if(ADC_Read_Cnt < ADC7799_RD_CYCLE) return;  //延时
  •   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异常超时计数器,为ADC_Read_Cnt的1000倍
  •     //在ADC转换完成后,读取ADC的值.(同时检测IO口的状态
  •     if((xd & 0x80) == 0)  //最高位(bit7)为0,表示ADC转换完成,则读取转换结果并且进行滤波处理
  •     {   
  •       adcerr_cnt[chipn] = 0;
  •       ADC_Read_Cnt = 0;
  •       xd = xd & 0x03;  //AD7799当前的转换通道
  •       if(xd >= AD7799_CHANN_USE) //通道不正确
  •       {
  •         ADC_Chn[chipn] = 0;
  •         Config_AD7799(chipn,ADC_Chn[chipn]);   
  •         return;
  •       }
  •       xd = read_data_reg7799(chipn);   //读取转换结果
  • #ifdef  AD7799_BIPOLAR
  •       //双极性: 负差分输入的AD值:0~0x7fffff;0v电压的AD值:0x800000;正差分输入的AD值:0x800001~0xffffff;
  •       xd = xd - 0x800000;
  • #endif
  •       //中位值滤波 - 排序:把最新采集的AD值按从小到大插入到排序缓存中
  •       if(MedianFilt_Cnt[chipn] > 0)  //中位值滤波缓存中有数据,则排序
  •       {
  •         for(i = 0; i < MedianFilt_Cnt[chipn]; i++) //排序
  •         {
  •           if(MedianFilt_Buf[chipn] > xd)
  •           {tmp = MedianFilt_Buf[chipn];
  •           MedianFilt_Buf[chipn] = xd;
  •           xd = tmp;
  •           }
  •         }
  •       }
  •       MedianFilt_Buf[chipn][MedianFilt_Cnt[chipn]] = xd;
  •       MedianFilt_Cnt[chipn]++;
  •       if(MedianFilt_Cnt[chipn] >= MEDIAN_FILTERING_BUFSIZE) //连续采集完一组中位值滤波所的数据, 取中值,且切换到下一个通道
  •       {
  •         xd = MedianFilt_Buf[chipn][MEDIAN_FILTERING_BUFSIZE/2];  //取中位值,如果总个数为偶数,则取中间偏后面的数
  •         MedianFilt_Cnt[chipn] = 0;
  •         AD_Work_Info[chnbase+ADC_Chn[chipn]].CurrValue = xd;  //AD当前条件(GAIN等)下的采集值,是计算自动增益的依据
  •         //自动增益与固定增益处理:
  •         xf = (float)xd / (float)(1 << AD_Work_Info[chnbase+ADC_Chn[chipn]].SetGain);   //还原为无增益时的AD值-小数
  •         //滑动平均滤波
  •         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;    //新数据循环放入缓存,且覆盖最旧的数据
  •           MovingAv_Fill[chnbase+ADC_Chn[chipn]] = 1;   //缓存已填满标志
  •         }
  •         //判断用来计算平均值的缓存数据个数:
  •         if(MovingAv_Fill[chnbase+ADC_Chn[chipn]]) //数据已填满"滑动平均滤波"器的缓存,即按最大数据计算平均值
  •         {tmp = MOVING_AVERAGE_BUFSIZE;}
  •         else //数据还未填满"滑动平均滤波"器的缓存,则按实际个数(小于缓存的最大个数)计算平均值
  •         {tmp = MovingAv_Cnt[chnbase+ADC_Chn[chipn]];}
  •         //求平均值
  •         for(xf = 0.0, i = 0; i < tmp; i++)
  •         { xf += MovingAv_Buf[chnbase+ADC_Chn[chipn]]; }
  •         xf = xf / (float)tmp;
  •         AD_Value[chnbase+ADC_Chn[chipn]].Value = xf;   
  •         AD_Value[chnbase+ADC_Chn[chipn]].Status = 1;      //数据有效
  •         //切换到下一通道
  •         ADC_Chn[chipn]++;
  •         if(ADC_Chn[chipn] >= Ad7799ChnS[chipn])
  •         {ADC_Chn[chipn] = 0;}
  •         if(Ad7799ChnS[chipn] > 1)  Config_AD7799(chipn,ADC_Chn[chipn]); //当只有一个通道时,不对AD7799重新初始化
  •       }
  •     }
  •     else
  •     {
  •       if(adcerr_cnt[chipn] > 10000) //约3~10S, ADC超时,未产生新的转换结果,则重新初始化
  •       {   
  •         Reset_AD7799(chipn);
  •         Config_AD7799(chipn,ADC_Chn[chipn]);   
  •         adcerr_cnt[chipn] = 0;
  •       }
  •     }
  •   }
  • }





第二部分.h文件
单片机源程序如下:
  • #ifndef __user_AD7799_H
  • #define __user_AD7799_H
  • /************* 定义相关工作参数的结构体    *******************************/
  • typedef struct    //运行参数结构体 - 适用于每个通道
  • {
  •     u8    RefMode;   //1=基准与信号互换;0=未互换
  •     u8    SetGain;    //下一次ADC的设定增益:0~7 (= 1~128)
  •     u8    CurrGain;   //当前AD值的增益:0~7 (= 1~128)
  •     s32   CurrValue;  //当前最新的AD值,含GAIN,用于自动增益
  • }ADC_RUN_Def;
  • typedef struct    //外部接口结构体 - 适用于每个通道
  • {
  •     u8    Status;     //0=AD值无效;1=得到最新的ADC转换结果,用户获取ADC值后,需清0该标志
  •     float Value;      //最新的AD值:1)经过了滤波处理;2)已除以放大倍数,即原始信号的AD值
  • }ADC_VAL_Def;
  • /**************  AD7799的MODE寄存器的相关参数定义 ********************/
  • //转换模式控制位: bit15,14,13
  • #define AD7799_MODE_CONTINUE  0x0000    //v连续转换模式(默认)
  • #define AD7799_MODE_SINGLE    0x2000    //单次转换模式
  • //PSW开关控制位: bit12
  • #define AD7799_MODE_PSW_ON    0x1000    //打开PSW开关
  • #define AD7799_MODE_PSW_OFF   0x0000    //关闭PSW开关
  • //bit<12:4>未使用,必须置为0
  • //转换速率控制位:bit3,2,1,0
  • #define AD7799_MODE_4_17HZ    0x000f    //转换速率=4.17hz;  抑制:74db(50,60hz)
  • #define AD7799_MODE_6_25HZ    0x000e    //转换速率=6.25hz;  抑制:72db(50,60hz)
  • #define AD7799_MODE_8_33HZ    0x000d    //转换速率=8.33hz;  抑制:70db(50,60hz)
  • #define AD7799_MODE_10HZ      0x000c    //转换速率=10hz  ;  抑制:69db(50,60hz)
  • #define AD7799_MODE_12_5HZ    0x000b    //转换速率=12.5hz;  抑制:66db(50,60hz)
  • #define AD7799_MODE_16_7HZ    0x000a    //转换速率=16.7hz;  抑制:65db(50,60hz)
  • #define AD7799_MODE_16_50HZ   0x0009    //转换速率=16.7hz;  抑制:80db(仅50hz)
  • #define AD7799_MODE_19_6HZ    0x0008    //转换速率=19.6hz;  抑制:90db(仅60hz)
  • #define AD7799_MODE_50HZ      0x0005    //转换速率=50hz;    抑制:-
  • #define AD7799_MODE_470HZ     0x0001    //转换速率=470hz;   抑制:-
  • /**************  AD7799的CONFIG寄存器的相关参数定义 ********************/
  • //bit15,14,11,7,6,3未使用;
  • //BIT13-为100nA电流源使能(=1),默认为0(关闭),所以未定义
  • //差分输入信号的单/双极性编码控制: bit12
  • #define AD7799_CONFIG_BIPOLAR     0x0000    //双极性编码(默认)
  • #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    //自动增益 - AD7799硬件无该功能,该功能由软件自动实现
  • //基准电压检测位: bit5
  • #define AD7799_CONFIG_REFDET_EN   0x0020    //基准电压检测功能有效:当外部基准电压开路或小于0.5V时,状态寄存器的NOXREF位置位
  • #define AD7799_CONFIG_REFDET_DIS  0x0000    //基准电压检测功能禁用
  • //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使用数据及每片ADC的通道数  **********/
  • #define AD7799_PCS                 2                       //AD7799芯片数量(1~4)
  • #define AD7799_CHANN_USE1          2                       //第1片AD7799的通道数(1~3)
  • #define AD7799_CHANN_USE2          2                       //第2片AD7799的通道数(0~3,该芯片未使用时必须置为0)
  • #define AD7799_CHANN_USE3          0                       //第3片AD7799的通道数(0~3,该芯片未使用时必须置为0)
  • #define AD7799_CHANN_USE4          0                       //第4片AD7799的通道数(0~3,该芯片未使用时必须置为0)
  • #define AD7799_CHANN_USE           4        //总的通道数:各AD7799通道数之和
  • //#define AD7799_CHANN_USE  AD7799_CHANN_USE1+AD7799_CHANN_USE2+AD7799_CHANN_USE3+AD7799_CHANN_USE4
  • //定义AD_Value[]变量的通道编号,从0开始编号。注意:包括第二片的编号
  • typedef enum
  • {
  •   ADSF = 0,   //
  •   ADSB,       //
  •   ADBP,       //
  •   ADOTH,      //
  • }AdcChName;
  • /**************** ADC片选引脚CS 输出GPIO  --可修改 --必须为4个 **********/
  • #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时钟引脚SCLK 输出GPIO  --可修改 --必须为4个 **********/
  • #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数据输入引脚DIN 输出GPIO  --可修改 --必须为4个 **********/
  • #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数据输出引脚DOUT 输入GPIO  --可修改 --必须为4个 **********/
  • #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采样的滤波参数      **********
  • * 2种滤波算法结合:中位值滤波法和递推平均滤波法(又称滑动平均滤波法)
  • */
  • #define  MEDIAN_FILTERING_BUFSIZE 4     //中位值滤波的(连续)数据采集次数.
  • #define  MOVING_AVERAGE_BUFSIZE   3     //递推平均滤波的队列长度.
  • #define AD7799_RATE               AD7799_MODE_10HZ //AD7799_MODE_10HZ        //设定ADC的转换速率
  • #define AD7799_GAIN               AD7799_CONFIG_GAIN_128  //设定ADC的增益
  • ……………………
  • …………限于本文篇幅 余下代码请从电子发烧友下载附件…………



所有资料51hei提供下载:
    STM32 .AD7799程序.doc  



更多回帖

发帖
×
20
完善资料,
赚取积分