数字时钟(LCD1602显示+时分按键校准功能)

概要

用51系列单片机设计一个数字时钟,要求在LCD1602显示屏的第一行显示学号;第二行显示时钟并有时、分按键校准功能。

预览图:

整体设计流程

先在proteus仿真软件画好仿真图,然后再到keil编程软件中实现功能代码的编写,最后将我们的代码进行编译、导出,然后下载到我们的仿真单片机中或者是实物的开发板中进行验证。

具体操作流程

top1:仿真图的绘制

实验用到的器件如图所示,找不到器件可以参考这张图下的标签来找:

查找的步骤如下图:

  

top2:keil编程代码

#include <REG52.H>//头文件
#define uchar unsigned char//无符号char数据类型的宏定义,用uchar替换unsigned char
#define uint unsigned int
sbit RS=P2^5;     //  定义端口      
sbit RW=P2^3;     
sbit E=P2^4;     
sbit key1=P3^0;   
sbit key2=P3^1;  
sbit key3=P3^2;  
sbit key4=P3^3;   //定义端口  
uchar code str[]="20210410B02xx";      // 学号
char hour=0,min=0,second=0;//时分秒
uchar con=0;
void delayms(uint ms)//ms延时函数
{
  uchar i;
	while(ms--)
	for(i=0;i<123;i++);
}
void w_com(uchar com)//1602写命令函数(一般是写位置,清除等)
{
  RS=0;
	RW=0;
	E=1;
	P0=com;
	E=0;
	delayms(1);
}
void w_dat(uchar dat)//1602写数据函数()
{
 RS=1;
	RW=0;
	E=1;
	P0=dat;
	E=0;
	delayms(1);
}
void lcd_init()//1602初始化函数()
{
  delayms(10);
	 w_com(0x38);
	delayms(10);
	 w_com(0x0c);
	delayms(10);
	 w_com(0x06);
	delayms(10);
	 w_com(0x01);
	delayms(10);
	 w_com(0x38);
	delayms(10);
}
void T0_inti()//T0定时1s。默认时钟频率为12Mhz
{
  TMOD=0x01;//方式一16位定时器
	TH0=(65536-50000)/256;//设置初值为50ms中断一次
	TL0=(65536-50000)%256;//设置初值为50ms中断一次
	TR0=1;//开定时器
	ET0=1;//开定时器的中断函数
	EA=1;//开中中断
}
void KEY_can()//按键处理函数
{
	
  if(key1==0||key2==0||key3==0||key4==0)
		 {
		   delayms(20);//消抖
			 if(key1==0||key2==0||key3==0||key4==0)
			 { 
				  
			    if(key1==0)//时+1
					{						
					   hour++;
						if(hour>23)
							hour=0;
						while(key1==0);					
					}
					else if(key2==0)//时-1						
					{							
					   hour--;
						if(hour<0)
							hour=23;
						while(key2==0);				
					}				
					else if(key3==0)	//分+1					
					{							
					   min++;
						if(min>59)
							min=0;
						while(key3==0);					
					}
					else if(key4==0)	//分-1					
					{
					   min--;
						if(min<0)
							min=59;
					  while(key4==0);
					}										
			 	
			 }
		   
		 }

}
void main()
{
	uint i;
  T0_inti();
	lcd_init();
	w_com(0x82);
	for(i=0;str[i]!='\0';i++)
	w_dat(str[i]);
	while(1)
	{	    
         KEY_can();
				 w_com(0xc2);
				 w_dat(hour/10+0x30);
				 w_dat(hour%10+0x30);
		     w_dat(':');
		     w_dat(min/10+0x30);
				 w_dat(min%10+0x30);
		     w_dat(':');
		     w_dat(second/10+0x30);
				 w_dat(second%10+0x30);
	}

}
void T0_EX0()interrupt 1//中断服务函数
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
    if(++con==20)//1s
	{
		con=0;
		if(++second==60)//1min
		{
			  second=0;
				if(++min==60)//1hour
				{		min=0;
						if(++hour==24)//1day
							hour=0;
				}		
		}

  }
	
}
	

 top3:将程序写好后先进行编译,看是否有错误,如果没错误就可以编译导出HEX下载文件

流程如下:

*无错误无警告*

top4:最后将工程目录下的Hex文件下载到单片机中

流程如下:

top5:运行

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要在51单片机上使用LCD1602显示时钟,可以按照以下步骤进行: 1. 配置时钟:使用定时器来产生1秒钟的中断,然后在中断服务函数中更新时钟数据。 2. 初始化LCD1602:设置LCD1602的工作模式、显示模式、光标模式等参数,并初始化显示内容。 3. 实现时钟显示:在主循环中不断更新LCD1602上的显示内容,包括时、分、秒等。 以下是代码示例: ```c #include <reg51.h> #define LCD1602_DB P1 sbit LCD1602_RS = P2^6; sbit LCD1602_RW = P2^5; sbit LCD1602_E = P2^7; unsigned char hour, minute, second; void initLCD1602(); void writeCommand(unsigned char command); void writeData(unsigned char data); void delay(unsigned int msec); void updateTime(); void main() { TMOD = 0x01; // 使用定时器0模式1 TH0 = 0xFC; // 定时1秒钟 TL0 = 0x66; TR0 = 1; // 开始计时 ET0 = 1; // 允许定时器0中断 EA = 1; // 允许总中断 initLCD1602(); while(1) { updateTime(); // 更新时钟数据 writeCommand(0x80); // 设置光标位置为第一行第一列 writeData(hour/10 + '0'); // 显示时 writeData(hour%10 + '0'); writeData(':'); writeData(minute/10 + '0'); // 显示分 writeData(minute%10 + '0'); writeData(':'); writeData(second/10 + '0'); // 显示秒 writeData(second%10 + '0'); } } void initLCD1602() { delay(15); // 上电后等待15ms writeCommand(0x38); // 设置工作模式为8位数据接口,双行显示,5x7点阵字符 writeCommand(0x0C); // 设置显示模式为开,关光标,不闪烁 writeCommand(0x06); // 设置光标移动方向为右,字符不移动 writeCommand(0x01); // 清屏 } void writeCommand(unsigned char command) { LCD1602_RS = 0; // 选择命令寄存器 LCD1602_RW = 0; // 写数据 LCD1602_DB = command; // 写入命令 LCD1602_E = 1; // 使能时序 delay(1); // 延时1us LCD1602_E = 0; // 禁能时序 } void writeData(unsigned char data) { LCD1602_RS = 1; // 选择数据寄存器 LCD1602_RW = 0; // 写数据 LCD1602_DB = data; // 写入数据 LCD1602_E = 1; // 使能时序 delay(1); // 延时1us LCD1602_E = 0; // 禁能时序 } void delay(unsigned int msec) { unsigned int i, j; for(i=0; i<msec; i++) { for(j=0; j<125; j++); } } void updateTime() { static unsigned int count = 0; if(count++ >= 1000) // 1秒钟到了 { count = 0; second++; if(second >= 60) { second = 0; minute++; if(minute >= 60) { minute = 0; hour++; if(hour >= 24) { hour = 0; } } } } } ``` 这段代码实现了在LCD1602显示时钟,使用定时器0产生1秒钟的中断,然后在中断服务函数中更新时钟数据。在主循环中不断更新LCD1602上的显示内容,使用writeCommand和writeData函数向LCD1602写入命令和数据。同时,还需要实现延时函数delay和更新时钟数据的函数updateTime。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小郑TE_Lab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值