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

📄 lcd_clock.c

📁 基于51系列单片机的1602液晶显示可调时钟(精确到毫秒级)。
💻 C
字号:
//=============================================
//    		基于1602液晶显示可调时钟		 //
//作者:万迅	   2008年11月02日			 //
//QQ:373179882								 //
//E-mail:wanxunpcmo@163.com				 //
//使用AT89C51单片机  12MHz晶振	精确到毫秒	 //
//=============================================
//库与数据缩写定义
#include <AT89X51.h>		//包含AT89X51库
#define uc unsigned char	//定义数据格式缩写
#define ui unsigned int		//定义数据整形缩写
#define control_number 2	//定义可供调节的数据数
//=============================================
//与1602液晶显示模块(LCM)的接口定义
#define DB_BUS P2			//定义数据总线
sbit RS=P3^0;				//定义:数据(1)/指令(0)使能引脚
sbit RW=P3^1;				//定义:读(1)/写(0)使能信号
sbit E=P3^2;				//定义执行操作使能信号,下降沿有效
sbit busy=DB_BUS^7;			//定义忙信号
//=============================================
//定义按键接口				
sbit FUN_KEY=P1^0;				//定义功能键
sbit INC_KEY=P1^1;				//定义增加键
sbit DEC_KEY=P1^2;				//定义减少键
//=============================================
//定义相关数据
uc hou,min,sec,mil;				//定义:小时(hou),分钟(min),秒(sec),毫秒(mil)
uc connum;						//定义数据可调允许位,为0时不可调
bit k0,k1,k2;					//定义按键状态位,防止因长按按键引起多次操作
//=============================================
//函数预定义
void writcode(uc cd);			  //写指令函数
void writdata(uc dat);			  //写数据函数
//=============================================

//液晶显示模块(LCM)初始化
void init_lcm()
{	writcode(0x38);				  //设置功能:8位通信;两行显示;5x7显示单元
	writcode(0x38);				  //重写一次防止因1602通电时的假就绪而引起的功能设置失败
	writcode(0x08);				  //关闭显示屏
	writcode(0x01);				  //清屏
	writcode(0x0c);				  //开显示屏并置光标不可见,光标所在字符不闪烁
	writcode(0x06);				  //设置输入模式
}
//单片机基本初始化								   
void uart_init()			   	//定义初始化定时函数
{	hou=min=sec=mil=0;			//时,分,秒初始化
	connum=0;					//置数据可调允许位为0,即数据不可调节
	k0=k1=k2=1;				   	//按键状态初始化
	TMOD=0x01;					//定时计数工作方式1
	IE=0x82;					//允许定时计数中断0
	TH0=0xd8;					//
	TL0=0xf0;					//定时10ms
	TR0=1;						//开启定时计数器0
} 
//每10ms中断一次的定时中断
//实现毫秒100进1,秒60进1,分钟60进1,小时24清零时钟功能
void timer0() interrupt 1 using 2
{	TH0=0xd8;					   //
	TL0=0xf0;					   //定时10ms
	if(mil>=99)					   
		{	mil=0;				   
			if(sec>=59)
				{	sec=0;
					if(min>=59)
						{	min=0;
							hou=hou>=23?0:++hou;
						}
					else ++min;
				}
			else ++sec;
		}
	else ++mil;
}
//等待空闲函数
//检查忙状态,等待空闲
void chkbusy()						 
{	RS=0;							 //定义数据类型为指令
	E=1;							 //置E为1
	RW=1;							 //RW为“1”,使能信号E为“1”表示从总线读数据
	DB_BUS=0xff;					 //置数据总线为0xff以便正确读出忙信号
	while(!busy);					 //等待直到不忙为止
}

void writcode(uc cd)						   
{	chkbusy();						 //等待空闲								
	RW=0;							 //数据操作为写
	RS=0;							 //数据类型为指令
	E=1;
	DB_BUS=cd;						 //将指令写到数据总线端口
	E=0;							 //E产生下跳沿将总线上的数据写入1602
}

void writdata(uc dat)
{	chkbusy();						 //等待空闲	
	RW=0;							 //数据操作为写
	E=1;
	RS=1;							 //数据类型为数据
	DB_BUS=dat;						 //将数据写到数据总线端口
	E=0;							 //E产生下跳沿将总线上的数据写入1602
}
//屏幕显示函数
//注:指定DDRAM地址后每写一次数据DDRAM地址自动加一
void display()
{ 	writcode(0x80);					 //置DD RAM地址为0x00(0x80-0x80=0x00)
	switch(connum)					 //屏幕显示的数据与DD RAM地数据相对应,初始时0x00对应屏幕上的第一行第一个字符
	{	case 1:writdata('h');break;	 //数据可调允许位为1,即允许调节小时则写第一行第一个字符为‘h’
		case 2:writdata('m');break;	 //数据可调允许位为2,即允许调节分钟则写第一行第一个字符为‘m’
		default:writdata(' ');		 //数据不可调则清空第一行第一个字符
	}
	writdata(' ');					 //空出一格
	writdata(hou/10+48);			 //取小时的十位并将其加48转换成其ASCII后写数据到DDRAM
	writdata(hou%10+48);			 //取小时的个位并将其加48转换成其ASCII后写数据到DDRAM
 	writdata(':');					 //编译器会自动将‘:’转换为ASCII码
	writdata(min/10+48);			 //以下同理
	writdata(min%10+48);
	writdata(':');
	writdata(sec/10+48);
	writdata(sec%10+48);
	writdata('-');;
	writdata(mil/10+48);
	writdata(mil%10+48);
	writdata(' ');
	hou>12?writdata('P'):writdata('A');	   //小时大于12则显示‘P’小于则显示‘A’
	writdata('M');	
}
//按键检测函数
//
void  chkkey()						
{	if(k0==1&&FUN_KEY==0)			//与标志位结合起来可判断按键的下跳沿
	{	k0=0;						//按键按下将标志位清零表示按键处于按下状态
		connum=connum>=control_number? 0:++connum;	//改变数据可调允许位的值
	}
	if(k1==1&&INC_KEY==0)			
	{	k1=0;
		if(connum==1)hou=hou>=23?0:++hou;	 //按下加键根据数据可调允许位的值对数据进行操作
		if(connum==2)min=min>=59?0:++min;
	}
	if(k2==1&&DEC_KEY==0)
	{	k2=0;
		if(connum==1)hou=hou==0?23:--hou;	 //按下减键根据数据可调允许位的值对数据进行操作
		if(connum==2)min=min==0?59:--min;
	}
	k0=FUN_KEY?1:0;				   //一下操作使按键状态与标志位处以同一状态
	k1=INC_KEY?1:0;
	k2=DEC_KEY?1:0;
}

void main(void)
{	uart_init();				  //对单片机进行基本初始化
	init_lcm();					  //初始化1602液晶显示模块
	while(1)
	{	display();				  //屏幕显示
		chkkey();				  //按键检
	 }

}

⌨️ 快捷键说明

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