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

程序如下所示:

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

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

#include 
#include 

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;
     }
}



1602显示数字不稳定一直跳动(AD转换)_第1张图片

你可能感兴趣的:(STC单片机)