⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock- lcd1602.c

📁 1602显示电子时钟的51代码。包括C语言和汇编语言两种语言。
💻 C
字号:
/*******************************************************************
*                                                                  *
* ME500单片机开发系统演示程序 -   时钟                             *
*                                                                  *
* LCD1602显示                                                      *
*                                                                  *
* 版本: V1.0 (2006/11/20)                                         *
* 作者: gguoqing (Email: gguoqing@willar.com)                     *
* 网站: www.willar.com(伟纳电子)   www.mcusj.com(伟纳单片机世界)  *
* 邮箱: support@willar.com                                        *
*                                                                  *
*【版权】Copyright(C)伟纳电子 www.willar.com  All Rights Reserved  *
*【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!        *
*                                                                  *
*******************************************************************/

#include <reg51.h>
#include <intrins.h>

#define uchar unsigned char
#define uint  unsigned int

sbit  K1   = P1^4;
sbit  K2   = P1^5;
sbit  K3   = P1^6;
sbit  K4   = P1^7;
sbit  BEEP = P3^7;          //蜂鸣器

uchar code  cdis1[ ] = {"   WELCOME TO   "};
uchar code  cdis2[ ] = {" WWW.WILLAR.COM "};
uchar code  cdis3[ ] = {"  BEIJING TIME  "};
uchar code  cdis4[ ] = {"TIME:           "};
uchar code  cdis5[ ] = {" RESET REALTIME "};

sbit LCD_RS = P2^0;             
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

bit    settime,updown;
uchar  msec,sec,min=59,hour=23,m,count;

uchar display[] =  {0x00,0x00,0x00,0x00,0x00,0x00};

/*********************************************************
*                                                        *
* 延时函数                                               *
*                                                        *
*********************************************************/
void Delay(uint num)//延时函数
{
  while( --num );
}

/*********************************************************
*                                                        *
* 延时函数                                               *
*                                                        *
*********************************************************/
void delay1(int ms)
{
   unsigned char n;
   while(ms--)
   {
     for(n = 0; n<250; n++)
    {
      _nop_();
      _nop_();
      _nop_();
      _nop_();
    }
   }
}

/**********************************************************
*                                                         *
* 蜂鸣器响一声                                            *  
*                                                         *                                        
**********************************************************/
void beep()
{
    unsigned char y;
    for (y=0;y<180;y++)
    {
      BEEP=!BEEP;                //BEEP取反
	  Delay(70);
    } 
    BEEP=1;                      //关闭蜂鸣器
    delay1(100);

}

/**********************************************************
*                                                         *
* 检查LCD忙状态                                           *
* lcd_busy为1时,忙,等待。                               *
* lcd-busy为0时,闲,可写指令与数据。                      *
*                                                         *
**********************************************************/ 
bit lcd_busy()
 {                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result); 
 }

/**********************************************************
*                                                         *
*写指令数据到LCD                                          *
*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                     *
*                                                         *
**********************************************************/
void lcd_wcmd(uchar cmd)
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_(); 
    P0 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}

/**********************************************************
*                                                         *
*写显示数据到LCD                                          *
*RS=H,RW=L,E=高脉冲,D0-D7=数据。                       *
*                                                         *
**********************************************************/
void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0; 
}

/**********************************************************
*                                                         *
*  LCD初始化设定                                          *
*                                                         *
**********************************************************/
void lcd_init()
{ 
    delay1(15);   
    lcd_wcmd(0x01);      //清除LCD的显示内容            
    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);

    lcd_wcmd(0x0c);      //开显示,不显示光标  
    delay1(5);

    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay1(5);
}

/**********************************************************
*                                                         *
*  设定显示位置                                           *
*                                                         *
**********************************************************/

void lcd_pos(uchar pos)
{                          
  lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量
}

/**********************************************************
*                                                         *
* 显示函数                                                *
*                                                         *
**********************************************************/
void play(uchar input1,input2,input3)
{  
   display[1]=input1/10+0x30;    //秒单位数据处理
   display[0]=input1%10+0x30;

   display[3]=input2/10+0x30;    //分单位数据处理
   display[2]=input2%10+0x30;
   
   display[5]=input3/10+0x30;    //时单位数据处理
   display[4]=input3%10+0x30;

   lcd_pos(0x46);
   lcd_wdat(display[5]);         //显示时
   lcd_wdat(display[4]);
   lcd_wdat(0x3a);               //显示':'
  
   lcd_wdat(display[3]);         //显示分
   lcd_wdat(display[2]);
   lcd_wdat(0x3a);               //显示':'

   lcd_wdat(display[1]);         //显示秒
   lcd_wdat(display[0]); 
}

/**********************************************************
*                                                         *
* 时间设定函数                                            *
*                                                         *
**********************************************************/
void  set_time()
{   
  updown=1;
  settime=0;

  if(K1==0)
  {
     beep();
     while(K1==0);
     settime=1;
     lcd_pos(0x00);             //设置显示位置为第一行
     for(m=0;m<16;m++) 
     lcd_wdat(cdis5[m]);        //显示字符 
  
   while(settime)
   { 
     TR0=0;
	 if(K2==0)
	 {
	   beep();
	   if(updown)
	   {
	     hour++;
	     if(hour==24)
	     hour=0;
	   }
	   else
	   {
	     hour--;
	     if(hour==0xff)
	     hour=23;	   
	   }
     }

     if(K3==0)
	 {
	   beep();
	   if(updown)
	   {
	     min++;
	     if(min==60)
	     min=0;
	   }
	   else
	   {
	     min--;
	     if(min==0xff)
	     min=59;	   
	   }
     }

	 if(K1==0)
     {
       beep();
       while(K1==0);
       updown=~updown;
     }

     if(K4==0)
     {
       beep();
       while(K4==0);
       settime=0;
	   sec=0;
	   TR0=1;
     }
      
      play(sec,min,hour);
 
   }  // end of while(settime)  
   
    lcd_pos(0x00);             //设置显示位置为第一行
    for(m=0;m<16;m++)
    lcd_wdat(cdis3[m]);
 
  } // end of if(K1==0)  
}

/*********************************************************
*                                                        *
* 主函数                                                 *
*                                                        *
*********************************************************/
main()
{
   TMOD=0x01; 
   TH0=0x4c; 
   TL0=0x00;        //50ms定时 
   ET0=1;
   EA=1;

   lcd_init();
   
   lcd_pos(0x00);             //设置显示位置为第一行
   for(m=0;m<16;m++)
   {
     lcd_wdat(cdis1[m]);        //显示字符 
     delay1(50);
   }
   lcd_pos(0x40);             //设置显示位置为第二行
   for(m=0;m<16;m++)
   {
    lcd_wdat(cdis2[m]);        //显示字符
    delay1(50);
   }

   delay1(3000);

   lcd_pos(0x00);             //设置显示位置为第一行
   for(m=0;m<16;m++) 
   lcd_wdat(cdis3[m]);        //显示字符 

   lcd_pos(0x40);             //设置显示位置为第二行
   for(m=0;m<16;m++)
   lcd_wdat(cdis4[m]); 

   TR0=1;

   while(1)
   {   
     play(sec,min,hour);
 	 set_time();
   }
}

/**********************************************************
*                                                         *
* Time0中断函数                                           *
*                                                         *
**********************************************************/
void Time0(void) interrupt 1 using 0
{
   TH0=0x4c;               //50ms定时
   TL0=0x00;

   msec++;
   if(msec==20)            //50*20=1S
   {
     msec=0;
     sec++;                //秒加1
	 if(sec==60)
	 {
	   sec=0;
 	   min++;              //分加1
 	   if(min==60)
	   {
	     min=0;
		 hour++;           //时加1
		 if(hour==24)
         {
		   hour=0;        //清计时单元
           min=0;
           sec=0;
         }
       }
     }
   }
}

/*********************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -