⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc.c

📁 LCD显示电子计价秤方案 1. 该方案使用的传感器为20KG,灵敏度约为0.5mv/v,选用新传感器线性较好的一段(100g-15Kg),直接处理,没有做非线性修正,称重可能会有偏差. 2. 软件
💻 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 + -