标题:
STM32 AD7799驱动程序
[打印本页]
作者:
fythl
时间:
2018-2-11 09:31
标题:
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[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芯片编号: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][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) //连续采集完一组中位值滤波所的数据, 取中值,且切换到下一个通道
{
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]][i]; }
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的增益
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
STM32 .AD7799程序.doc
(134 KB, 下载次数: 125)
2018-2-11 09:30 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
dillinllp
时间:
2018-3-31 09:54
好东西。。。。。。。。。。。。
作者:
zhaojun_xf
时间:
2019-7-18 14:20
好东西,下载学习一下。
作者:
JackZhao
时间:
2020-1-14 15:13
自动扫描频率多少,怎么更改
作者:
cdwess
时间:
2020-10-28 15:17
正好在用这个,顶一下
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1