📄 lcdclock.c
字号:
/********************************************************************************
*1602液晶显示时钟程序,按键P1.4-P1.7 喇叭 P3.7 液晶数据P0,控制P2.0-2.2 *
********************************************************************************
* 日期: 2007-3-25 *
* 版本: 3.0 *
* 作者: 深圳学林电子有限公司 专业8051单片机教学站 *
* 邮箱: sxj1974@163.com *
* 网站: http://www.51c51.com http://www.8951.com 更多例程请登陆网站 *
********************************************************************************
* 硬件:此程序在本公司xlisp系列单片机实验仪运行通过 *
********************************************************************************
* 【版权】 Copyright(C)深圳学林电子有限公司 www.51c51.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.51C51.COM "};
uchar code cdis3[ ] = {" XUE LIN DIAN ZI"};
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 + -