专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

基于stc89c52rc单片机的数字钟设计程序部分(1602液晶显示)

作者:佚名   来源:本站原创   点击数:  更新时间:2011年11月05日   【字体:
与数字中的数码管显示类似,

增加:

液晶初始化部分

写命令部分

写数据部分


********************************************************************

*********************************************************************

#include<reg52.h>
#define  uchar unsigned char
#define  uint unsigned int
sbit rs = P2^6; //1602相应                                                      
sbit rw = P2^5;                                                       
sbit ep = P2^7;  

uchar hour,min,sec,k;

uchar key;
unsigned char lcdd[]="0123456789"; 
uchar key_code[] = {0xb7,0xbb,0xbd,0xbe};//键盘编码,我只用到四个键。 你我的编码可能不同 ,具体看电路如何连接。
     
void delay(uint z)
{     

 uint x,y;
 for(z=x;x>0;x--)
    for(y=100;y>0;y--);
}

bit lcd_bz()
{   // 测试LCD忙碌状态
 bit result;
 rs = 0;
 rw = 1;
 ep = 1;
    delay(5);
 result = (bit)(P0 & 0x80);//判断P0^7是一还是零.屏蔽掉其它位0x80.强制转换位bit型数据。在返回给result。
 ep = 0;
 return result; 
}
void lcd_cmd(uchar cmd)
{
   
 while(lcd_bz());
 rs = 0;//rs为1时写入的是“数据”为0时写入“指令”
 rw = 0;//rw为1时“读取”为0时“写入”
 ep = 0;//使能
 delay(5); 
 P0 = cmd;
 delay(5);
 ep = 1;
 delay(5);
 ep = 0;  
 
}


void lcd_data(uchar dat )//液晶写数据
{
 

 while(lcd_bz());
 rs=1;
 rw=0; 
 ep=0;
    P0 = dat;
    delay(5);
 ep = 1;
 delay(5);
 ep = 0;
 //return dat; 
}

void lcd_init()  //液晶写命令                  
{                                                                         
    delay(15);      //等待LCD电源稳定                      
    lcd_cmd(0x38);                           
    delay(10);                                                            
    lcd_cmd(0x38);                                                       
    delay(10);                                                           
    lcd_cmd(0x38);                                                       
    delay(10);                                                            
                                                                          
    lcd_cmd(0x0c);          //显示开,关光标                             
    delay(10);                                                            
    lcd_cmd(0x06);          //移动光标                                   
    delay(10);                                                            
    lcd_cmd(0x01);          //清除LCD的显示内容                          
    delay(10);                                                            
}  

 


void timer0() interrupt 1
{
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;
 k++;
        if(k==20)
        {
        k=0;
          sec++;
  
     }

        if(sec>59)
    {
     min++;
     sec=0;
 }
 if(min>59)
 {
    min=0;
    hour++;
 }
 if(hour>23)
 {
    hour=0;
 }  
}    


void disptime()  //时间显示函数
{
 lcd_cmd(0x0c); //设置光标不显示、不闪烁
 delay(20);
 lcd_cmd(0x80); //起始显示地址
 delay(20);

 lcd_data(lcdd[hour/10]);
 delay(10);          
 lcd_data(lcdd[hour%10]);
 delay(10);
 lcd_data(':');
 delay(12);              
      
 lcd_data(lcdd[min/10]);
 delay(10);           
 lcd_data(lcdd[min%10]);
 delay(12);
 lcd_data(':');
 delay(12);
  
 lcd_data(lcdd[sec/10]);
 delay(12);          
 lcd_data(lcdd[sec%10]);
 delay(12);    
 lcd_data(' ');
 delay(12);

 
}

uchar keyscan()    //键盘扫描程序
{
  uchar scan1, scan2, keycode, j;

  P1 = 0xf0;
  scan1 = P1;
  if (scan1 != 0xf0)
  //判键是否按下
  {
    delay(10); //延时10ms
    scan1 = P1;
    if (scan1 != 0xf0)
    //二次判键是否按下
    {
   TR0=0; //如果有键按下 则定时器停止工作
      P1 = 0x0f;
      scan2 = P1;
      keycode = scan1 | scan2; //组合成键扫描编码

      for (j = 0; j < 4; j++)
      {
        if (keycode == key_code[j])
        //查表得键值
        {
          key = j;
    while(P1!= 0x0f)    //松手有效 这里需要好好研究一下 可以用万用表测量管脚电压帮助理解
    disptime();
          return (key); //返回有效键值   
        }
      }
    }
 
  }
  else
    P1 = 0xff;

 
  return (key = 4); //返回无效码
}

 


   
void Set_time(uchar key)
{
 
 if(key==0||key==1||key==2)//若s1,s2,s3其中有键按下,则为真
 {
    if(key==0)
    {
       sec++;
    if(sec>59)
    {
   sec=0;
    }
    }
    else if(key==1)
    {
    min++;
    if(min>59)
    {
       min=0;
    }
    }
       else if(key==2)
    {
     hour++;
     if(hour>23)
     {
        hour=0;
     }
    }

    
   }
   else if(key==3)
   {
   TR0=1;   //按下退出键 定时器继续工作
 
   }
}

  
void sysint() //定时器初始化
{   
 
 TMOD=0x01;
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;
 EA=1;
 ET0=1;
 TR0=1;
 }


 void timeint()    //初始化
 {
   
 hour=0;
 min=0;
 sec=0;
 }

 

 

 

void main()
{
    
     sysint() ;
  timeint();
  lcd_init();//函数调用
 while(1)
 {
    keyscan();//调用键盘扫描,
    Set_time(key);
    disptime();
          
 }
}
关闭窗口

相关文章