关于10位ADC采集PT100温度值的问题,温度值波动很厉害,求高手指点!
温度值在29到31之间在波动。不过需要注意的是,哪个蓝色的模块是可测正负200度的变送器,输出0-5V; ...
//#include <REG51.H>
#include<reg15.h>
#define uchar unsigned char
#define uint unsigned int
#define ADC_POWER 0X80 //ADC电源控制位
#define ADC_FLAG 0X10 //ADC完成标志位
#define ADC_START 0X08 //ADC起始控制位
#define ADC_SPEEDLL 0X00 //ADC电源
#define FOSC 12000000L //系统时钟频率
#define T1MS (65536-FOSC/1000)//1T模式
#define T2MS (65536-FOSC/100)//1T模式
#define N 11//滤波常数
#define A 1//滤波常数
//#define 1TMS (65536-FOSC/12/1000)//12T模式
uchar ch=0,cycle,y,average,count;
uint dat1,dat2,tt,ge,shi,bai,qian,t1,time=20;
uint x,z;
uint value_buf[15],new_value,value;
char o=0;
unsigned char code Tab[] = {0xc0,0xcf,0xa4,0xb0,0x99,0x92,0x82, 0xf8,0x80,
0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0x7f,0xbf};//0 1 2 3 4 5 6 7 8 9 A B C D F 灭 . -// 共阳数码管
sbit led=P5^5;
sbit LOAD=P0^0;
sbit CLK=P0^1;
sbit SDK=P0^2;
sbit BUTTON1=P0^3;
sbit add=P0^4;
sbit sub=P0^5;
sbit clear=P0^6;
sbit change=P0^7;
sbit fmq=P2^0;
bit flag,flag2,flag3=1;
void scal(void);
void ChangeCH(void);
void display(void);
void ADCFUCTION(void);
void TimeRef(void);
void dismode(void);
void contrl(void);
void timeREF(void);
uint filter();
void delay(int z)
{
int i,j;
for(i=z;i>0;i--)
for(j=120;j>0;j--);
}
/////////////////////////////////////////////////////////////////////////
void init_adc()
{
P1ASF=0XFF;//打开P1口的ADC功能
ADC_RES=0; //清空AD数据寄存器
ADC_CONTR=0x80;//初始化ADC_CONTR寄存器
delay(2);//等待ADC内部电源稳定后,再启动ADC转换
ADC_CONTR=0x88;//启动ADC转换
}
/////////////////////////////////////////////////////////////////////
void init_timer0()
{
AUXR |=0Xc0;//定时器0,1为1T模式
//AUXR &=0X7F;//定时器0为12T模式
TMOD=0X00;//T0T1工作在16位自动重装模式
EA=1;
ET0=1;
ET1=1;
TR1=1;
TH0=T1MS>>8;
TL0=T1MS;
TH1=T2MS>>8;
TL1=T2MS;
}
//////////////////////////////////////////////////////////////////////
void delay10ms(uint temp)
{
unsigned char i,j,t;
t=temp;
while(t!=0)
{
for(i=20;i>0;i--)
for(j=248;j>0;j--);
t--;
}
}
//////////////////////////////////////////////////////////////////////
void SPI_595(unsigned char out_data)
{
unsigned char i,temp;
for(i=0;i<8;i++)
{
CLK=0;
temp=out_data&0x80;
if(temp==0x80)
SDK=1;
else SDK=0;
out_data=out_data<<1;
CLK=1;
}
}
//主函数///////////////////////////////////////////////////////////
void main(void)
{
P0M1=0x00 ; //弱上拉双向口
P0M0=0x00 ; //弱上拉双向口
P2M1=0x00 ; //弱上拉双向口
P2M0=0x00 ; //弱上拉双向口
init_timer0();
init_adc();
while(1)
{
contrl();
scal();
ChangeCH();
dismode();
}
}
//////////////////////////////////////////
void contrl(void)
{
if(!flag)ADCFUCTION();
if(flag)timeREF();
if(t1==time)
{
TR0=0;
fmq=~fmq;
delay10ms(100);
}
else
fmq=1;
if(!clear)t1=0;
}
/*AD转换程序*///////////////////////////////////////////////////////
void ADCFUCTION()
{
if(flag2)
{ flag2=0;
if(ADC_CONTR&0X10)//用来检测AD转换是否完成,ADC控制寄存器第五位为ADC_FLAG,为1时代表转换完成。
{
ADC_CONTR &=!ADC_FLAG;//清零转换完成标志位。
dat1=ADC_RES;//取出高8位转换值
dat2=ADC_RESL;//取出低2位转换值
x=(dat1<<2)|dat2;//将高8位与低2位的数值整合
ADC_CONTR=0x88|ch;//切换AD通道,同时启动AD转换,共8个AD通道,及P1口。转换速度90个时钟周期
value_buf[o++] = x;
}
}
}
////////////////////////////////////////////////////////
void scal()
{
if(o==N)
{
z=(3.906*filter()-2000);
ge=z%10;
shi=z%100/10;
bai=z%1000/100;
qian=z/1000;
display();
o=0;
}
}
//////////////////////////////////////////////////
void display()
{
flag3=1;
y=0;
if(!add)TR0=1;
if(!sub)TR0=0;
LOAD=1;
LOAD=0;
delay10ms(100);
//if(flag2)
//{
SPI_595(Tab[ge]);
SPI_595(Tab[shi]);
SPI_595(Tab[bai]);
SPI_595(Tab[qian]);
//SPI_595(Tab[ch]);//显示4位数码管
//delay10ms(5);
//flag2=0;
//}
//z=0;
}
//////////////////////////////////////////
/////////////////////////////////////
void timeREF()
{
if(y<3)
{
LOAD=1;
LOAD=0;
delay10ms(100);
SPI_595(Tab[time%10]);//显示4位数码管
SPI_595(Tab[time/10]);
SPI_595(Tab[18]);
SPI_595(Tab[18]);
delay10ms(10);
y++;
TR0=0;
}
while(!add)
{
delay10ms(10);
if(!add)
time++;
LOAD=1;
LOAD=0;
delay10ms(50);
SPI_595(Tab[time%10]);//显示4位数码管
SPI_595(Tab[time/10]);
SPI_595(Tab[18]);
SPI_595(Tab[18]);
}
while(!sub)
{
delay10ms(10);
if(!sub)
time--;
LOAD=1;
LOAD=0;
delay10ms(50);
SPI_595(Tab[time%10]);//显示4位数码管
SPI_595(Tab[time/10]);
SPI_595(Tab[18]);
SPI_595(Tab[18]);
}
}
/////////////////////////////////////
void ChangeCH()
{
if(!change)
{
delay10ms(100);
if(!change)
ch++;
}
if(ch==8)ch=0;
}
////////////////////////////////////////////////
void timer0() interrupt 1 using 1
{
tt++;
if(tt==1000)
{
led=~led;
t1++;
tt=0;
}
}
//////温度扫描更新周期500ms////////////////////////////////////////////////
void timer1() interrupt 3
{
cycle++;
if(cycle==20)
{
flag2=1;
cycle=0;
led=~led;
}
}
////////////////////////////////////////////////////
void dismode()
{
if(!BUTTON1)
{
delay(400);
if(!BUTTON1)
flag=~flag;
while(!BUTTON1);
}
}
//////////////////////////////////////////////////
uint filter()
{
char count,i,j;
int sum=0,temp;
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j;i++)
{
if ( value_buf[i]>value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
for(count=1;count<N-1;count++)
sum +=value_buf[count];
return (uint)(sum/(N-2));
}
//#include <REG51.H>
#include<reg15.h>
#define uchar unsigned char
#define uint unsigned int
#define ADC_POWER 0X80 //ADC电源控制位
#define ADC_FLAG 0X10 //ADC完成标志位
#define ADC_START 0X08 //ADC起始控制位
#define ADC_SPEEDLL 0X00 //ADC电源
#define FOSC 12000000L //系统时钟频率
#define T1MS (65536-FOSC/1000)//1T模式
#define T2MS (65536-FOSC/100)//1T模式
#define N 11//滤波常数
#define A 1//滤波常数
//#define 1TMS (65536-FOSC/12/1000)//12T模式
uchar ch=0,cycle,y,average,count;
uint dat1,dat2,tt,ge,shi,bai,qian,t1,time=20;
uint x,z;
uint value_buf[15],new_value,value;
char o=0;
unsigned char code Tab[] = {0xc0,0xcf,0xa4,0xb0,0x99,0x92,0x82, 0xf8,0x80,
0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0x7f,0xbf};//0 1 2 3 4 5 6 7 8 9 A B C D F 灭 . -// 共阳数码管
sbit led=P5^5;
sbit LOAD=P0^0;
sbit CLK=P0^1;
sbit SDK=P0^2;
sbit BUTTON1=P0^3;
sbit add=P0^4;
sbit sub=P0^5;
sbit clear=P0^6;
sbit change=P0^7;
sbit fmq=P2^0;
bit flag,flag2,flag3=1;
void scal(void);
void ChangeCH(void);
void display(void);
void ADCFUCTION(void);
void TimeRef(void);
void dismode(void);
void contrl(void);
void timeREF(void);
uint filter();
void delay(int z)
{
int i,j;
for(i=z;i>0;i--)
for(j=120;j>0;j--);
}
/////////////////////////////////////////////////////////////////////////
void init_adc()
{
P1ASF=0XFF;//打开P1口的ADC功能
ADC_RES=0; //清空AD数据寄存器
ADC_CONTR=0x80;//初始化ADC_CONTR寄存器
delay(2);//等待ADC内部电源稳定后,再启动ADC转换
ADC_CONTR=0x88;//启动ADC转换
}
/////////////////////////////////////////////////////////////////////
void init_timer0()
{
AUXR |=0Xc0;//定时器0,1为1T模式
//AUXR &=0X7F;//定时器0为12T模式
TMOD=0X00;//T0T1工作在16位自动重装模式
EA=1;
ET0=1;
ET1=1;
TR1=1;
TH0=T1MS>>8;
TL0=T1MS;
TH1=T2MS>>8;
TL1=T2MS;
}
//////////////////////////////////////////////////////////////////////
void delay10ms(uint temp)
{
unsigned char i,j,t;
t=temp;
while(t!=0)
{
for(i=20;i>0;i--)
for(j=248;j>0;j--);
t--;
}
}
//////////////////////////////////////////////////////////////////////
void SPI_595(unsigned char out_data)
{
unsigned char i,temp;
for(i=0;i<8;i++)
{
CLK=0;
temp=out_data&0x80;
if(temp==0x80)
SDK=1;
else SDK=0;
out_data=out_data<<1;
CLK=1;
}
}
//主函数///////////////////////////////////////////////////////////
void main(void)
{
P0M1=0x00 ; //弱上拉双向口
P0M0=0x00 ; //弱上拉双向口
P2M1=0x00 ; //弱上拉双向口
P2M0=0x00 ; //弱上拉双向口
init_timer0();
init_adc();
while(1)
{
contrl();
scal();
ChangeCH();
dismode();
}
}
//////////////////////////////////////////
void contrl(void)
{
if(!flag)ADCFUCTION();
if(flag)timeREF();
if(t1==time)
{
TR0=0;
fmq=~fmq;
delay10ms(100);
}
else
fmq=1;
if(!clear)t1=0;
}
/*AD转换程序*///////////////////////////////////////////////////////
void ADCFUCTION()
{
if(flag2)
{ flag2=0;
if(ADC_CONTR&0X10)//用来检测AD转换是否完成,ADC控制寄存器第五位为ADC_FLAG,为1时代表转换完成。
{
ADC_CONTR &=!ADC_FLAG;//清零转换完成标志位。
dat1=ADC_RES;//取出高8位转换值
dat2=ADC_RESL;//取出低2位转换值
x=(dat1<<2)|dat2;//将高8位与低2位的数值整合
ADC_CONTR=0x88|ch;//切换AD通道,同时启动AD转换,共8个AD通道,及P1口。转换速度90个时钟周期
value_buf[o++] = x;
}
}
}
////////////////////////////////////////////////////////
void scal()
{
if(o==N)
{
z=(3.906*filter()-2000);
ge=z%10;
shi=z%100/10;
bai=z%1000/100;
qian=z/1000;
display();
o=0;
}
}
//////////////////////////////////////////////////
void display()
{
flag3=1;
y=0;
if(!add)TR0=1;
if(!sub)TR0=0;
LOAD=1;
LOAD=0;
delay10ms(100);
//if(flag2)
//{
SPI_595(Tab[ge]);
SPI_595(Tab[shi]);
SPI_595(Tab[bai]);
SPI_595(Tab[qian]);
//SPI_595(Tab[ch]);//显示4位数码管
//delay10ms(5);
//flag2=0;
//}
//z=0;
}
//////////////////////////////////////////
/////////////////////////////////////
void timeREF()
{
if(y<3)
{
LOAD=1;
LOAD=0;
delay10ms(100);
SPI_595(Tab[time%10]);//显示4位数码管
SPI_595(Tab[time/10]);
SPI_595(Tab[18]);
SPI_595(Tab[18]);
delay10ms(10);
y++;
TR0=0;
}
while(!add)
{
delay10ms(10);
if(!add)
time++;
LOAD=1;
LOAD=0;
delay10ms(50);
SPI_595(Tab[time%10]);//显示4位数码管
SPI_595(Tab[time/10]);
SPI_595(Tab[18]);
SPI_595(Tab[18]);
}
while(!sub)
{
delay10ms(10);
if(!sub)
time--;
LOAD=1;
LOAD=0;
delay10ms(50);
SPI_595(Tab[time%10]);//显示4位数码管
SPI_595(Tab[time/10]);
SPI_595(Tab[18]);
SPI_595(Tab[18]);
}
}
/////////////////////////////////////
void ChangeCH()
{
if(!change)
{
delay10ms(100);
if(!change)
ch++;
}
if(ch==8)ch=0;
}
////////////////////////////////////////////////
void timer0() interrupt 1 using 1
{
tt++;
if(tt==1000)
{
led=~led;
t1++;
tt=0;
}
}
//////温度扫描更新周期500ms////////////////////////////////////////////////
void timer1() interrupt 3
{
cycle++;
if(cycle==20)
{
flag2=1;
cycle=0;
led=~led;
}
}
////////////////////////////////////////////////////
void dismode()
{
if(!BUTTON1)
{
delay(400);
if(!BUTTON1)
flag=~flag;
while(!BUTTON1);
}
}
//////////////////////////////////////////////////
uint filter()
{
char count,i,j;
int sum=0,temp;
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j;i++)
{
if ( value_buf[i]>value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
for(count=1;count<N-1;count++)
sum +=value_buf[count];
return (uint)(sum/(N-2));
}
并个电容低通滤波
温度的改变是很慢的
跳变是引入了干扰
我刚好这个东西,感觉还行,三线制
今天排查了下,把那个蓝色的变送器接到了PLC的AD模块上,数据仍然波动厉害,所以我决定更换变送器,重新选型。
你的检测温度范围是多少?可以透露下吗!
0-600,负的没去测量
你也使用了温度变送器的吧,单片机编程有做滤波处理吗?
您可以采用天微的产品,我是天微原厂的,我们的ADC芯片线产品非常全6-24位全部都有,目前在国内已被广泛应用于压力/温度/电池等行业,可以提供资料与技术支持,欢迎前来索取资料。文生QQ:31468679 电话:13428747651