1602显示数字不稳定一直跳动(AD转换)

来源:互联网 发布:网络布线 价格 编辑:程序博客网 时间:2024/05/20 04:50

程序如下所示:

首先说明下,此程序为AD转换芯片PCF8591采集电压数据,然后送到1602显示。

现象:1602显示的数字一直频繁的跳动,乱花眼。此现象不是一直出现的,有时候会出现,同样的硬件,同样的程序,昨天还是好好的,今天一开机就会跳动,让人捉摸不透,即使我把中断屏蔽了也不行,后来百度有人说可能是读AD的时候没有把中断关闭,可是我中断已经屏蔽了啊,不纯在不关闭的情况啊?但是我还是按照他给的建议在读AD前加上了EA=0,读后EA=1,然后再试,果然立马好了。

#include <reg51.h>#include <intrins.h>sbit SDA=P2^0;sbit SCL=P2^1;sbit lcd_rs=P1^0;sbit lcd_rw=P1^1;sbit lcd_en=P2^5;sbit beep=P2^3;bit ADFlag;unsigned char num,count;unsigned char table[]="Voltage: .    V";unsigned char TempData[2];char shi,ge,bai;void Delay(unsigned char i){unsigned char j,k;for(j=i;j>0;j--)for(k=110;k>0;k--);}void NOP(){    _nop_();    _nop_();    _nop_();        _nop_();}/****起始****/void i2c_start(){    SDA=1;    NOP();    SCL=1;    NOP();    SDA=0;    NOP();    SCL=0;    NOP();}/****停止****/void i2c_stop(){    SDA=0;    NOP();    SCL=1;    NOP();    SDA=1;    NOP();}/****写字节****/void Write_Byte(unsigned char date){     unsigned char i,temp;      temp=date;    for(i=0;i<8;i++)    {        temp=temp<<1;        SDA=CY;        NOP();        SCL=1;        NOP();        SCL=0;        NOP();      }        SDA=0;        NOP();        SCL=1;        NOP();        SCL=0;        NOP();       }/****应答i2c****/void Ack(void){    SDA=0;    NOP();    SCL=1;    NOP();    SCL=0;    NOP();}/****非应答i2c****/void No_Ack(void){    SDA=1;    NOP();    SCL=1;    NOP();    SCL=0;    NOP();}//读字节。注意:读数据时SCL与SDA的先后顺序unsigned char Read_Byte(){    unsigned char i,temp=0;    SCL=0;    NOP();    SDA=1;    for(i=0;i<8;i++)    {        temp=temp<<1;        NOP();        temp=temp|SDA;        SCL=1;        NOP();        SCL=0;        NOP();  }    return temp;}//读取AD模数转换的值,有返回值unsigned char Read_PCF8591_ADC(){    unsigned char temp;    i2c_start();    Delay(20);    Write_Byte(0x90);  //写入地址    Delay(20);    Write_Byte(0x42);  //选择通道    Delay(20);    i2c_start();    Write_Byte(0x91);  //读命令    temp= Read_Byte();    i2c_stop();    return temp;}void lcd1602_write_com(unsigned char a){    lcd_rs=0;    Delay(5);    lcd_rw=0;    Delay(5);    P0=a;    Delay(5);    lcd_en=1;    Delay(5);    lcd_en=0;}void lcd1602_write_date(unsigned char b){    lcd_rs=1;    Delay(5);    lcd_rw=0;    Delay(5);    P0=b;    Delay(5);    lcd_en=1;        Delay(5);      lcd_en=0;}void lcd1602_init(){      lcd_en=0;      Delay(5);    lcd1602_write_com(0x38);    Delay(5);    //lcd1602_write_com(0x08);    Delay(5);    lcd1602_write_com(01);    Delay(5);    lcd1602_write_com(0x06);    Delay(5);    lcd1602_write_com(0x0c);    Delay(5);    }void lcd1602_Display(){    lcd1602_write_com(0x80+0x01);    for(num=0;num<15;num++)     {        lcd1602_write_date(table[num]);        Delay(20);      }     lcd1602_write_com(0x80+0x40+1); }//定时器中断程序void Timer0_init(){    TMOD=0x01;  //定时器0,模式1,16位定时器        TR0=1;    TH0=(65535-50000)/256;   //高8位,=60    TL0=(65536-50000)%256;  //低8位    ET0=1;  //使能定时器0中断    EA=1;   //开总中断}void main(){     // unsigned char AD_temp;  //如果用此语句,会在值达到255后溢出,并重新计数   long AD_temp;   long kk;     lcd1602_init();     Timer0_init();     while(1)        {           if(ADFlag)             {              ADFlag=0;  lcd1602_Display();       EA=0;                AD_temp=Read_PCF8591_ADC();      EA=1;kk=AD_temp*5*100/256;bai=kk/100;shi=kk%100/10;ge=kk%10;               // shi=AD_temp*5*100/256;               // ge=(AD_temp%50)/10;                    lcd1602_write_com(0x80+0x40+7);                  lcd1602_write_date(0x30+bai);                   lcd1602_write_com(0x80+0x40+8);                  lcd1602_write_date(0x2e);//小数点                   lcd1602_write_com(0x80+0x40+9);                  lcd1602_write_date(0x30+shi);                   lcd1602_write_com(0x80+0x40+10);                  lcd1602_write_date(0x30+ge);                                                              Delay(2000);                }        }}void timer0() interrupt 1{  TH0=(65536-50000)/256;  TL0=(65535-50000)%256;  //50000*(11.0592/12)ms定时,若晶振为12MHz,则为50ms  count++;    if(count=18)    {        count=0;        ADFlag=1;     }}


0 1