微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 关于10位ADC采集PT100温度值的问题,温度值波动很厉害,求高手指点!

关于10位ADC采集PT100温度值的问题,温度值波动很厉害,求高手指点!

时间:10-02 整理:3721RD 点击:
关于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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top