基于51单片机的LCD1602电子时钟

学习任务:
(1)基本了解LCD1602
(2)基于51单片机用LCD1602实现分秒的计时;
(3)按键控制分秒的调整(两个按键分别控制分和秒的增加);
(4)能实现整时报时的功能(蜂鸣器响);
(5)了解下载模块、下载原理;
(6)基本上了解并使用DXP绘制PCB板;
知识点总结:
一、LCD1602:
字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,本次使用的LCD1602为16*2型。
1、基本操作时序
1、1读状态:输入:RS=L,Rw=H,E=H 输出:D0~D7=状态字;
1、2写指令:输入:RS=L,Rw=L,D0~D7=指令码,E=高脉冲,输出:无;
1、3读数据:输入:RS=H,Rw=H,E=H 输出:D0~D7=数据;
1、4写数据:输入:RS=L,Rw=H,D0~D7=数据,E=高脉冲,输出:无;
2、状态字说明
STA7……STA0
D7……D0
STA0~6为当前数据地址指针的数值;STA7为读写操作使能 1 禁止 0 允许;
第一行取地址为80 第二行为80+40;
3、初始化设置
显示模式设置
00111000(0x38)
显示开关及光标设置
指令码
00001DCB D=1开显示 ,D=0关
C=1显示光标,C=0关
B=1光标闪烁,B=0关
000001NS N=1 当读或写一个地址后字符指针加一,且光标加一
N=0 减 减
S=1 写一个字符,整屏显示左移(N=1)或右移(N=0)以得到光标不移动而屏移动
S=0 不移动
4、指示码
80H+地址码(0-27H 40-67H)(只显示每行前十六位)
01H 显示清屏:1、数据指针清零 2、所有显示清零
02H 显示回车:数据指针清零
5、初始化过程(复位过程)
1、延时15ms
2、写指令38H(不检测忙信号)
3、延时5ms
4、写指令38H(不检测忙信号)
5、延时5ms
6、写指令38H(不检测忙信号)
7、写指令38H:显示模式设置
8、写指令08H:显示关闭
9、写指令01H:显示清屏
10、写指令06H:显示光标移动设置
11、写指令0cH:显示开及光标设置
二、计时器
1、TMOD
用于设置定时、计数器的工作方式,低四位用于T0,高四位用于T1
位 7 6 5 4 3 2 1 0
字节地址 GATE C/T M1 M0 GATE C/T M1 M0 TMOD
GATE是门控位,用于控制定时器的启动是否受外部中断源信号的影响,用软件使TCON中的TR0或者TR1 为1 ,就可以启动定时/计数器工作;GATE=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能使定时/计数器工作。即此时定时器的启动条件加上了INT0/1引脚为高电平这一条件;
C/T:定时/计数模式选择位 C/T=0为定时模式;C/T=1为计数模式;
M1M0:工作模式设置位
定时/计数有四种工作方式
M1M0 工作方式 说明
00 1 13位定时器/计数器
01 2 16位定时器/计数器
10 3 8位自动重装定时/计数器
11 4 T0分为两个独立的8位定时/计数器;T1此方式停止计数

方式3:只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数
工作方式3将T0分成两个独立的8位计数器TL0好TH0
2、初始化程序
对TMOD赋值,已确定T0和T1的工作方式
计算初值,并将其写入TH0、TL0或TH1、TL1
中断方式时,则对EA赋值,开放定时器中断
使TR0或TR1置位,启动定时、计数器定时或计数
学习过程:
通过视频或网上资料对LCD1602及TMOD定时器有个基本的认识并进行初始化操作;
分析问题
首先使LCD1602能够基本的可以显示分秒位置;
再次能够使定时器能够实现每秒的增加,即对定时器设置成每秒变化,因为定时器为2^16us 所以为了使其能准确的在1s调整一位则在走一次定时器时实现50ms,然后重复走20次定时器时进行秒的增加;
在实现分秒增加的时候最好在按键的同时是定时器停止运行即TR0=0,然后显示光标及光标的闪烁即0x0f,然后每按一次使秒数增加,调整分时道理同上,在结束调整的时候使光标消失闪烁停止(0x0c),计时继续开始(TR0=1)
同时在主程序运行之前,按键扫描最好进行消抖处理,分秒程序放在主程序之前;

DXP画PCB板
先建立工程,再建立原理图及PCB 将这两个拖入工程中进行保存后开始在库中找元器件并进行连线,连线的同时注意引脚要确定连接好否则在导入PCB板时会出现错误,注意元器件的封装,没有封装的元器件不会导入PCB中
原理图画完之后导入PCB并没有错误的时候开始设置PCB板的大小及元器件的位置和连线,同时连线不要过于细,尽量将线连接适当。

#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar num=0,AN=0,e;
char fen=0,miao=0;
sbit rs=P2^6;
sbit rw=P2^5;
sbit E=P2^7;
sbit beef=P1^5;
sbit key1=P3^1;
sbit key2=P3^2;
void delay_50us(uchar i)
{
	uchar j;
	for( ;i>0;i--)
	for(j=100;j>0;j--);
}
void write_com(uchar com)
{
	rs=0;
	rw=0;
	E=0;
	P0=com;
	delay_50us(10);
	E=1;
	delay_50us(20);
	E=0;
}
void write_data(uchar dat)
{
	rs=1;
	rw=0;
	E=0;
	P0=dat;
	delay_50us(10);
	E=1;
	delay_50us(20);
	E=0;
}
void write_shu(uchar add,uchar date)
{
	uchar ge,shi;
	shi=date/10;
	ge=date%10;
	write_com(0x80+0x40+add);
	write_data(0x30+shi);
	write_data(0x30+ge);
}
void init(void)
{
	delay_50us(300);
	write_com(0x38);
	delay_50us(10);
	write_com(0x38);
	delay_50us(10);
	write_com(0x38);
	write_com(0x38);
	write_com(0x08);
	write_com(0x01);
	write_com(0x06);
	write_com(0x0c);
	write_com(0x80);
	write_com(0x80+0x46);
	write_data(':');
	delay_50us(10);
	TMOD=0x01;
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	EA=1;
	ET0=1;
	TR0=1;

}

void key_scan()
{
	if(key1==0)
	delay_50us(100);
	if(key1==0)
	{
		TR0=0;
		AN++;
		while(!key1);
	}
		if(AN==1)
		{
			write_com(0x80+0x40+8);
			write_com(0x0f);
	    if(key2==0)
	    delay_50us(100);
	    if(key2==0)
	    {
		   while(!key2);
		    miao++;
		    if(miao==60)
		    {
			   beef=~beef;
					delay_50us(10);
		     miao=0;
		     fen++;
					if(fen==60)
						fen=0;
			   write_shu(4,fen);
		    }
    		write_shu(7,miao);
	    }
		}
		if(AN==2)
		{
			write_com(0x80+0x40+5);
			write_com(0x0f);
	    if(key2==0)
	    delay_50us(100);
	    if(key2==0)
	    {
		   while(!key2);
	  	 	fen++;
				if(fen==60)
		     fen=0;
		    write_shu(4,fen);
    	}
		}
		 if(AN==3)
		 {
			 TR0=1;
			 AN=0;
			 write_com(0x0c);
		 }
}
void int0 () interrupt 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	num++;
    if(num==20)
		{
			num=0;
			miao++;
			if(miao==60)
			{
				miao=0;
				beef=~beef;
				delay_50us(10);
				beef=~beef;
				delay_50us(10);
				beef=~beef;
				delay_50us(10);
				beef=~beef;
				delay_50us(10);
				beef=~beef;
				delay_50us(10);
				beef=~beef;
				delay_50us(10);

				fen++;
				if(fen==60)
				{
					fen=0;
				}
			}
	  	write_shu(4,fen);
			write_shu(7,miao);
		}
}
void main()
{
	init();
	while(1)
	{
		key_scan();
	}
}

要实现51单片机LCD1602电子时钟,可以按照以下步骤进行: 1. 硬件连接 将LCD1602模块的VSS、VDD、V0分别连接到GND、VCC、可变电阻器的中间端口。将RS、RW、EN分别连接到单片机的P1口的0、1、2。将D0-D7分别连接到单片机的P2口的0-7。 2. 初始化 在程序中初始化LCD1602模块,包括设置显示模式、光标位置等。 3. 获取时间 通过单片机的定时器或外部RTC模块获取当前时间。 4. 更新显示 将时间信息显示到LCD1602模块上。 5. 循环更新 使用循环结构,不断获取时间并更新显示。 下面是一个简单的51单片机LCD1602电子时钟程序示例: ```c #include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit RS=P1^0; sbit RW=P1^1; sbit EN=P1^2; void Delay(uint n) { while(n--); } void WriteCommand(uchar cmd) { RS=0; RW=0; P2=cmd; EN=1; _nop_(); _nop_(); EN=0; } void WriteData(uchar dat) { RS=1; RW=0; P2=dat; EN=1; _nop_(); _nop_(); EN=0; } void InitLCD1602() { WriteCommand(0x38); //设置显示模式,16x2,5x7点阵,8位数据接口 WriteCommand(0x0c); //显示开,光标关,光标闪烁关 WriteCommand(0x06); //光标移动设置,增量,不移动屏幕 WriteCommand(0x01); //清屏 } void DisplayTime(uchar hour, uchar minute, uchar second) { 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 main() { uchar hour=0, minute=0, second=0; InitLCD1602(); while(1) { hour=12; //假设当前时间为12点 minute=30; second=0; DisplayTime(hour, minute, second); Delay(50000); //延时,等待下一秒 second++; if(second>=60) { second=0; minute++; } if(minute>=60) { minute=0; hour++; } if(hour>=24) { hour=0; } } } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值