📄 adc.c
字号:
/*
数字滤波采用限幅+递推均值滤波法
*/
#include<def.h>
#define f 10 //滤波器的频率,HZ
#define fadc 2457600 //ADC时钟
#define fcode fadc/f/128 //tm7707滤波器的值
ulong databuf[6]={0,0,0,0,0,0};
ulong dataave[6]={0};
//---------------------------------------------adc_8bit串行数据输入程序-----------------------------------------------------------------------
//上升沿传输数据
void adc_in8bit(uchar adc_data)
{
uchar m;
DIN=1;
SCLK=1;
for(m=0;m<8;m++)
{
SCLK=0;
if((adc_data&0x80)!=0)
{
DIN=1;
}
else
{
DIN=0;
}
SCLK=1;
adc_data=adc_data<<1;
}
}
//下降沿传输数据
void adc_in8bit_neg(uchar adc_data)
{
uchar m;
DIN=1;
for(m=0;m<8;m++)
{
SCLK=1;
if((adc_data&0x80)!=0)
{
DIN=1;
}
else
{
DIN=0;
}
SCLK=0;
adc_data=adc_data<<1;
}
}
//---------------------------------------------adc_8bit串行数据输出程序-----------------------------------------------------------------------
//上升沿传输数据
uchar adc_out()
{
uchar m,k;
DOUT=1; //端口设置输入口
SCLK=1;
for(m=0;m<8;m++)
{
SCLK=0;
k=k<<1;
if(DOUT==0)
{
k=k&0xfe;
}
else
{
k=(k|0x01&0xff);
}
SCLK=1;
}
return(k);
}
//下降沿传输数据
uchar adc_out_neg()
{
uchar m,k;
DOUT=1; //端口设置输入口
for(m=0;m<8;m++)
{
SCLK=1;
k=k<<1;
if(DOUT==0)
{
k=k&0xfe;
}
else
{
k=(k|0x01&0xff);
}
SCLK=0;
}
return(k);
}
//---------------------------------------------ADC转换控制程序---------------------------------------------------------------------------------
uint adc7705_con()
{
uchar datal;
uint adcdata=0;
do
{
adc_in8bit(0x08); //写通讯寄存器,选择下一步读通讯寄存器
datal=adc_out(); //读通讯寄存器,等待最高位为0
}
while((datal&0x80)==0x80);
adc_in8bit(0x38); //写通讯寄存器,选择下一步读数据寄存器
//读数据寄存器
adcdata=adc_out();
adcdata<<=8;
adcdata|=adc_out();
return (adcdata);
}
uint adc7715_con()
{
uchar datal;
uint adcdata=0;
do
{
adc_in8bit(0x0b); //写通讯寄存器,选择下一步读通讯寄存器
datal=adc_out(); //读通讯寄存器
}
while((datal&0x80)==0x80);
adc_in8bit(0x3b); //写通讯寄存器,选择下一步读数据寄存器
//读数据寄存器
adcdata=adc_out();
adcdata<<=8;
adcdata|=adc_out();
return (adcdata);
}
ulong adc7707_con()
{
uchar datal;
ulong adcdata=0;
do
{
adc_in8bit_neg(0x0c); //写通讯寄存器,选择下一步读通讯寄存器
datal=adc_out_neg(); //读通讯寄存器
}
while((datal&0x80)==0x80); //等待最高位为0
adc_in8bit_neg(0x5c); //写通讯寄存器,选择下一步读数据寄存器
//读数据寄存器
adcdata=adc_out_neg();
adcdata<<=8;
adcdata|=adc_out_neg();
adcdata<<=8;
adcdata|=adc_out_neg();
return (adcdata);
}
//-----------------------------------------------adc初始化程序------------------------------------------------------------
void adcinit()
{
uchar p;
//发送连续40个时钟
DIN=1;
for(p=0;p<40;p++)
{
SCLK=0;
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
}
if(adcbit1==0)
{
if(adcbit0==0)
{
//tm7705初始化
adc_in8bit(0x20); //写通讯寄存器,选择下一步写时钟寄存器,CH1通道
adc_in8bit(0x84); //写时钟寄存器,使用2.4576M晶体,输出更新速率20HZ
adc_in8bit(0x10); //写通讯寄存器,选择下一步写设置寄存器
adc_in8bit(0x7c); //写设置寄存器,G=128,单极性,无缓冲
}
else
{
//tm7715初始化
adc_in8bit(0x13); //写通讯寄存器,选择下一步写设置寄存器,G=128
adc_in8bit(0x60); //写设置寄存器
}
}
else
{
//tm7707初始化
adc_in8bit_neg(0x24); //写通讯寄存器,选择下一步写滤波器高8位
adc_in8bit_neg(0xe0|(fcode/256)); //写滤波器高8位
adc_in8bit_neg(0x34); //写通讯寄存器,选择下一步写滤波器低8位
adc_in8bit_neg(fcode%256); //写设置寄存器
adc_in8bit_neg(0x14); //写通讯寄存器,选择下一步写设置寄存器
adc_in8bit_neg(0x3c); //写设置寄存器,设置增益为16,自校准,并启动AD转换
}
}
//--------------------------------------------------ADC数据处理--------------------------------------------------------------
ulong adccon()
{
uchar i,j;
ulong idata temp,adcresult;
ulong idata adcdata_new,adcdata_now,adcdata_old;
//采集数据
if(adcbit1==0)
{
if(adcbit0==0)
{
adcdata_new=adc7705_con();
}
else
{
adcdata_new=adc7715_con();
}
}
else
{
adcdata_new=adc7707_con();
}
//数据处理
if(adcdata_new>=adcresult)
{
temp=adcdata_new-adcresult;
}
else
{
temp=adcresult-adcdata_new;
} //得到新的数据与滤波器值的差值
if(temp>data_th)
{
//比较上一次ADC的数据与本次滤波器的差值是否大于阀值
if(adcdata_old>=adcresult)
{
temp=adcdata_old-adcresult;
}
else
{
temp=adcresult-adcdata_old;
} //得到上次ADC的数据与滤波器值的差值
if(temp>data_th)
{
//称重发生变化
dataave[0]=dataave[1]=dataave[2]=dataave[3]=dataave[4]=dataave[5]=adcdata_new; //用新的ADC的数据代替滤波器中的所有数据
adcdata_old=adcdata_new; //更新上次ADC采集到的数据
adcresult=(dataave[1]+dataave[2]+dataave[3]+dataave[4])/4;
return (adcresult); //返回平均值
}
else
{
adcdata_now=adcresult; //认为是干扰
}
}
else
{
adcdata_now=adcdata_new;
}
adcdata_old=adcdata_new; //更新上次ADC采集到的数据
//采用递推平均滤波
databuf[5]=databuf[4];
databuf[4]=databuf[3];
databuf[3]=databuf[2];
databuf[2]=databuf[1];
databuf[1]=databuf[0];
databuf[0]=adcdata_now;
dataave[5]=dataave[4];
dataave[4]=dataave[3];
dataave[3]=dataave[2];
dataave[2]=dataave[1];
dataave[1]=dataave[0];
dataave[0]=(databuf[0]+databuf[1]+databuf[2]+databuf[3]+databuf[4]+databuf[5])/6;
//将得到的数据按照从小到大的顺序排列
for(j=0;j<5;j++)
{
for(i=0;i<5-j;i++)
{
if(dataave[i]>dataave[i+1])
{
temp=dataave[i];
dataave[i]=dataave[i+1];
dataave[i+1]=temp;
}
}
}
adcresult=(dataave[1]+dataave[2]+dataave[3]+dataave[4])/4;
return (adcresult); //返回平均值
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -