基于单片机的LCD1602电子时钟设计

合集下载

C语言Lcd1602万年历闹钟Proteus仿真单片机毕业课程电子设计

C语言Lcd1602万年历闹钟Proteus仿真单片机毕业课程电子设计

C语言Lcd1602万年历闹钟Proteus仿真单片机毕业课程电子设计
C语言Lcd1602万年历闹钟Proteus仿真单片机设计
AT89C51+Lcd1602+DS1302+独立按键+蜂鸣器
Lcd1602万年历闹钟。

时间信息来自DS1302,显示采用
Lcd1602,蜂鸣器提供闹音和按键提示音。

液晶上面显示年月日时分秒星期以及闹钟时间。

有时间调节和闹钟调节,可以调节年月日时分秒星期信息以及闹钟时间。

具体介绍如下。

1.做好的仿真图,如下图所示。

2.启动仿真后,先在液晶屏显示系统信息,然后在第二屏显示需要的万年历闹钟信息。

如下图所示!
3.通过单片机右侧的三个按键,即可设置闹钟。

如下图所示。

4.通过单片机左侧的四个按键,来设置年月日时分秒星期的值。

设置时,参数闪烁,同时会有按键提示音。

5.本设计默认套餐1,具体套餐详情请看下面的发货清单。

如需要其它套餐,请联系客服询问。

详情请:点击此处。

基于51单片机LCD1602数字钟讲解

基于51单片机LCD1602数字钟讲解

基于51单片机的数字时钟实训单位: 南耕科技系别: 工程技术系专业:姓名:摘要本文介绍了基于AT89C51单片机的数字式时钟的设计,详细叙述了系统硬件、软件的具体实现过程。

本文在硬件、软件设计上均采用模块化的方法,使得在设计和调试方面取得很大的方便。

软件同样采用模块化的设计,包括中断模块、时间调整模块等设计,并采用简单流通性强的C语言编写实现。

本设计实现了时、分、秒的显示和时间修改的功能。

通过对比实际的时钟,查找出误差的来源,确定调整误差的方法,尽可能的减少误差,使得系统可以达到实际数字钟的允许误差范围内。

关键字:AT89C51单片机;数字钟;模块化;目录1 绪论 (1)1.1 课题背景 (1)1.2 课题意义 (2)1.3 数字式时钟的应用 (2)1.4 本章小结 (3)2 单片机简介 (3)2.1 单片机的选择 (3)2.1.1 单片机的特点 (5)2.1.2 单片机的应用领域 (5)2.2 AT89C51单片机的基本结构 (6)2.3 本章小结 (11)3 数字式时钟的硬件设计 (12)3.1 最小系统设计 (13)3.2 数字式时钟的外围电路设计 (14)3.3 本章小结 (19)4 数字式时钟的软件设计 (19)4.1 系统软件设计内容 (19)4.2主程序 (20)4.3时钟设置子程序 (22)4.4中断子程序 (24)4.5 LCD显示子程序 (24)4.6 本章小结 (26)5 数字式时钟的Protues软件仿真 (26)5.1 Protues软件的概述 (26)5.2 Protues软件的功能特点 (27)5.3 Protues软件具有4大功能模块 (27)5.4 数字式时钟的Proteus软件仿真 (29)5.5 本章小结 (35)结论 (36)致谢 (37)单片机介绍 (37)附录 (41)1 绪论1.1 课题背景单片机自1976年由Intel公司推出MCS-48开始,迄今已有二十多年了。

基于LCD1602电子时钟

基于LCD1602电子时钟

信息与电子工程学院课程设计报告录目一、课程设计概述 (3)1.1 课程设计背景 (3)1.2 课程设计内容 (3)1.3 课程设计技术指标 (3)二、方案的选择及确定 (3)2.1 单片机芯片的选择 (3)2.2 显示模块的选择 (4)2.3 实时时间计算模块的选择.42.4 实时环境温度采集模块选择 (4)2.5 电路设计最终方案决定 (5)三、系统硬件设计 (5)3.1 主控模块 (5)3.2LCD显示模块设计 (6)3.3 时间计算模块设计 (6)3.4 实时环境温度检测模块 (7)3.5 报警模块 (7)3.6 设置模块 (8)3.7 电源接口部分 (8)四、系统软件设计 (8)4.1 主函数 (8)4.2 设置模块 (9)4.31602 液晶屏 (10)4.4 软件原理图 (11)五、系统调试过程 (11)5.1 软件调试 (11)5.2 硬件调试 (12)六、结论 ..................................12七、遇到的问题及解决方法和总结 (12)7.1 硬件方面 (12)7.2 软件方面 (13)7.3 总结 (13)1八、参考文献 (13)九、附录 (14)课程设计概述1.1 课程设计背景随着微电子技术的高速发展,单片机在国民经济的个人领域得到了广泛的运用。

单片机以体积小、功能全、性价比高等诸多优点,在工业控制、家用电器、通信设备、信息处理、尖端武器等各种测控领域的应用中独占鳌头,单片机开发技术已成为电子信息、电气、通信、自动化、机电一体化等专业技术人员必须掌握的技术。

而电子万年历作为电子类小设计不仅是市场上的宠儿,也是是单片机实验中一个很常用的题目。

因为它有很好的开放性和可发挥性,因此对作者的要求比较高,不仅考察了对单片机的掌握能力更加强调了对单片机扩展的应用。

而且在操作的设计上要力求简洁,功能上尽量齐全,显示界面也要出色。

1.2 课程设计内容利用单片机、时钟芯片DS1302温度传感器DS18B20 16O2液晶屏等实现日期、时间、温度的显示,即是一个电子时钟。

基于c51功能最全的电子钟程序(lcd1602)

基于c51功能最全的电子钟程序(lcd1602)

功能最全的电子钟【单片机】c51数字时钟(带年月日显示)摘要:本设计以单片机为核心,lcd1602显示。

采用独立键盘输入能任意修改当前时间日期和设定闹钟时间。

具有显示年月日(区分闰年和二月),闹钟报警和整点报时功能主程序:/********************************************************************************************************************************************************************************* ****************************************** lcd1602电子钟********************************************************************************************************************************** *************************************************************************************************** ********************/# include <reg52.h># include "lcd16024.h"sbit key1 = P2^0; //调整sbit key2 = P2^1; //加1sbit key3 = P2^2; //减1sbit speaker = P2^3; //蜂鸣器sbit key4 = P2^4; //闹钟设计bit cal_year = 1; //进入判断闰年标志位bit leap_year; //闰年标志位bit calculate = 0; //日加一标记bit run = 0; //闹钟标志bit beep = 0; //整点报时标志//uint8 num = 0; //调整是给的脉冲uint8 code str1[] = "D: ";uint8 code str2[] = "T: ";uint8 code str3[] = "Wek";uint8 daystr[]="2013-07-29 "; //年月日格式uint8 timestr[]="21:30:59 N"; //时分秒格式uint8 daystr1[]="2013-07-29 "; //闹钟年月日格式uint8 timestr1[]="21:30:59 N"; //闹钟时分秒格式uint8 numweek = 0; //星期加1标记char week = 1; //星期char sec = 53; //秒char min = 50; //分char hour = 23; //时uint8 day = 30; // 日uint8 month = 9; //月uint16 year = 2013; //年char week1 = 1; //闹钟星期char sec1 = 58; //闹钟秒char min1 = 50; //闹钟分char hour1 = 23; //闹钟时uint8 day1 = 30; //闹钟日uint8 month1 = 9; //闹钟月uint16 year1 = 2013; //闹钟年uint8 WeekData1; //闹钟星期标记uint8 number = 0; //定时uint8 WeekData; //星期标记uint8 speaker_num; //整点报时次数uint8 scan_key(void); //函数声名/****************************************************************************** ***************************** 更新LCD时间分离读取******************************************************************************************************************* *******/void TimeChange(){//时分秒timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';timestr[4] = min%10+'0';timestr[3] = min/10+'0';timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';//年月日daystr[9] = day%10+'0';daystr[8] = day/10+'0';daystr[6] = month%10+'0';daystr[5] = month/10+'0';daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';//星期WeekData = week+'0';}/****************************************************************************** ***************************** 闹钟更新LCD时间分离读取******************************************************************************************************************* *******/void TimeChange1(){//时分秒timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';//年月日daystr1[9] = day1%10+'0';daystr1[8] = day1/10+'0';daystr1[6] = month1%10+'0';daystr1[5] = month1/10+'0';daystr1[3] = year1%10+'0';daystr1[2] = year1/10%10+'0';daystr1[1] = year1/100%10+'0';daystr1[0] = year1/1000+'0';//星期WeekData1 = week1+'0';}/****************************************************************************** ***************************** 初始化系统定时器0 ******************************************************************************************************************* *******/void systimer0_init(void){TMOD |=0x01;//设置为1时用或(|)TMOD &=0xfd;//设置为0时用与(&)TH0 = 0xDC; // 定时10msTL0 = 0x00;EA = 1;ET0=1;TR0=1;EX0 = 1;}/****************************************************************************** ***************************** 闹钟时间设置*************************************************************************************************************** *******/void naozhong(){uint8 number = 1;uint8 a = 0;uint8 b = 0;if(0 == key4){Delay1Ms(5);if(0 == key4){a = 1;LCD_write_command(0xc0+9);LCD_write_command(0x0f);}while(!key4);}while(a){if(0 == key4){Delay1Ms(5);if(0 == key4){a = 0;run = ~run;while(!key4);}}if(run){timestr[9] = 'Y';}else{timestr[9] = 'N';}if(0 == key1){Delay1Ms(5);if(0 == key1){b = 1;}while(!key1);}while(b){if(0 == key1){Delay1Ms(5);if(0 == key1){number++;if(4 == number)b = 0;}while(!key1);if(number == 1){LCD_write_command(0xc0+9);LCD_write_command(0x0f);}if(number == 2){LCD_write_command(0xc0+6);LCD_write_command(0x0f);}if(number == 3){LCD_write_command(0xc0+3);LCD_write_command(0x0f);}}}switch(number){case 1:if(0 == key2) //闹钟秒加1的设置{Delay1Ms(5);if(0 == key2){sec1++;if(60 == sec1){sec1 = 0;}while(!key2);timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';LCD_write_char(8,1,timestr1[6]);LCD_write_char(9,1,timestr1[7]);LCD_write_command(0xc0+9);}}if(0 == key3) //闹钟秒减1的设置Delay1Ms(5);if(0 == key3){sec1--;if(sec1 < 0){sec1 = 59;}while(!key3);timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';LCD_write_char(8,1,timestr1[6]);LCD_write_char(9,1,timestr1[7]);LCD_write_command(0xc0+9);}}break;case 2:if(0 == key2) //闹钟分加1的设置{Delay1Ms(5);if(0 == key2){min1++;if(60 == min1){min1 = 0;}while(!key2);timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';;LCD_write_char(5,1,timestr1[3]);LCD_write_char(6,1,timestr1[4]);LCD_write_command(0xc0+6);}}if(0 == key3) //闹钟分减1的设置{Delay1Ms(5);if(0 == key3){min1--;if(min1 < 0){min1 = 59;}while(!key3);timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';;LCD_write_char(5,1,timestr1[3]);LCD_write_char(6,1,timestr1[4]);LCD_write_command(0xc0+6);}}break;case 3:if(0 == key2) //闹钟时加1的设置{Delay1Ms(5);if(0 == key2){hour1++;if(24 == hour1){hour1 = 0;}while(!key2);timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';LCD_write_char(2,1,timestr1[0]);LCD_write_char(3,1,timestr1[1]);LCD_write_command(0xc0+3);}}if(0 == key3) //闹钟时减1的设置{Delay1Ms(5);if(0 == key3){hour1--;if(hour1 < 0){hour1 = 23;}while(!key3);timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';LCD_write_char(2,1,timestr1[0]);LCD_write_char(3,1,timestr1[1]);LCD_write_command(0xc0+3);}}break;case 4:b = 0;LCD_write_command(0x0c);break;}}}LCD_write_command(0x0c);while(!key4);}/****************************************************************************** ***************************** 判断按键进入时间调整*************************************************************************************************************** *******/uint8 scan_key(void){uint8 number = 1;uint8 a = 0;if(0 == key1){Delay1Ms(5);if(0 == key1){while(!key1);a = 1;LCD_write_command(0xc0+9);LCD_write_command(0x0f);}}while(a){if(0 == key1){Delay1Ms(5);if(0 == key1){number++;while(!key1);TR0 = 0;if(number == 2){LCD_write_command(0xc0+6);LCD_write_command(0x0f);}if(number == 3){LCD_write_command(0xc0+3);LCD_write_command(0x0f);}if(number == 4){LCD_write_command(0x80+11);LCD_write_command(0x0f);}if(number == 5){LCD_write_command(0x80+8);LCD_write_command(0x0f);}if(number == 6){LCD_write_command(0x80+5);LCD_write_command(0x0f);}if(number == 7){LCD_write_command(0xc0+14);LCD_write_command(0x0f);}if(8 == number){LCD_write_command(0x0c);a = 0;number = 0;}}}switch(number){case 1:if(0 == key2) //秒加1的设置{Delay1Ms(5);if(0 == key2){sec++;if(60 == sec){sec = 0;}timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';LCD_write_char(8,1,timestr[6]);LCD_write_char(9,1,timestr[7]);LCD_write_command(0xc0+9);while(!key2);}}if(0 == key3) //秒减1的设置{Delay1Ms(5);if(0 == key3){sec--;if(sec < 0){sec = 59;}timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';LCD_write_char(8,1,timestr[6]);LCD_write_char(9,1,timestr[7]);LCD_write_command(0xc0+9);while(!key3);}}break;case 2:if(0 == key2) //分加1的设置{Delay1Ms(5);if(0 == key2){min++;if(60 == min){min = 0;}timestr[4] = min%10+'0';timestr[3] = min/10+'0';;LCD_write_char(5,1,timestr[3]);LCD_write_char(6,1,timestr[4]);LCD_write_command(0xc0+6);while(!key2);}}if(0 == key3) //分减1的设置{Delay1Ms(5);if(0 == key3){min--;if(min < 0){min = 59;}timestr[4] = min%10+'0';timestr[3] = min/10+'0';LCD_write_char(5,1,timestr[3]);LCD_write_char(6,1,timestr[4]);LCD_write_command(0xc0+6);while(!key3);}}break;case 3:if(0 == key2) //时加1的设置{Delay1Ms(5);if(0 == key2){hour++;while(!key2);if(24 == hour){hour = 0;}timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';LCD_write_char(2,1,timestr[0]);LCD_write_char(3,1,timestr[1]);LCD_write_command(0xc0+3);}}if(0 == key3) //时减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);hour--;if(hour < 0){hour = 23;}timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';LCD_write_char(2,1,timestr[0]);LCD_write_char(3,1,timestr[1]);LCD_write_command(0xc0+3);}}break;case 4:if(0 == key2) //日加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);calculate = 1;if(calculate == 1){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;if(day > 31){day=1;}}if(month==4|month==6|month==9|month==11){day++;if(day > 30){day=1;}}if(month == 2){cal_year = 1;while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day++;if(day > 30){day=1;}}else{day++;if(day > 29){day=1;}}}calculate = 0;}daystr[9] = day%10+'0';daystr[8] = day/10+'0';LCD_write_char(10,0,daystr[8]);LCD_write_char(11,0,daystr[9]);LCD_write_command(0x80+11);}}if(0 == key3) //日减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);calculate = 1;if(calculate == 1){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day--;if(day == 0){day=31;}}if(month==4|month==6|month==9|month==11){day--;if(day == 0){day=30;}}if(month == 2){cal_year = 1;while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day--;if(day == 0){day=30;}}else{day--;if(day == 0){day=29;}}}calculate = 0;}daystr[9] = day%10+'0';daystr[8] = day/10+'0';LCD_write_char(10,0,daystr[8]);LCD_write_char(11,0,daystr[9]);LCD_write_command(0x80+11);}}break;case 5:if(0 == key2) //月加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);month++;if(13 == month){month = 1;}daystr[6] = month%10+'0';daystr[5] = month/10+'0';LCD_write_char(7,0,daystr[5]);LCD_write_char(8,0,daystr[6]);LCD_write_command(0x80+8);}}if(0 == key3) //月减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);month--;if(month == 0){month = 12;}daystr[6] = month%10+'0';daystr[5] = month/10+'0';LCD_write_char(7,0,daystr[5]);LCD_write_char(8,0,daystr[6]);LCD_write_command(0x80+8);}}break;case 6:if(0 == key2) //年加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);year++;}daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';LCD_write_char(2,0,daystr[0]);LCD_write_char(3,0,daystr[1]);LCD_write_char(4,0,daystr[2]);LCD_write_char(5,0,daystr[3]);LCD_write_command(0x80+5);}if (0 == key3) //年减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);year--;if(year == 0){year = 2020;}daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';LCD_write_char(2,0,daystr[0]);LCD_write_char(3,0,daystr[1]);LCD_write_char(4,0,daystr[2]);LCD_write_char(5,0,daystr[3]);LCD_write_command(0x80+5);}}break;case 7:if(0 == key2) //星期加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);week++;if(7 == week){week = 0;}LCD_write_char(14,1,week+'0');LCD_write_command(0xc0+14);}}if (0 == key3) //星期减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);week--;if(week < 0){week = 6;}LCD_write_char(14,1,week+'0');LCD_write_command(0xc0+14);}}break;case 8:TR0 = 1;break;}}}/****************************************************************************** ***************************** 主函数******************************************************************************************************************* *******/void main(void){systimer0_init();LCD_init();LCD_write_str(0,0,str1);LCD_write_str(0,1,str2);LCD_write_str(13,0,str3);speaker = 0;while (1){TimeChange();scan_key();naozhong();LCD_write_str(2,0,daystr);LCD_write_str(2,1,timestr);LCD_write_char(14,1,WeekData);if(1 == run){if(sec==sec1 & month==month1 & hour==hour){speaker_num =30;beep = 1;}}else{speaker_num =0;beep = 0;}}}/****************************************************************************** ***************************** 定时中断0 ******************************************************************************************************************* *******/void time_0() interrupt 1{TH0 = 0xDC; // 定时10msTL0 = 0x00;number++;if(number ==100){sec++;if(beep){speaker=!speaker;speaker_num--;if(speaker_num == 0){beep=0;speaker = 0;}}if(sec == 60){sec = 0;min++;if(min == 60){min = 0;hour++; //小时加1speaker_num = hour%12; //蜂鸣器响的次数beep = 1;if(hour == 24){hour = 0;calculate = 1;if(calculate == 1) //判断这个月有多少天{if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;if(month==7|month==12){week++;if(7 == week){week = 0;}}else{if(day <= 31){week++;if(7 == week){week = 0;}}}if(day > 31){if(month==7|month==12){day = 1;}else{day=0;}month++;if(month > 12){month=1;year++;cal_year=1;}}}if(month==4|month==6|month==9|month==11) {day++;week++;if(7 == week){week = 0;}if(day > 30){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}if(month == 2){while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day++;if(day <= 30){week++;if(7 == week){week = 0;}}if(day > 30){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}else{day++;week++;if(7 == week){week = 0;}if(day > 29){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}}}calculate=0;}}}}}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Lcd1602.c子程序:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /****************************************************************************** ***************************** lcd1602低层函数********************************************************************************************************************* *******/# include <reg52.h># include <intrins.h># include "lcd16024.h"# define LCD_DATA P0 //LCD1602的数据口定义sbit LCD_RS = P0^0; //LCD1602控制线的定义,4位控制方式sbit LCD_RW = P0^1;sbit LCD_EN = P0^2;/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void Delay1Us(uint16 n){for(;n>0;n--){_nop_();}}/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void Delay1Ms(uint16 n){while(n--){Delay1Us(1000);}}/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void LCD_en_write(void){LCD_EN=0;LCD_EN=1;Delay1Us(1);LCD_EN=0;}/****************************************************************************** ************************ LCD写一个字节命令函数************************************************************************************************************ *******/void LCD_write_command(uint8 command){Delay1Us(16);LCD_RS=0;LCD_RW=0;LCD_DATA&=0x0f;LCD_DATA|=command&0xf0;LCD_en_write();command=command<<4;LCD_DATA&=0x0f;LCD_DATA|=command&0xf0;LCD_en_write();}/****************************************************************************** ********************** LCD写一个字节数据函数*************************************************************************************************************** *******/void LCD_write_data(uint8 Data){Delay1Us(16);LCD_RS=1;LCD_RW=0;LCD_DATA&=0x0f;LCD_DATA|=Data&0xf0;LCD_en_write();Data=Data<<4;LCD_DATA&=0x0f;LCD_DATA|=Data&0xf0;LCD_en_write();}/****************************************************************************** ***************************** LCD1602光标定位函数************************************************ x--列0~15;y--行0~1********************************************************************************************************* *******/void LCD_set_xy(uint8 x,uint8 y){uint8 address;if(y==0)address=0x80+x;else address=0xc0+x;LCD_write_command(address);}/***************************************************************************************************** LCD1602 初始化函数,四位显示方式******************************************************************************************************* *******/void LCD_init(){LCD_write_command(0x28);// Delay1Us(40);LCD_write_command(0x28);LCD_write_command(0x0c);LCD_write_command(0x01);LCD_write_command(0x06);Delay1Ms(2);}/****************************************************************************** ***************************** LCD写字符串函数******************************************************* x--列0~15;y--行0~1******************************************************* s指向字符串数组**************************************************************************************************************** *******/void LCD_write_str(uint8 x,uint8 y,uint8 *s){LCD_set_xy(x,y);while(*s){LCD_write_data(*s);s++;}}/****************************************************************************** ***************************** LCD写一个字符函数******************************************************* x--列0~15;y--行0~1******************************************************* d--字符的ASCII码**************************************************************************************************************** *******/void LCD_write_char(uint8 x,uint8 y,uint8 d){LCD_set_xy(x,y);LCD_write_data(d);}/*////////////////////////////////////////////////////////////////// 等待繁忙标志/////////////////////////////////////////////////////////////////void LCD_wait(void){P0 = 0xFF;do{LCD_RS = 0;LCD_RW = 1;LCD_EN = 0;LCD_EN = 1;}while (BUSY == 1);LCD_EN = 0;}*//****************************************************************************** ***************************** LCD1602左移********************************************************************************************************************* *******void LCD_youyi(uint8 y,uint8 *s){LCD_write_str(17,y,s);for(a=0;a<16;a++){LCD_write_command(0x1c); //左移LCD_write_command(0x1c); 为右移Delay1Ms(6);}}*///LCD_write_command(0x0d);//光标闪烁//LCD_write_command(0x0e);//光标显示不闪烁//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Lcd1602.h头文件////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _LCD16024_H_#define _LCD16024_H_typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;void Delay1Us(uint16 n);void Delay1Ms(uint16 n);void LCD_write_data(uint8 dat);void LCD_write_command(uint8 com); //BuysC为0时忽略忙检测void LCD_set_xy(uint8 x,uint8 y);void LCD_en_write(void);void LCD_write_char(uint8 x, uint8 y, uint8 Data1);void LCD_write_str(uint8 x, uint8 y,uint8 *s);void LCD_init();//void LCD_wait(void);//void LCD_youyi(uint8 y,uint8 *s);#endif。

基于DS1302和LCD1602的数字电子钟设计

基于DS1302和LCD1602的数字电子钟设计

关键词:单片机;DS1302;LCD1602;数字时钟
1
Abstract
This paper mainly introduces the hardware and software design of digital electronic clock which is made up of the AT89S52 MCU ,DS1302 clock chip and LCD1602 module .It can accurately adjust the information of the year,month,day,hour,minutes and seconds.This electronic clock has the characteristics of working accurately,keeping the time date when system losing power, and low power consumptions. Keywords: singlechip;DS1302;LCD1602;Digital clock
图(3)系统硬件连接原理图
8
三.系统软Leabharlann 设计[3]软件是单片机应用系统的灵魂,是整个系统的核心部分。如果把硬件比作人的手臂那么 软件就是人的大脑,手臂的一切动作的执行都要受控于大脑。同样,对 DS1302 时钟芯片和 1602 液晶显示模块的操作都是通过相应的软件程序来控制的。 3.1 DS1302 读写程序 任何一款数字芯片都有自己的操作时序,只有完全按照芯片厂商提供的操作时序进行编 程才可以使其正常工作。DS1302 的读写时序如图(4)所示。 按照此时序图编制的写操作程序如下:
2
一.引言
1.DS1302 时钟芯片简介[1]

基于单片机的lcd1602电子时钟设计

基于单片机的lcd1602电子时钟设计

基于单片机的LCD1602电子时钟设计一、设计任务和目的1.1、设计任务(1):用单片机设计基于LCD1602的电子时钟,显示时间和日期;(2):误差精度控制在1s/天;(3):具有时间和日期的校准功能;(4):能区分某年是闰年或平年,并对应显示2月份的天数;(5):根据月份的不同显示不同的最大日数;(6):搭建仿真电路图,模拟单片机要实现的功能;(7):焊接单片机开发板;(8):编写程序,下载并调试,实现要求的功能。

1.2、设计目的(1):熟练掌握KEIL软件的使用方法;(2):熟练掌握PROTEUS软件的使用方法;(3):掌握单片机I/O接口的工作原理;(4):掌握LCD显示器的工作原理及编程方法;(5):掌握独立式键盘的工作原理及编程使用方法;(6):掌握单片机的下载使用方法。

二、设计思路和方案论证2.1、设计思路电路总体上分为控制和显示部分。

以单片机最小系统作为核心控制电路,控制LCD显示,具体显示内容及方式由软件来完成;由于有时钟和日期的调节功能需要校准电路和基本的复位电路,复位电路采用按键复位,调节键、加1键、减1键三个按键完成,共需四个按键;计时功能由固定频率的晶振完成(采用11.0592MHz);显示部分主要采用LCD1602作为显示。

2.2、方案论证(1):时钟芯片的选择和论证方案一:采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、月、年以及闰年补偿的年进行计数,精度也较高,工作电压2.5V~5.5V范围内,功耗也较低,但价格比较贵。

方案二:直接采用单片机定时计数器提供秒信号,使用程序实现秒、分、时、日、月、年计数。

采用此方案实现虽然有一定的时间误差,但可减少芯片的使用,节约成本,易于实现,符合现实选用,所以采用此种作为时钟信号发生器。

(2):显示模块选择方案和论证:方案一:采用点阵式图形LCD12864液晶显示屏,液晶显示屏的显示功能强大,可显示文字,图形,显示多样,清晰可见,但是价格昂贵,需要的接口线多,所以在此设计中不采用点阵式图形LCD12864液晶显示屏。

用1602LCD设计的可调式电子钟

用1602LCD设计的可调式电子钟

单片机应用课程设计说明书用1602LCD设计的可调式电子钟专业自动化学生姓名班级自动化142学号 14100指导教师蒋完成日期 20年1 月23 日目录1 概述 (3)2 课题研究背景与意义 (3)2.1 课题研究背景 (3)2.2 课题研究意义 (3)3 系统方案设计与主要设计工作 (3)3.1 设计任务 (3)3.2 功能要求说明 (4)4设计课题总体方案 (4)4.1硬件设计方案 (5)4.2系统软件设计 (7)5. 软件仿真及实物设计调试 (9)5.1PROTUES仿真软件介绍 (9)5.2仿真运行结果说明 (10)5.3实物设计结果与调试 (11)6课程设计实验总结 (11)参考文献 (13)附录 (14)附录1:程序清单 (14)附录2:系统电路原理图 (21)附录3:元器件清单 (22)用1602LCD设计电子钟1 概述数字钟是采用数字电路实现对“时”、“分”、“秒”数字显示的计时装置。

数字钟的精度、稳定度远远超过老式机械钟。

在这次设计中,我们采用LED数码管显示时、分、秒,以24小时计时方式,根据数码管动态显示原理来进行显示,用12MHz的晶振产生振荡脉冲,定时器计数。

在此次设计中,电路具有显示时间的其本功能,还可以实现对时间的调整。

数字钟是其小巧,价格低廉,走时精度高,使用方便,功能多,便于集成化而受广大消费的喜爱,因此得到了广泛的使用。

2 课题研究背景与意义2.1 课题研究背景20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。

目前,单片机正朝着高性能和多品种方向发展趋势将是进一步向着CMOS化、低功耗、小体积、大容量、高性能、低价格和外围电路内装化等几个方面发展。

下面是单片机的主要发展趋势。

单片机应用的重要意义还在于,它从根本上改变了传统的控制系统设计思想和设计方法。

基于LCD1602的电子时钟和温度计的设计

基于LCD1602的电子时钟和温度计的设计

基于LCD1602的电子时钟和温度计的设计目录摘要...................................................... 错误!未定义书签。

Abstract ................................................... 错误!未定义书签。

第一章绪论. (1)1.1 开发背景及研究意义 (1)1.1.1 LCD数字温度计的研究背景及研究意义 (1)1.1.2 LCD电子钟电路的研究背景及研究意义 (1)1.2 研究进展及成果 (2)1.2.1 LCD数字温度计的研究进展及成果 (2)1.2.2 LCD电子钟的研究进展及成果 (3)1.3 课题来源与主要容和技术参数 (3)1.3.1 课题来源 (3)1.3.2 课题的主要容和技术参数 (4)1.4 主要工作和工作难点 (5)第二章系统的总体结构 (6)2.1 系统的总体设计方案 (6)2.1.1 设计总体设计思路 (6)2.1.2 方案论证 (6)2.1.3 功能介绍 (7)2.2 设计思路步骤 (8)2.2.1 下载线部分的设计 (8)2.2.2 LCD电子时钟系统的设计 (8)2.2.3 LCD数字温度计系统的设计 (9)2.3 本章小结 (10)第三章硬件电路设计 (11)3.1 下载线电路的设计 (11)3.1.1 主要器件简介 (11)3.1.2 MAX232电平转换电路的设计 (12)3.1.3 监控电路的设计 (13)3.2 LCD电子时钟系统的设计 (14)3.2.1 主要器件简介 (14)3.2.2 蜂鸣器电路的设计 (15)3.2.3 DS1302电路的设计 (16)3.2.4 按键电路的设计 (17)3.2.5 单片机与液晶屏LCD1602的接口电路 (17)3.3 LCD数字温度计系统的设计 (18)3.3.1 主要器件介绍 (18)3.3.2 LCD数字温度计的设计 (20)3.4 AVR单片机最小系统的设计 (22)3.4.1 系统时钟 (22)3.4.2 AVR的复位源和复位方式 (24)3.5 本章小结 (27)第四章软件设计 (28)4.1 概述 (28)4.2 系统软件开发环境 (28)4.3 软件程序设计 (30)4.3.1 监控程序流程图及ATtiny2313监控程序通信协议 (30)4.3.2 ATmega16单片机串行编程 (32)4.3.3 LCD电子时钟流程图设计 (33)4.3.4 LCD数字温度计流程图设计 (36)4.4 本章小结 (39)第五章仿真与调试 (40)5.1 系统仿真 (40)5.1.1 Proteus软件简介 (40)5.1.2 系统仿真 (41)5.2 程序下载及实物调试 (47)5.3 本章小结 (51)结论 (52)参考文献 (53)致谢........................................................ 错误!未定义书签。

单片机实验报告 ——LCD1602显示时钟

单片机实验报告 ——LCD1602显示时钟

XXXX学院实验报告Experimentation Report of Taiyuan Normal University系部计算机年级大三课程单片机原理与接口技术姓名同组者日期学号项目 LCD1602显示时钟一、实验目的1、了解单片机顺序执行的特点;2、掌握C语言的编写和keilc51的使用;3、熟悉DS1302芯片的工作过程二、实验仪器硬件资源:单片机开发板笔记本电脑 DS1302芯片;软件资源:软件 Keil uVision5;三、实验原理1、流程图2、连接图四、实验结果将LCD屏连接到单片机上,点击编译运行,LCD屏上显示时间:2013-01-01 2 12-00-38。

在DS1302.c文件里修改uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01,0x02, 0x13};为uchar TIME[7] = {0x14, 0x11, 0x19, 0x28, 0x11,0x04, 0x19};点击编译运行按钮,LCD屏幕显示2019-11-28 4 19-11-14。

四、实验代码及分析//主函数void main(){Ds1302Init(); //初始化DS1302LcdInit(); //初始化LCDwhile(1){Ds1302ReadTime(); //DS1302读时间LcdDisplay(); //LCD显示时间}}//初始化DS1302void Ds1302Init(){uchar n;Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能for (n=0; n<7; n++) //写入7个字节的时钟信号:分秒时日月周年{Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);}Ds1302Write(0x8E,0x80); //打开写保护功能}//读取时钟信息void Ds1302ReadTime(){uchar n;for (n=0; n<7; n++) //读取7个字节的时钟信号:分秒时日月周年{TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);}}//---DS1302写入和读取时分秒的地址命令---////---秒分时日月周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。

基于1602液晶的电子时钟设计

基于1602液晶的电子时钟设计

2012 ~ 2013 学年第2 学期《单片机原理及应用》课程设计报告题目:基于1602液晶的电子时钟设计专业:自动化班级:电气工程系2011年5月12日1、任务书课题名称基于1602液晶的电子时钟设计指导教师(职称)执行时间2012~2013 学年第2学期第10 周学生姓名学号承担任务摘要电子时钟在日常生活和工农业生产中是必不可少的。

所以本文利于89C51单片机作为核心控制芯片,设计了一款基于1602LCD液晶显示的电子时钟。

该时钟具有键盘控制的暂停和启动,时钟、分钟和秒钟的手动调节功能;同时具备到整时(如1点整,2点整)时蜂鸣器发出“滴答”声,并且一个发光二极管发出闪烁。

所以设计最后在Protues仿真软件上仿真,验证该设计的正确性,关键词:电子时钟,LCD1602液晶,仿真。

基于1602液晶的电子时钟设计目录摘要 (2)绪论 (4)第一章设计要求与方案论证 (5)1.1 设计要求 (5)1.2 系统基本方案选择 (5)1.2.1 单片机芯片的选择方案 (5)1.2.2 显示模块选择方案 (5)1.2.3 时钟的控制方案 (5)1.3 电路设计最终方案决定 (5)第二章主要元件介绍 (7)2.1 单片机STC89C52介绍 (7)2.1.1 STC89C52主要功能 (7)2.1.2 STC89C52引脚介绍 (7)2.1.3 STC89C52最小系统 (9)2. 2 1602字符液晶介绍 (10)2.2.1 1602液晶概述 (10)2.2.2 1602引脚介绍 (10)2.2.3 1602字符液晶使用方法 (11)第三章系统硬件设计 (13)3.1 单片机控制系统 (13)3.2.各部分功能实现 (13)3.2.1.控制部分(STC89C52) (13)3.2.2键盘控制系统设计 (14)3.2.3.显示电路 (14)3.2.4.整点提醒电路 (15)3.3. 总电路原理图 (16)第四章软件设计及仿真 (17)4.1 软件主要要完成的功能 (17)4.2软件设计的主要流程 (17)4.3 仿真显示效果 (18)总结 (19)参考文献 (20)附录 (21)绪论20世纪末,电子技术获得了飞速发展,在其推动下,现代电子产品几乎深入到社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也是现代产品性能进一步提高,产品更新换代的节奏也越来越快。

基于单片机的LCD1602电子时钟设计

基于单片机的LCD1602电子时钟设计

基于单片机的LCD1602电子时钟设计近年来,随着物联网和智能设备的快速发展,电子时钟作为一种常见的智能设备,广泛应用于家庭、办公室等各种场合。

本文将基于单片机设计一款LCD1602电子时钟,实现时间显示、闹钟设置等功能。

一、硬件设计1.单片机选择在本设计中,选择常用的51系列单片机AT89C51,具有丰富的外设资源和强大的处理能力。

该单片机具有8位数据总线、16位地址总线,并且集成了定时/计数器、中断控制器和串行通信接口等外设。

2.显示模块选择3.时钟模块选择通过接入DS1302时钟模块,可以实现实时时钟的功能。

DS1302模块具有时钟计数器、电压检测电路、串行通信接口等,并且具有低功耗特点。

4.控制板设计根据LCD1602的引脚连接方式,设计一个控制板,用于将单片机、显示模块和时钟模块等连接在一起。

同时,需注意设计供电电路、外设输入输出电平等电路。

二、软件设计1.初始化设置通过单片机的GPIO口配置,将LCD1602和DS1302对应的引脚设置为输出模式,同时初始化LCD显示屏并进行清屏操作。

此外,需设置DS1302时钟模块的时钟、日期、闹钟等参数。

2.时间显示通过读取DS1302时钟模块的计数器,获得当前的小时、分钟和秒数,然后将其格式化为HH:MM:SS的形式,并通过LCD显示出来。

3.时间设置通过单片机的外部中断,当用户按下设置按钮后,进入时间设置模式。

在时间设置模式下,用户可以通过按下不同的按键来调整小时、分钟和秒数。

调整完成后,再次按下设置按钮即可保存设置。

4.闹钟设置通过单片机的定时器中断,设定一个闹钟定时器。

当闹钟定时器触发时,触发相应的中断,然后通过LCD显示闹钟提示。

此外,用户也可以通过按下按钮来设置闹钟时间,并通过单片机的外部中断进行处理。

5.闹钟响铃当闹钟时间到达时,触发相应的中断,通过LCD显示闹钟提示,并通过蜂鸣器发出响铃声。

总结通过本设计,可以实现一款功能齐全的LCD1602电子时钟。

基于单片机的1602电子时钟设计

基于单片机的1602电子时钟设计

基于单片机的1602电子时钟设计一.实验目的:(1)用单片机设计基于单片机的1602电子时钟显示;(2)熟练掌握Keil软件;(3)熟练掌握Proteus软件仿真;(4)掌握单片机的I/O接口的工作原理;(5)掌握LCD显示器的原理和编程方法;(6)掌握独立式键盘的工作原理和编程方法;(7)掌握单片机下载方法;二.实验要求(1)可实现时钟显示(2)可调整时间三.实验内容(1)画仿真图如图1图1(2)编写程序(3)下载运行(4)运行结果,分析其中的错误四.程序(一)#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit LCD_RS=P2^0;sbit LCD_RW=P2^1 ;sbit LCD_EN=P2^2;void Delay_ms(uint xms) ;bit lcd_busy();void lcd_wcmd(uchar cmd);void lcd_wdat(uchar dat) ;void lcd_clr() ;void lcd_init() ;/********以下是延时函数********/void Delay_ms(uint xms){uint i,j;for(i=xms;i>0;i--) //i=xms即延时约xms毫秒for(j=110;j>0;j--);}/********以下是LCD忙碌检查函数********/bit lcd_busy(){bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;_nop_(); _nop_(); _nop_(); _nop_();result = (bit)(P0&0x80);LCD_EN = 0;return result;}/********以下是写指令寄存器IR函数********/void lcd_wcmd(uchar cmd){while(lcd_busy());LCD_RS = 0; LCD_RW = 0; LCD_EN = 0;_nop_(); _nop_();P0 = cmd;_nop_(); _nop_(); _nop_(); _nop_();LCD_EN = 1;_nop_(); _nop_(); _nop_(); _nop_();LCD_EN = 0;}/********以下是写寄存器DR函数********/void lcd_wdat(uchar dat){while(lcd_busy());LCD_RS = 1; LCD_RW = 0; LCD_EN = 0;P0 = dat;_nop_(); _nop_(); _nop_(); _nop_();LCD_EN = 1;_nop_(); _nop_(); _nop_(); _nop_();LCD_EN = 0;}/********以下是LCD清屏函数********/void lcd_clr(){lcd_wcmd(0x01); //清除LCD的显示内容Delay_ms(5);}/********以下是LCD初始化函数********/void lcd_init(){Delay_ms(15); //等待LCD电源稳定lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据Delay_ms(5);lcd_wcmd(0x38);Delay_ms(5);lcd_wcmd(0x38);Delay_ms(5);lcd_wcmd(0x0c); //显示开,关光标Delay_ms(5);lcd_wcmd(0x06); //移动光标Delay_ms(5);lcd_wcmd(0x01); //清除LCD的显示内容Delay_ms(5);}(二)#include <reg51.h>#include "LCD_drive.h"#define uchar unsigned char#define uint unsigned intuchar year=12,mon=10,day=10,hour=12,min=00,sec=00;uchar count_10ms;sbit k7=P3^0; sbit k1=P3^2; sbit k2=P3^3; sbit k3=P3^4;sbit k4=P3^5; sbit k5=P3^6; sbit k6=P3^7; bit k1_flag=0;uchar code line1_data[] = {"----"};uchar code line2_data[] = {"****"};uchardisp_buf[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; void LCD_conv(char in1,in2,in3,in4,in5,in6){disp_buf[0]=in1/10+0x30; disp_buf[1]=in1%10+0x30; disp_buf[2]=in2/10+0x30; disp_buf[3]=in2%10+0x30; disp_buf[4]=in3/10+0x30; disp_buf[5]=in3%10+0x30; disp_buf[6]=in4/10+0x30; disp_buf[7]=in4%10+0x30; disp_buf[8]=in5/10+0x30; disp_buf[9]=in5%10+0x30; disp_buf[10]=in6/10+0x30; disp_buf[11]=in6%10+0x30; }void LCD_disp(){lcd_wcmd(0x04|0x80);lcd_wdat(disp_buf[0]); lcd_wdat(disp_buf[1]);lcd_wdat(0xb0);lcd_wdat(disp_buf[2]); lcd_wdat(disp_buf[3]);lcd_wdat(0xb0);lcd_wdat(disp_buf[4]); lcd_wdat(disp_buf[5]);lcd_wcmd(0x44|0x80);lcd_wdat(disp_buf[6]); lcd_wdat(disp_buf[7]);lcd_wdat(0x3a);lcd_wdat(disp_buf[8]); lcd_wdat(disp_buf[9]);lcd_wdat(0x3a);lcd_wdat(disp_buf[10]); lcd_wdat(disp_buf[11]);}void timer1() interrupt 3{TH1=0xdc; TL0=0x00;count_10ms++;if(count_10ms>=100){count_10ms=0; sec++;if(sec>=60){sec=0; min++;if(min>=60){min=0; hour++;if(hour>=24){hour=0; day++;if(day>=30){day=1; mon++;if(mon>=12){mon=1; year++;} }}} } }}void keyprocess(){TR1=0;if(k2==0){Delay_ms(10);if(k2==0){while(!k2); year++; }}if(k3==0){Delay_ms(10);if(k3==0){while(!k3); mon++;if(mon>12){mon=0;} } }if(k4==0){Delay_ms(10);if(k4==0){while(!k4); day++;if(day>30){day=0;} } }if(k5==0){Delay_ms(10);if(k5==0){while(!k5); hour++;if(hour==24){hour=0;} }}if(k6==0){Delay_ms(10);if(k6==0){while(!k6); min++; if(min==60) {min=0;} }}if(k7==0){Delay_ms(10);if(k7==0){while(!k7);TR1=1; k1_flag=0;} }}void timer1_init(){TMOD=0x10;TH1=0xdc; TL1=0x00;EA=1; ET1 =1; TR1 =1;}void main(){uchar i;P0=0xff; P2=0xff;timer1_init ();lcd_init(); lcd_clr();lcd_wcmd(0x00|0x80);i=0;while(line1_data[i]!='\0'){lcd_wdat(line1_data[i]); i++;}lcd_wcmd(0x0c|0x80); i=0;while(line1_data[i]!='\0'){lcd_wdat(line1_data[i]); i++;}lcd_wcmd(0x40|0x80); i=0;while(line2_data[i]!='\0'){lcd_wdat(line2_data[i]); i++;}lcd_wcmd(0x4c|0x80); i=0;while(line2_data[i]!='\0'){lcd_wdat(line2_data[i]); i++;}while(1){if(k1==0){Delay_ms(10);if(k1==0){while(!k1);k1_flag=1;}}if(k1_flag==1)keyprocess();LCD_conv(year,mon,day,hour,min,sec); LCD_disp();}}。

答辩材料-基于LCD1602的数字钟程序设计(C语言)

答辩材料-基于LCD1602的数字钟程序设计(C语言)

答辩材料一、LCD1602概要LCD1602液晶显示模块是一种字符型显示模块,16引脚,5*7点阵,高电平点亮,可显示2行×16个字符。

LCD1602具有如下特性:⏹+5v电压,对比度可调⏹内含复位电路⏹提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能⏹有80字节显示数据存储器DDRAM⏹内建有160个5*7点阵的字型的字符发生器CGROM⏹8个可有用户自定义的5*7的字符发生器CGRAM二、硬件说明1、单片机最小显示系统;..2、 电源电路;....3、 下载电路;...4、 蜂鸣器电路;5、 LCD 显示电路。

三、 软件说明1、程序流程图:定义第一行要显示的内容···显示第一行要现实的内容···定义第二行要显示的内容···显示第二行要现实的内容···对第一行要显示的内容进行“加减”操作···对第二行要显示的内容进行“加减”操作···在第一行显示内容的基础上进行音乐加载···通过按键切换画面显示内容···2、LCD1602 初始化:0x38 设置16*2显示,5*7点阵,8位数据接口0x08 只开显示0x01 清屏0x0c 开显示,不显示光标0x06 地址加1,当写入数据的时候光标右移3、操作时序四、显示结果通过软硬件结合,最终在LCD显示屏上显示出如下结果:第一步:上电后,可以发现LCD显示板上显示“Come On(第一行)、Baby!(第二行)”。

5秒后,LCD显示板上显示学号“1006043129(第一行)、1006043130(第二行)”;第二步:按键S1(k1)切换画面。

按第一次S1,显示画面:“23:59:50 T(第一行)、2012年12月30日(第二行)”;按第二次S1,显示画面:“23:59:50(第一行)、2012年12月30日D(第二行)”;按第三次S1,显示画面:“1006043129(第一行)、1006043130(第二行)”;然后依次循环······第三步:当LCD显示板上的时间行更新到“00:00:00”时,蜂鸣器播放歌曲“让我们荡起双桨”。

基于51单片机的用 LCD1602 显示时钟的程序

基于51单片机的用 LCD1602 显示时钟的程序

用LCD1602 显示的时钟2012-04-30 15:04有这样一个题目:求一个为51 单片机编写的LCD 电子时钟的设计,简单就好!希望说一下怎么设计这个时钟,都需要些什么东西,最重要的——把这个设计需要的程序写出来。

设计的任务:以单片机控制的时钟,在LCD 显示器上显示当前的时间。

设计的基本要求:1.使用文字型LCD 显示器显示当前时间。

2.显示格式为“时时:分分:秒秒”。

3.用4个功能键操作来设置当前时间。

各个功能键的功能如下:K1:进入设置现在的时间。

K2:设置小时。

K3:设置分钟。

K4:确认完成设置。

4. 程序执行后工作指示灯LED 闪烁,表示程序开始执行,LCD 显示“00:00:00”,然后开始计时。

题目链接:/question/416705477.html//==================================================提到设计时钟,很多人都想到了时钟芯片DS1302,都说它简单、准确。

其实,这是个误区。

仅仅使用一般的单片机,简单的编程,达到相同DS1302 的准确度,并不是难事。

如果不要求计算平闰年、不要求分清大小月、不要求计算星期几,只是要求一个简单的时钟(及日历),用DS1302,就是自寻烦恼。

大家可以打开题目链接,看看其中的一些答案,就可以看出使用DS1302 是多么的繁琐了,简直就是一场噩梦。

做而论道以前就使用普通的单片机和LCD1602 设计过《时钟与日历》,程序设计的非常合理,时间精度就完全取决于晶振的精度。

设计出来的时钟,几个月都差不上一秒。

针对这个题目,做而论道翻出了以前的设计,删节了一些不需要的功能,设计出了符合题目要求的时钟,用PROTEUS 仿真截图如下:程序用C 语言编写,全部代码如下://---------------------------------------------------#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define KEY_IO P3#define LCD_IO P0sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;sbit SPK = P1^2;sbit LED = P2^4;bit new_s, modify = 0;char t0, sec = 50, min = 59, hour = 23;char code LCD_line1[] = "Designed by ZELD"; char code LCD_line2[] = "Timer: 00:00:00 "; char Timer_buf[] = "23:59:50";//---------------------------------------------------void delay(uint z){uint x, y;for(x = z; x > 0; x--) for(y = 100; y > 0; y--);//---------------------------------------------------void W_LCD_Com(uchar com) //写指令{LCD_RS = 0; LCD_IO = com; // LCD_RS和R/W都为低电平时,写入指令LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲}//---------------------------------------------------void W_LCD_Dat(uchar dat) //写数据{LCD_RS = 1; LCD_IO = dat; // LCD_RS为高、R/W为低时,写入数据LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲}//---------------------------------------------------void W_LCD_STR(uchar *s) //写字符串{while(*s) W_LCD_Dat(*s++);}//---------------------------------------------------void W_BUFF(void) //填写显示缓冲区{Timer_buf[7] = sec % 10 + 48; Timer_buf[6] = sec / 10 + 48;Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;Timer_buf[1] = hour % 10 + 48;Timer_buf[0] = hour / 10 + 48;W_LCD_Com(0xc0 + 7); W_LCD_STR(Timer_buf);}//---------------------------------------------------uchar read_key(void){uchar x1, x2;KEY_IO = 255;x1 = KEY_IO;if (x1 != 255) {delay(100);x2 = KEY_IO;if (x1 != x2) return 255;while(x2 != 255) x2 = KEY_IO;if (x1 == 0x7f) return 0;else if (x1 == 0xbf) return 1;else if (x1 == 0xdf) return 2;else if (x1 == 0xef) return 3;else if (x1 == 0xf7) return 4;}return 255;//---------------------------------------------------void Init(){LCD_RW = 0;W_LCD_Com(0x38); delay(50);W_LCD_Com(0x0c);W_LCD_Com(0x06);W_LCD_Com(0x01);W_LCD_Com(0x80); W_LCD_STR(LCD_line1);W_LCD_Com(0xC0); W_LCD_STR(LCD_line2);TMOD = 0x01; //T0定时方式1TH0 = 0x4c;TR0 = 1; //启动T0PT0 = 1; //高优先级, 以保证定时精度ET0 = 1;EA = 1;}//---------------------------------------------------void main(){uint i, j;uchar Key;Init();while(1) {//-------------------------------if (new_s) { //如果出现了新的一秒, 修改时间new_s = 0; sec++; sec %= 60;if(!sec) { min++; min %= 60;if(!min) { hour++; hour %= 24;}}W_BUFF(); //写显示//-------------------------------if (!sec && !min) { //整点报时for (i = 0; i < 200; i++) {SPK = 0; for (j = 0; j < 100; j++);SPK = 1; for (j = 0; j < 100; j++);} }}//-------------------------------Key = read_key(); //读出按键switch(Key) { //分别处理四个按键case 0: modify = 1; break;case 1: if(modify) {min++; min %= 60; W_BUFF(); break;}case 2: if(modify) {hour++; hour %= 24; W_BUFF(); break;}case 3: modify = 0; break;} }}//---------------------------------------------------void timer0(void) interrupt 1 //T0中断函数, 50ms执行一次{TH0 = 0x4c;t0++; t0 %= 20; //20, 一秒钟if(t0 == 0) {new_s = 1; LED = ~LED;}if(modify) LED = 0;}//===================================================呵呵,全部程序,也不过120 行左右。

LCD1602电子时钟设计

LCD1602电子时钟设计

电子时钟设计班级:电子1001姓名:***学号:**********指导老师:***一、实验目的学习利用AT89C52进行任务设计,练习使用52单片机内部的定时器进行计时。

学习ds1302时钟芯片和ds18b20温度传感器的使用。

学习用模块化编程进行较长程序的编写。

二、设计要求:(1)利用lcd1602液晶显示屏作为显示模块,用AT89C52进行控制,要求用ds18b02测量显示即时温度,温度报警,用ds1302时钟芯片为单片机提供时间数据。

具有定时功能。

(2)要求时间和定时时间可调,并且在闹铃报时的时候可以用按键进行关闭。

并且可以用按键关闭打开定时功能。

(3)利用keil uVision4编译软件进行编译。

(4)完成实验要求,写出实验报告。

三、电子元件列表四、工作现象本时钟具有显示年月日时分秒星期、温度和温度报警的功能。

实验用时钟芯片ds1302来提供秒、分、时、星期、日期、月份和年份的数据,显示部分采用液晶显示模块lcd1602,右上方显示星期,左下角显示温度,右下角显示闹铃的开关状态。

用温度传感器ds18b20来测量温度。

另外,闹铃用pxo888音乐芯片来报时,用蜂鸣器做温度报警发声器。

具体各部分功能及操作下面将做介绍:ds1302给单片机at89c52提供年、月、日、时、分、秒、星期,ds18b20采集温度的数据,经单片机的处理送到液晶显示屏lcd1602上显示,实验设置的报警温度为30*c,由于程序有点长,已达到52单片机内存的极限,所以没加调整报警温度的功能,并且在天正时间的过程中能能加,不能减。

现在开始介绍具体的操作步骤:key1为调整时间和日期的按键,按下key1键,lcd1602上的光标按时分星期日月年的顺序进行移动,光标所到处按key3键可以调整相应的数据信息。

Key2键是闹钟调整键,本实验只提供了设置时间来调整闹钟,不设计年月日和星期,按下key2键,光标在时分之间切换,光标所到处按key3调整相应数据。

LCD1602单片机数字钟设计(含附件)

LCD1602单片机数字钟设计(含附件)

基于单片机89C52的液晶数字钟设计摘要设计采用定时计数器工作方式1进行数值上的累加,经过延时程序,lcd1602驱动程序和时间格式转换程序,实现了数字钟的正常运转以及显示。

添加整点报时,用1个if 语句设置整点条件调用蜂鸣器程序实现功能;添加闹钟功能,通过当前时间与闹钟时间的对比促使蜂鸣器发声。

关键词定时计数器 LCD1602 闹钟单片机89C521.电路设计1.1主体设计1.1.1设计原理端,使用P0端要外接上拉电阻,这里放置10k阻值的排阻。

蜂鸣器需要三极管放大后方可使用。

开关用四脚独立按键,接P1端。

使用12MHz的晶振。

1.2各部分设计1.2.1时钟设计单片机的时钟有两种方式产生,分别是内部方式和外部方式。

设计采用内部方式。

产生时钟的是振荡电路。

由一个12MHz的晶振和两个30pF的串联着的电容并联在一起,形成谐振电路。

晶振和电容大小涉及电路振荡频率的稳定性和大小,以及起振响应速度。

1.2.2复位设计复位有两种,区别在于是否有开关。

按一次开关,电位变化形成一次脉冲,使单片机复位。

采用10k电阻和10uF的电解电容。

1.2.3按键设计有三种模式,分别是工作模式,当前时间设置模式,闹铃时间设置模式。

(1)工作模式。

就是正常数字钟功能,有整点报时功能。

(2)当前时间设置模式。

1键进入该模式,之后,1键调时,2键调分,3键确认。

(3)闹铃时间设置模式。

3键进入该模式,之后,1键调时,2键调分,3键确认,4键打开闹铃。

工作模式2键可以查看闹铃时间。

1.2.4lcd1602设计Lcd1602的DB端接单片机的P0端,2和15脚接5v,其他的接地。

加10k排阻,程序正确,电路无差错,可正常使用。

1.2.5蜂鸣器设计蜂鸣器通过三极管放大后使用,作用有闹铃和整点报时的发声。

三极管采用pnp型规格。

1.3软件仿真Proteus 7.5图1.3仿真图图1.4PCB 设计设计仿真用到的器件在此版本软件上都能找到。

基于LCD1602电子时钟课程设计报告

基于LCD1602电子时钟课程设计报告

信息与电子工程学院课程设计报告课程单片机技术应用设计题目基于LCD1602电子时钟专业班级姓名学号分工成绩成员指导老师答辩日期目录一、课程设计概述 (3)1.1课程设计背景 (3)1.2课程设计内容 (3)1.3课程设计技术指标 (3)二、方案的选择及确定 (3)2.1单片机芯片的选择 (3)2.2显示模块的选择 (4)2.3实时时间计算模块的选择 (4)2.4实时环境温度采集模块选择 (4)2.5电路设计最终方案决定 (5)三、系统硬件设计 (5)3.1主控模块 (5)3.2LCD显示模块设计 (6)3.3时间计算模块设计 (6)3.4实时环境温度检测模块 (7)3.5报警模块 (7)3.6设置模块 (8)3.7电源接口部分 (8)四、系统软件设计 (8)4.1主函数 (8)4.2设置模块 (9)4.31602液晶屏 (10)4.4软件原理图 (11)五、系统调试过程 (11)5.1软件调试 (11)5.2硬件调试 (12)六、结论 (12)七、遇到的问题及解决方法和总结 (12)7.1硬件方面 (12)7.2软件方面 (13)7.3总结 (13)八、参考文献 (13)九、附录 (14)一、课程设计概述1.1 课程设计背景随着微电子技术的高速发展,单片机在国民经济的个人领域得到了广泛的运用。

单片机以体积小、功能全、性价比高等诸多优点,在工业控制、家用电器、通信设备、信息处理、尖端武器等各种测控领域的应用中独占鳌头,单片机开发技术已成为电子信息、电气、通信、自动化、机电一体化等专业技术人员必须掌握的技术。

而电子万年历作为电子类小设计不仅是市场上的宠儿,也是是单片机实验中一个很常用的题目。

因为它有很好的开放性和可发挥性,因此对作者的要求比较高,不仅考察了对单片机的掌握能力更加强调了对单片机扩展的应用。

而且在操作的设计上要力求简洁,功能上尽量齐全,显示界面也要出色。

1.2 课程设计内容利用单片机、时钟芯片DS1302、温度传感器DS18B20、1602液晶屏等实现日期、时间、温度的显示,即是一个电子时钟。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于单片机的LCD1602电子时钟设计一、设计任务和目的1.1、设计任务(1):用单片机设计基于LCD1602的电子时钟,显示时间和日期;(2):误差精度控制在1s/天;(3):具有时间和日期的校准功能;(4):能区分某年是闰年或平年,并对应显示2月份的天数;(5):根据月份的不同显示不同的最大日数;(6):搭建仿真电路图,模拟单片机要实现的功能;(7):焊接单片机开发板;(8):编写程序,下载并调试,实现要求的功能。

1.2、设计目的(1):熟练掌握KEIL软件的使用方法;(2):熟练掌握PROTEUS软件的使用方法;(3):掌握单片机I/O接口的工作原理;(4):掌握LCD显示器的工作原理及编程方法;(5):掌握独立式键盘的工作原理及编程使用方法;(6):掌握单片机的下载使用方法。

二、设计思路和方案论证2.1、设计思路电路总体上分为控制和显示部分。

以单片机最小系统作为核心控制电路,控制LCD显示,具体显示内容及方式由软件来完成;由于有时钟和日期的调节功能需要校准电路和基本的复位电路,复位电路采用按键复位,调节键、加1键、减1键三个按键完成,共需四个按键;计时功能由固定频率的晶振完成(采用11.0592MHz);显示部分主要采用LCD1602作为显示。

2.2、方案论证(1):时钟芯片的选择和论证方案一:采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、月、年以及闰年补偿的年进行计数,精度也较高,工作电压2.5V~5.5V范围内,功耗也较低,但价格比较贵。

方案二:直接采用单片机定时计数器提供秒信号,使用程序实现秒、分、时、日、月、年计数。

采用此方案实现虽然有一定的时间误差,但可减少芯片的使用,节约成本,易于实现,符合现实选用,所以采用此种作为时钟信号发生器。

(2):显示模块选择方案和论证:方案一:采用点阵式图形LCD12864液晶显示屏,液晶显示屏的显示功能强大,可显示文字,图形,显示多样,清晰可见,但是价格昂贵,需要的接口线多,所以在此设计中不采用点阵式图形LCD12864液晶显示屏。

方案二:采用点阵式字符型LCD1602液晶显示屏,LCD1602是专门用于显示字母、数字、符号等的点阵型液晶显示模块,分4位和8位数据传输方式。

提供“5×7点阵+光标”和“5×10点阵+光标”的显示模式。

价格现对便宜,所以用此种作为显示。

三、系统的硬件设计与实现3.1 电路设计框图图1:整体设计方框图3.2 单片机最小系统的设计以AT89C51为核心组成的单片机的最小系统,主要包括时钟振荡电路,复位电路等。

正5V 电源直接接到89C51的40脚(VCC ),20脚(GND )接地。

时钟振荡电路的18脚(XTAL1)和19脚(XTAL2)外接11.0592MHZ 的晶振和二个30PF 的电容,振荡频率就是晶振的固有频率,经过一定的电路连接实现计时的功能。

复位电路采用上电自动复位和手动复位相结合的方式接到89C51的9端(RST )。

单片机最小系统原理图如图2所示:图2:单片机最小系统原理图AT89C51 主 控 制 模 块 复位电路 时钟振荡电路 LCD 显示模块 键盘控制电路3.3 显示电路设计采用LCD1602液晶显示,LCD1602的D0~D7与单片机的P0口相连,P0口作为I/O口输出时必须外接10KΩ的上拉电阻。

分别用P1.0、P1.1、P1.2作为LCD1602的RS、RW、E控制线。

显示电路如图3所示:图3:液晶显示电路3.4 时间调整电路该电路设计有三个轻触式按键,分别命名为:模式设定键S1、加调整键S2、减调整键S3。

由P2.0口外接S1,P2.1外接S2,P2.2外接S3,P2.3作为公共端。

按一下S1,调整光标开始出现在秒位,再按一下S1光标移动到分,按一下光标移动一个校准位直到年位。

S2实现调整加1功能,S3实现调整减1功能。

时间调整电路如图4所示:图4:键盘电路3.5 复位电路及晶振电路该电路采用按键复位,有一个22uF的电容、一个按键S4、一个10K的电阻和一个220Ω的电阻构成。

在产品工作期间出现错误或死机现象可采用手动复位,即按下S4,此时无论电路处于何种状态,电路都会恢复到初始状态的显示。

晶振电路可以给单片机提供所需要的时钟频率,主要由晶振这个元件固定的精确的频率来实现。

复位电路及晶振电路如图5所示:图5 复位电路及晶振电路四、系统软件设计软件系统分四个部分:主函数程序部分,键盘扫描部分,定时器中断部分,LCD初始化部分。

各部分程序流程图如下所示:4.1 主函数程序流程图开始定时器的选择、工作模式设定、给定时器赋值开中断启动定时器调用LCD初始化子程序调用键盘扫描子程序图6 主函数流程图4.2 键盘扫描子程序流程图图7 键盘扫描程序流程图4.3 定时器中断子程序流程图NOYES 4.3 LCD初始化程序流程图图9 LCD初始化流程图五、设计结果分析5.1 硬件分析该设计电路系统较大,电路系统中只要出于一处的错误,则会对检测造成很大的不便,而且电路的交线较多。

另外,买来的元器件要先进行检测,如果有坏的器件要进行更换,还有就是要注意元器件的正确放置与安装以及布线的合理,便于成品电路的检测与维护。

为了减少复杂度,可用Proteus软件进行仿真,按照电路原理图在Proteus 中选择元器件并连接,把生产的HEX文件烧入到单片机内部进行仿真,若出现错误及时更改。

在本设计中遇到了很多的问题。

回想这些问题,其实只要认真思考许多都是可以避免的,以下为主要的问题:(1):在Proteus仿真中提示出错,没有仿真结果。

在Proteus中仿真中,提示出现了R1(R2)错误,经过仔细排查,发现有两个电阻命名,是R1,两个电阻命名是R2。

修改后就没有出现错误。

(2):在Proteus仿真中,LCD不显示在硬件设计上需要用P0口来对LCD进行指令的读写和数据的输入,由于没有在P0口接上拉电阻,LCD屏就一直不显示。

最终将在查阅课本时想起P0做输出口使用时外部必须接10KΩ的上拉电阻,接上后LCD就正常显示了。

5.2 软件分析该设计的功能虽然比较简单,但程序也较为复杂,所以在编写程序和调试时出现了许多问题。

最后经过多次的模块子程序的修改,一步一步的完成,最终在KEIL调试成功,解决了软件问题。

在软件的调试过程中主要遇到的问题如下:(1):烧入程序后,秒、分、时、年能正常工作,但是日、月出错当秒等于60时显示为00,范围是0~59;当分等于60时显示00,范围是0~59;当时等于24时显示00,范围是0~23;年等于100是显示00,范围是00~99;日和月的显示都不包括0,当由于软件出错,显示时出现了,经过改写最终全能正常显示。

(2:):不能正常区分闰年和平年,每月都是31天闰年和平年的2月份分别是29天和28天,1、3、5、7、8、10、12月份显示范围是0~31,4、6、9、11月份显示范围是0~30。

刚开始不能区分,最后经过修改能区分显示。

六、设计体会通过这次单片机课程设计,发现了自身所学知识存在许多的不足和问题,同时也学到了不少东西,提高了动手实践的能力。

在整个设计过程中,从设计方案的确定,到具体电路在Proteus中的设计,最后到总体电路的联接构建以及程序的编写烧制,特别是程序的编写,要求对LCD1602的初始化操作、指令和数据的操作都需要很熟悉。

在设计过程中碰到实在不能解决的问题,就问老师或是和同学交流,把问题彻底搞清楚并加以掌握。

尽管在这次设计中遇到了许多难题,但也都一一得以解决。

比如程序编写中,由于思路不清晰,开始时遇到了许多的问题,经过静下心来思考,和同学们的共同讨论,理清了思路,反而得心应手;在硬件方面虽然没有遇到什么大问题,但从中也学到了许多知识。

通过此次设计,也使我知道了做任何事都要有一颗平常心,不要想着走捷径,一步一个脚印,把每一步都认认真真做好了,才能取得最后的成功,同时也锻炼了我的耐心,做什么事都要有耐心,不要遇到困难就退缩,而是要静下心来去寻找解决的办法否则很难有最后的成功。

在此过程中更要注重自主学习,发挥自己的主观能动性。

总之,这次课设是我的又一次全新的尝试,也是一个小小的成功,更是一次很好的锻炼,让我有了全方位的提高和进步。

七、proteus仿真图图(10)仿真主界面图(11)调节分界面图(12)调节月界面图(13)调节年界面八、参考文献[1] 周国运。

单片机原理及应用(C语言版)。

北京:中国水利水电出版社,2009[2] 张齐、朱宁西。

单片机应用系统设计技术。

北京:电子工业出版社,2009[3] 汪道辉。

单片机系统设计与实践。

北京:电子工业出版社,2006[4] 杨子文。

单片机原理及应用。

西安:西安电子科技大学出版社,2006九、程序附录:#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define datasend P0sbit lcden=P1^2; //LCD使能端sbit lcdrs=P1^0; //LCD 数据/指令(H/L)选择端sbit lcdrw=P1^1;uchar mytable0[]="Nan yang li gong";uchar mytable1[]="liu hai yan DIY!!";uchar code line0[]=" 2010-12-01 "; //初始化显示uchar code line1[]=" 00:00:00 ";uchar code month0[]={31,28,31,30,31,30,31,31,30,31,30,31}; //平年月uchar code month1[]={31,29,31,30,31,30,31,31,30,31,30,31}; //闰年月uchar count,hour,minute,second,year=1,month=1,date=1;uchar s1num; //s1num:定义功能键按下次数变量void delay(unsigned int z) //延时子函数z*1ms{unsigned int x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(unsigned char c) //写命令子函数{lcdrs=0; //低电平选择为写指令lcden=0;datasend=c; //把指令写入P0口delay(5);lcden=1; //开使能delay(5); //读取指令lcden=0; //关闭使能}void write_data(unsigned char d) //写数据子函数{lcdrs=1; //高电平选择为写数据datasend=d; //把数据写入P0口delay(5);lcden=1; //开使能delay(5); //读取数据lcden=0; //关闭使能}void write_hms(uchar add,uchar dat) //时分秒写函数add:输入位置设置变量dat:输入时分秒数据{uchar sw,gw; //定义十位,个位变量sw=dat/10;gw=dat%10;write_com(0x80+0x40+add); //从第二行(add)位开始写数据write_data(0x30+sw); //写入十位write_data(0x30+gw); //写入个位}void write_ymd(uchar add,uchar dat) //年月日写函数add:输入位置设置变量dat:输入时分秒数据{uchar sw,gw; //定义十位,个位变量sw=dat/10;gw=dat%10;write_com(0x80+add); //从第一行(add)位开始写数据write_data(0x30+sw); //写入十位write_data(0x30+gw); //写入个位}void t0() interrupt 1 //定时器0中断子程序{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;}void gethms() //时分秒处理子程序{second++;if(second==60){second=0;minute++;if(minute==60){minute=0;hour++;if(hour==24){hour=0;date++;}write_hms(2,hour); //时输出显示}write_hms(5,minute); //分输出显示}write_hms(8,second); //秒输出显示}void getymd() //年月日处理子程序{if(year%4==0){if(date==month1[month-1]+1){date=1;month++;if(month==13){month=1;year++;if(year==100){year=1;}write_ymd(4,year);}write_ymd(7,month);}write_ymd(10,date);}else{if(date==month0[month-1]+1){date=1;month++;if(month==13){month=1;year++;if(year==100){year=1;}write_ymd(4,year);}write_ymd(7,month);}write_ymd(10,date);}}void key_process() //按键扫描子程序{if(P2==0xf6) //功能键delay(25);if(P2==0xf6) //功能键按下{while(P2==0xf6); //松手检测s1num++; //功能键按下计数TR0=0; //T0定时停止,进入时间调整switch(s1num){case 1: write_com(0x80+0x40+0x09); break; //光标闪烁位定为秒个位case 2: write_com(0x80+0x40+0x06); break; //光标闪烁位定为分个位case 3: write_com(0x80+0x40+0x03); break; //光标闪烁位定为时个位case 4: write_com(0x80+0x0b); break; //光标闪烁位定为日个位case 5: write_com(0x80+0x08); break; //光标闪烁位定为月个位case 6: write_com(0x80+0x05); break; //光标闪烁位定为年个位}write_com(0x0f); //光标闪烁if(s1num==7){s1num=0; //按键计数复位write_com(0x0c); //光标停止闪烁TR0=1; //重新启动定时器}}if(P2==0xee) // 时分秒+1 模块{delay(25);if(P2==0xee){while(P2==0xee);switch(s1num){case 1: second++; //秒+if(second==60) second=0; //复位write_hms(8,second); //秒输出显示write_com(0x80+0x40+0x09); //光标闪烁位定为秒个位break;case 2: minute++;if(minute==60) minute=0; //复位write_hms(5,minute); //分输出显示write_com(0x80+0x40+0x06); //光标闪烁位定为分个位break;case 3: hour++;if(hour==24) hour=0; //复位write_hms(2,hour); //时输出显示write_com(0x80+0x40+0x03); //光标闪烁位定为时个位break;case 4: date++; //日+if(year%4==0) //平闰年判断{if(date==month1[month-1]+1){date=1;}}else{if(date==month0[month-1]+1){date=1;}}write_ymd(10,date); //日输出显示write_com(0x80+0x0b); //光标闪烁位定为日个位break;case 5: month++; //月+if(month==13) month=1;if(year%4==0) //判断日和月的配对关系{if(date>month1[month-1])date=month1[month-1];}else{if(date>month0[month-1])date=month0[month-1];}write_ymd(10,date); //日输出显示write_ymd(7,month); //月输出显示write_com(0x80+0x08); //光标闪烁位定为月个位break;case 6: year++; //年+if(year==100) year=1; //复位write_ymd(4,year); //年输出显示write_com(0x80+0x05); //光标闪烁位定为年个位break;}}}if(P2==0xde) //时分秒-1 模块{delay(5);if(P2==0xde){while(P2==0xde);switch(s1num){case 1: second--; //秒-if(second==255) second=59; //复位write_hms(8,second); //秒输出显示write_com(0x80+0x40+0x09); //光标闪烁位定为秒个位break;case 2: minute--;if(minute==255) minute=59; //复位write_hms(5,minute); //分输出显示write_com(0x80+0x40+0x06); //光标闪烁位定为分个位break;case 3: hour--;if(hour==255) hour=23; //复位write_hms(2,hour); //时输出显示write_com(0x80+0x40+0x03); //光标闪烁位定为时个位break;case 4: date--; //日-if(year%4==0){if(date==0){date=month1[month-1];}}else{if(date==0){date=month0[month-1];}}write_ymd(10,date); //日输出显示write_com(0x80+0x0b); //光标闪烁位定为日个位break;case 5: month--; //月-if(month==0) month=12;if(year%4==0) //判断日和月的配对关系{if(date>month1[month-1])date=month1[month-1];}else{if(date>month0[month-1])date=month0[month-1];}write_ymd(10,date); //日输出显示write_ymd(7,month); //月输出显示write_com(0x80+0x08); //光标闪烁位定为月个位break;case 6: year--; //年-if(year==1) year=99; //复位write_ymd(4,year); //年输出显示write_com(0x80+0x05); //光标闪烁位定为年个位break;}}}}void initialize( ) //LCD初始化函数{uchar num;lcden=0;write_com(0x38); //设置16x2显示,5x7点阵显示,8位数据接口write_com(0x0c); //00001DCB,D(开关显示),C(是否显示光标),B(光标闪烁,光标不显示)write_com(0x06); //000001N0,N(地址指针+-1)write_com(0x01); //清屏指令每次显示下一屏内容时,必须清屏write_com(0x80+0x10); //第一行显示for(num=0;num<16;num++) //显示16个字符{write_data(mytable0[num]);delay(10);}write_com(0x80+0x50); //第二行,从第一格开始显示for(num=0;num<16;num++) //显示16个字符{write_data(mytable1[num]);delay(10);}for(num=0;num<16;num++){write_com(0x1c); //0001(S/C)(R/L)**; S/C:高电平移动字符,低电平移动光标;R/L:高电平左移,低电平右移delay(300);}delay(1000);write_com(0x01); //清屏指令每次显示下一屏内容时,必须清屏write_com(0x80);for(num=0;num<13;num++) //初始化第一行显示{write_data(line0[num]);delay(50);}write_com(0x80+0x40); //第二行,顶格显示for(num=0;num<10;num++) //初始化第二行显示{write_data(line1[num]);delay(50);}TMOD=0x01; //定时器0中断初值设置TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}void main(){ lcdrw=0;P2=0xfe;initialize(); //初始化while(1){key_process(); //按键扫描if(count==20) //定时1s 运行模块{count=0;gethms(); //时分秒数据处理getymd(); //年月日数据处理}}}系统总原理图如下所示设计说明书内容忽略此处..21。

相关文档
最新文档