C51 LCD(LM044L)多功能可调时钟设计
基于C51单片机技术的时钟课程设计报告
课设报告工程学院软件学院题目:时钟班级:姓名:学号:指导老师:日期: 2013 年 10 月 11日目录1 摘要32 设计要求32.1 功能需求32.2 设计要求33 硬件设计与描述33.1 总体描述33.2 系统总体框图 43.3 Proteus电路图43.4 各部分硬件介绍44 软件设计流程与描述84.1 程序流程图84.2 函数模块与功能94.2.1单片机主控制模块94.2.2数码管显示模块94.2.3 按键模块114.2.4计时模块115 功能实现136 心得体会147 源程序141 摘要众所周知单片机是一种集成在电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。
本设计要制作的就是单片机于生活中最为常见的几种应用——时钟。
本设计以AT89S52单片机作为核心,可以显示当前的时间,时间也可以人为设定,显示格式为时(两位),分(两位),秒(两位)。
设置时间的数值、启动定时器。
时钟显示电路由数码管组成,制作该装置的材料需要有软硬件的支持,硬件方面AT89C51单片机,晶振,电源,数码管。
2 设计要求2.1 功能需求1、在数码管上显示初始时间如12-23-33,从初始设置的时间开始走时,每一秒自动加1,当59秒后自动向分进位、59分后自动向时进位。
2、通过按键设置时间,按下键1,时钟分加1;按下键2,时钟分减1,。
从而实现用按键设置时间的功能。
2.2 设计要求本次设计的是时钟,本电路是由AT89S52单片机为控制核心,通过按键实现时钟分的自增自减进行时间的设置,在数码管上进行显示。
3 硬件设计与描述3.1 总体描述单片机采用STC90C516RD+,采用MCS-51实验开发板。
C51 LCD(LM044L)多功能可调时钟设计
1、LCD(LM044L)多功能可调时钟设计设计思路:利用单片机的定时器定时,产生时钟的时、分、秒,年、月、日,用LCD(LM044L)显示出时间的时、分、秒,年、月、日,并用英文显示“星期几”。
具有百分之一秒,秒,分,跑表功能。
一键开始并记录4组结果。
使用若干个按键调整时间,一个用于选择调整的时间位,一个用于调整时间。
也可以使用多个键,用于调整各自的时间位。
首先在proteus上绘制电路,编程模拟运行实现。
运行效果代码#include<reg51.h> //包含单片机寄存器的头文件#include<stdlib.h> //包含随机函数rand()的定义文件#include<intrins.h> //包含_nop_()函数定义的头文件sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚unsigned char code table[]="2011-12-01"; //初始化液晶显示10 unsigned char code table1[]=" 12:00:55"; //12 unsigned char code table2[]="week 3 00:00:00"; //15 unsigned char code table3[]="00:00:00 00:00:00 00:00:00 00:00:00"; unsigned char count,s1num,s5num;char second,minute,hour,day,month,year,week;char ms,sec,minu;sbit s1=P1^0; //功能键sbit s2=P1^1; //加键sbit s3=P1^2; //减键sbit s4=P1^3; //保存并退出sbit s5=P1^4; //秒表void delay1ms() //计算延迟1ms{unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}/***************************************************** 函数功能:延时若干毫秒入口参数:n***************************************************/void delay(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。
c51液晶显示时钟程序模块流程图
是否按下? Y
分-1
N 分=-1? Y
分<=60
N KeyY3 是否按下?
延时 10ms 消抖
N 再次判断 Key3
Y是否按下?
时+1
N 时=12? Y 时<=0
N Key2 是否释放
Y
N Key3 是否释放
Y
返回
N KeyY4 是否按下?
延时 10ms 消抖
再次判断 Key4 N 是否Y 按下?
时-1 N
延时 返回
数据写入 AT24C02 子程序
数据写入 AT24C02 子程序入口
write_add(23,miao)写秒
延时
、
write_add(24,fen)写分
延时 write_add(25,shi)写时
延时 结束
时12key1是否释放key2是否释放key3是否释放key4是否释放数据处理子程序流程图数据处理子程序入口秒个位秒10秒十位秒10分个位分10分十位分10时个位时10时十位时10返回液晶显示子程序流程图液晶显示子程序入口液晶初始化写指令选择第一行数据地址指针延时一会循环将8位时间数据逐位写入显示在第一行写指令选择第二行数据地址指针延时一会循环将clock12hour12位数据逐位写入显示在第二行读取at24c02中数据子程序读取数据子程序入口i2c总线初始化miaoreadadd23读秒延时fenreadadd24延时shireadadd25数据写入at24c02子程序数据写入at24c02子程序入口writeadd23miao写秒
总程序流程图
开始
读取 AT24C02 中的数据
程序初始化
TH0、TL0Z 装初值 并允许 T0 中断 Y
C51程序液晶显示及时间调整
write_data(0x30+ge);
}
void calute_time()
{
uchar revise_month=0;
uchar datechange=0;
uchar leap=0;
if(sec!=oldsec)
{
oldsec=sec;
else if(shift<=5)
write_com(0x80+14-4*(shift-3));
else
{
shift=0;
write_com(0xc0+12);//
}
}
}
if(key1==1&&key2==0)//上调时间
sbit RS=P3^5;
sbit LCDEN=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
bit key1=1;
bit key2=1;
bit press=1;
sbit s5=P3^7;
void init();
uchar leap_year(uint);
}
}
else if(month==2)
{
if(date>28)
{
revise_month=1;
}
}
}
else if((month==4)||(month==6)||(month==9)||(month==11))
date=1;
write_sfm1(13,date);
break;
C51课程设计报告(液晶时钟)
深圳职业技术学院Shenzhen Polytechnic 嵌入式C语言课程设计报告课题:学院:班级:姓名:目录一、设计方案 (1)1、功能简介 (1)2、开发测试环境选择 (1)二、液晶时钟程序设计 (1)1、功能状态转换图 (1)2、主要功能模块 (2)2.1主显示模块 (2)2.2功能选择模块 (2)2.3时间修改模块 (3)2.4闹铃修改模块 (3)2.6其他辅助模块函数以及变量 (4)三、小结 (4)四、附录 (5)1、使用说明 (5)2、参考文献资料 (5)3、附表1 (6)一、设计方案1、功能简介本文所设计的简易电子时钟可输出当前时间以及闹铃时间,并可通过机械按键来实现修改当前时间、修改闹铃时间、退出修改以及控制闹铃的打开和关闭,并通过1602型号的液晶屏显示出不同操作时的不同界面。
本程序共设计按键5个,按键及功能分别是1键:选择功能界面下选择时间修改、时间和闹铃修改状态下的增加“1”计数;2键:选择功能界面下选择闹铃修改、时间和闹铃修改状态下的减少“1”计数;3键:主显示界面下进入选择功能界面、时间和闹铃修改状态下切换修改项目、修改完成退回主显示界面;4键:时间和闹铃修改状态下直接退回主显示界面;5键:主显示界面下控制闹铃的开关。
2、开发测试环境选择开发软件选择了ARM公司的KeiluVision4,仿真软件选择了英国Labcenter electronics公司的proteus7 professional,测试硬件选择了普中的HC6800开发箱。
首先在KeiluVision4下进行程序设计,编译通过后用proteus7 professional进行仿真并尝试下载到开发箱中进行操作,最后下载到开发箱中进行操作演示。
二、液晶时钟程序设计1、功能状态转换图2、主要功能模块注:本文中提到的函数均见附表1的液晶时钟源程序中,本次使用的是1602液晶。
2.1主显示模块主显示模块包含了时间显示模块void TimeDisplay(void)函数,其运行过程为首先读取初始值,再通过定时器中断TO的中断服务函数void T0_int () interrupt 1 来进行秒计时并通过void TimeRunning(void)函数进行时间的加计数和进位运算;闹铃显示模块void AlarmDisplay(void),其运行过程为首先读取初始值,再通过void AlarmRunning(void)来进行比较,如果预设时间与当前时间相等就将响铃标记变量SoundFlage_1置为1,进而引发主函数中的响铃事件。
基于C51的电子钟方案设计书
1 系统电路设计1.1 系统总体设计思路此设计原理框图如下所示,电路包括四个部分:单片机,键盘,锁存及显示电路,掉电保护电路。
图1.1 单片机实现数码管显示电子钟总框图对于各部分:(1)单片机发送的信号经过锁存电路最终在数码管上显示出来。
(2)单片机通过输出各种电脉冲信号来驱动控制各部分正常工作。
(3)掉电保护电路保证系统掉电时时钟不会停止。
(4)为使时钟走时与标准时间一致,校时电路是必不可少的,键盘用来校正数码管上显示的时间。
1.2 工作原理设计的电路主要由四大模块构成:掉电保护电路,单片机控制电路,显示电路以及校正电路。
本设计采用C语言程序设计,使单片机控制数码管显示年、月、日、时、分、秒,当秒计数计满60时就向分进位,分计数器计满60后向时计数器进位,小时计数器按“23翻0”规律计数。
时、分、秒的计数结果经过数据处理可直接送显示器显示。
当计时发生误差的时候可以用校时电路进行校正。
时计数器计满24小时后自动向日计数器进一,日计数器需判断平年、闰年和大月、小月,当日计数器计满时,向月计数器进位,月计数器计满12月向年计数器进位。
设计采用的是年、月、日、时、分、秒显示,单片机对数据进行处理同时在数码管上显示。
2 单元电路设计2.1 单片机电路设计本设计采用AT89C52单片机进行设计,它是一种低功耗,高性能的CMOS8位微处理器,内部有8K字节的程序存储器和256字节的数据存储单元,32个I/O端口,3个16位定时/计数器,8个中断源。
时钟电路是单片机系统的心脏,它控制着单片机的工作节奏。
本设计采用内部时钟方式,12MHz的石英晶体振荡器。
电路图如下图2.1 时钟电路复位电路由单片机引脚RST接入,只要RST端保持10ms以上的高电平,就能使单片机有效地复位,本设计采用上电复位和手动复位两种方式。
电路图如下图2.2 复位电路2.2 掉电保护电路设计本设计采用如下掉电保护电路,当电源供电正常时,一方面给单片机供电,另一方面给电池充电,当电源断电时,电池放电,继续给单片机供电,保证其正常工作。
C51液晶显示时钟(可调整时间)
C51时、分、秒计时器设计一、任务及要求用51单片机设计时、分、秒计时器,具体要求如下。
1、具有时、分、秒计时功能和8位lcd1602显示功能,显示格式为:“时-分-秒”;2、用Proteus设计仿真电路进行结果仿真;3、完成程序设计、仿真电路设计、结果仿真,完成报告并上传空间课程栏目中的课程设计报告子栏目中。
二、设计方案1、总体设计方案(刘负责完成)(1)、仿真电路构成:电路分4个模块:晶振电路模块、I2C总线模块、按键模块、液晶显示模块。
晶振电路模块负责给单片机提供时钟周期;利用A T89C51芯片内部的T0定时器定时,定时1s到则使时间进行一次变化,要使时间显示在液晶上则在电路中添加8位lcd1602液晶;I2C总线模块是存储时分秒数据的,时间每变化一次都将其数据保存在A T24C02中;按键模块中,采用四个按键作为电子时钟的控制输入,通过按键来实现时钟的时间调整功能。
电路中将四个按键的一端接公共地,而单片机的P3口默认为高电平,一旦按键被按下,则该按键对应的额管脚被拉低,通过软件扫描按键即可知道用户所要实现的功能,调用相应的按键子程序来完成该操作。
按键的去抖动由软件来实现,如下图所示,分别按下“1、4、7、*”四个按键可以调整时和分。
(2)、程序模块构成:本系统的软件系统主要可分为I2C总线程序模块、定时计数中断程序、按键识别程序、数据处理程序、液晶显示程序、延时程序六大模块。
I2C总线程序模块:包含的子程序模块有起始信号、终止信号、应答信号、初始化、写一字节、读一字节、写数据、读数据等。
是将每次时间变化(即约1s变化一次)后的数据保存在A T24C02中,断电后,下次再上电时可读取断电时所保存的数据,接着继续计时;定时中断模块:采用51单片机内部T0定时器定时,定时50ms,再循环20次,即可得到50ms*20=1s的时间,定时1s到了之后使得秒自加1,当秒到了60时,秒重新赋值为0且分加1,当分到了60时,分重新赋值为0且时加1;按键识别模块:此模块是对时和分进行调整,检测四个按键,其功能分别是分+1、分-1、时+1、时-1,当检测到某一按键按下时执行相应的操作实现对时间的调整,此过程中主要要注意按键消抖的问题;数据处理模块:此模块是将时、分、秒的个位和十位分开,保存在数组中,供显示模块使用;液晶显示模块:此模块是将时、分、秒显示在液晶屏上。
C51多功能电子时钟
~~~~~~目录~~~~~~一、设计任务 (2)二、总体方案设计与方案论证 (3)2.1总体方案设计 (3)2.2方案论证 (4)三、总框图及总体软件设计说明 (7)四、系统资源分配说明 (10)五、局部设计说明 (12)六、系统功能与操作说明 (14)6.1系统功能 (14)6.2 操作说明 (15)七、调试记录及调试结果 (19)八、课程设计总结 (21)九、程序附录清单 (26)一、设计任务整体设计任务:本电多功能子时钟设计首要的工作是结合以往所学的单片机程序编写理论和编写规则来编写电子时钟的软件部分,编写时要结合所配的AT89S52芯片的管脚功能和其他硬件电路,该部分运用keil单片机软件来完成。
在编写完软件并检测完正确后再编译成.hex载入实验板中,并调试。
电子多功能万年历是一种非常广泛日常计时工具,对现代社会越来越流行。
它可以对年、月、日、周日、时、分、秒进行计时,温度显示,还具有闰年补偿,闹铃等多种功能。
对于数字电子万年历采用直观的数字显示,可以循环显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。
该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
二、总体方案设计与方案论证1、总体方案设计根据设计要求,总体方案我划分为如下几个模块:(1)自检模块(2)显示更新子程序(3)显示内容送显示缓冲单元的拆字子程序(4)显示定时切换子程序(5)手动切换进程子程序(6)温度滚动采集存储子程序(7)键盘扫描子程序(8)定时切换设定子程序(9)时钟日期设定子程序(10)无操作处理子程序(11)按键操作子程序(12)温度计算模块(13)星期计算模块(部分蔡勒公式汇编程序)(14)正点报时模块(15)闹铃判断模块(16)消抖动子程序(17)定时中断子程序(17)数码管闪烁模块(18)小数点模块(19)双字节压缩二进制码转BCD码模块以上各个模块进行有效地串接与组合,就可以完成本次多功能电子时钟的设计。
c51单片机可调时钟程序
{
uint i;
for(i=0;i<temp;i++);
}
shenying()
{
for(y=0;y<250;y++)
{
P0=0x00;delay0(9);
P0=0xff;delay0(9);
}
}
jialiang()
{
if(xuanshu==1)
}
}
else if(xuanshuhi==-1)
{
shi=23;
}
}
}
delay(uint temp)
{
uint i;
for(i=0;i<temp;i++)
{
if(xuanze==0)
{
while(xuanze==0)
}
fenwei()
{
c=fen%10;P1=duanma[c];P2=weima[2];delay(100);
d=fen/10;P1=duanma[d];P2=weima[3];delay(100);
}
shiwei()
{
e=shi%10;P1=duanma[e];P2=weima[4];delay(100);
{
P1=duanma[a];P2=weima[0];delay0(100);
P1=duanma[b];P2=weima[1];delay0(100);
P1=duanma[c];P2=weima[2];delay0(100);
P1=duanma[d];P2=weima[3];delay0(100);
基于51单片机设计的多功能数字时钟毕业设计
基于51单片机多功能数字时钟1系统设计1.1设计要求设计制作一个24小时制多功能数字钟。
1.1.1主要性能指标1、数字显示年、月、周、日、时、分、秒。
1.1.2创意部分要求准确的进行年、月、周、日、时、分、秒的转换,切换两种显示模式。
1.2总体设计方案1.2.1概述及设计思路该设计方案是以MC51单片机为核心,采用LCD液晶屏幕显示系统,温度采集模块、日期提醒、键盘时间调整预设置等模块,所构建的数字时钟系统,能动态显示实时时钟的时、分、秒,数据显示(误差限制在30每天)。
1.2.2方案论证(1)时钟模块【方案一】采用单片机内置定时/计数器。
它的处理过程主要是先设定单片机内部定时/计数器的工作方式,对机器周期计数确定基准时间,然后用另外一个定时器软件计数的方法对基准时间形成秒,秒计60次形成分,分计60次形成小时。
依此类推,获取日期也是采用相同的方法。
该方案在具体实现过程中,计时存在较大的误差。
如果晶振受到其他外界信号干扰,或者基准时间计算不准确,都会导致时间显示错误。
【方案二】采用555多谐振荡器。
由555定时器组成一个多谐振荡器,产生周期为100HZ的脉冲,然后经过两个74LS160组成的分频器得到1HZ的秒脉冲。
多谐振荡器的稳定度及频率的准确度决定了数字钟计时的准确程度,通常选用成品晶振构成振荡器电路。
计时精度取决于振荡器的频率,振荡器频率越高计时精度越高。
【方案三】采用DS1302时钟芯片。
DS1302是一种高性能、超低功耗的实时时钟芯片,附加31字节静态RAM,可以通过串行接口与单片机进行通信。
实时时钟提供秒、分、时、日、星期、月、年的信息,每个月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM标志位决定采用24或12小时时间格式。
芯片内部集成备用电源,当外围电路电路有电源供应的时候,备用电源充电储能。
当外围电路掉电时,DS1302芯片工作在休眠状态,以备用电源供电。
当外围电路再次供电,即可唤醒休眠进入正常工作状态,显示时间无任何异常。
C51单片机 定时器可调时钟 程序
void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
unsigned char KeyScan(void);//键盘扫描
void Init_Timer0(void);//定时器初始化
{
case 0xfe:return 1;break;
case 0xfd:return 2;break;
case 0xfb:return 3;break;
case 0xf7:return 4;break;
case 0xef:return 5;break;
case 0xdf:return 6;break;
minute++;
if(minute==60)//分钟到60,小时加1
{
minute=0;
hour++;
if(hour==24)//小时到24,回零
hour=0;
}
}
}
}
/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
break;
case 4:minute--;if(minute==255)minute=59; //分钟减1
break;
default:break;
}
if(UpdateTimeFlag==1)
{
UpdateTimeFlag=0;
TempData[0]=dofly_DuanMa[hour/10]; //时//数据的转换,因我们采用数码管0பைடு நூலகம்9的显示,将数据分开
基于51单片机的可调数码日历钟的设计与制作毕业设计论文
专科毕业设计(论文)题目基于51单片机的可调数码日历钟的设计与制作摘要单片机以其体积小、编程灵活、控制功能强大、价格低廉等特点被广泛应用在各种电子电器产品中。
单片机技术的出现和发展带来了电子技术和控制领域的一场革命。
单片机课程作为职业院校电子信息类专业一门重要的基础课程,它既是一门很有实用价值、实践性很强且很有趣味性的课程,同时它又是一门集硬件电路设计与软件编程于一体的学科,既要求我们有较好的电工电子技术基础知识,又要求有一定的逻辑思维和软件开发(编程)能力。
通过近几年对单片机的学习,我已掌握单片机的基本知识,并具备了单片机应用系统的初步开发能力。
即将毕业之际,我运用我所掌握的单片机知识设计和制作了一个基于51单片机的可调数码日历钟,这既是对我所学知识的总结与高度概括,同时也将自己所掌握的知识与实际应用结合起来,进一步提高工程实践能力。
数码日历钟是实际生活中应用较多的一个电子计时装置,可供人们查询日期、星期及掌握时间。
本文首先从数码日历钟的功能要求入手,对设计任务进行了分析,并将任务分解为若干个模块,提出在设计与制作过程中要用到的相关知识点,给出了本设计的硬件电路及软件流程,还给出了部分模块的源程序代码。
本设计经过多次调试运行无误,最终提交出一个完整的应用系统产品。
本次毕业设计的数码日历钟能在12864液晶屏上显示出年月日时分秒以及星期几,还能显示当前环境温度,并能通过按键调整日期和时间,在调整日期的同时通过相应算法自动实现星期几的调整,而且无论是否闰年、任何月份,当日期调整时都保证不会出现非法日期。
数码日历钟是一个非常实用的设计与制作,成本低廉,如能进一步完善,具有一定的推广使用价值。
本设计任务比较复杂,要考虑的问题很多,C语言的模块化程序设计思想较好地解决了这个问题,故本设计任务采用C语言编程。
关键词:51单片机,C语言,数码日历钟,毕业设计,制作I河南理工大学毕业设计论文目录摘要 (Ⅰ)1概述 (1)1.1 毕业设计的选题背景及制作意义 (1)1.1.1毕业设计的选题背景 (1)1.1.2毕业设计的制作意义 (1)1.2 数码日历钟的功能要求 (1)1.3 本设计制作的主要内容 (2)2数码日历钟的设计与制作任务分析 (3)2.1数码日历钟的设计与制作任务分析与分解 (3)2.2设计方案的论证及选择 (3)3 相关知识链接 (6)3.1 51单片机简介 (6)3.1.1 51单片机简介 (6)3.1.2 51单片机引脚功能介绍 (8)3.2由已知日期推算星期几 (11)3.2.1如何判断一个年份是否闰年 (11)3.2.2由已知日期如何推算星期几 (11)3.3 12864图形液晶的使用 (13)3.3.1 液晶概述 (13)3.3.2 LCM引脚功能介绍 (14)3.3.3 LCD12864图形液晶显示模块指令集 (15)3.3.4 LCD12864图形液晶显示模块与单片机的接口 (17)3.3.5 LCD12864图形液晶显示模块的基础函数 (17)3.4 51单片机中的中断与定时 (19)3.4.1 51单片机中的中断 (19)3.4.2 51单片机中的定时/计数器 (22)3.5数字温度传感器DS18B20的使用 (28)3.5.1 DS18B20概述 (28)3.5.2 DS18B20的内部结构 (29)3.5.3 DS18B20与单片机的接口电路 (32)3.5.4 DS18B20的操作命令 (32)-1-3.5.5 DS18B20的时序 (33)3.6 矩阵式按键的检测 (36)4系统设计与调试 (44)4.1 硬件系统设计与调试 (44)4.1.1硬件系统设计原理图 (44)4.1.2硬件系统元器件清单 (44)4.1.3硬件系统组装与调试 (45)4.2 软件系统设计与调试 (45)4.2.1软件系统设计 (45)4.2.2软件系统调试与仿真 (47)5结束语 (49)参考文献 (50)致谢 (51)-2-河南理工大学毕业设计论文 1 概述1、概述1.1 毕业设计的选题背景及制作意义1.1.1毕业设计的选题背景单片机以其体积小、编程灵活、控制功能强大、价格低廉等特点被广泛地应用在各种电子电器产品中。
C51单片机 定时器可调时钟 程序
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
TempData[1]=dofly_DuanMa[hour%10];
TempData[2]=0x40;//加入"-"
TempData[3]=dofly_DuanMa[minute/10];//分
TempData[4]=dofly_DuanMa[minute%10];
TempData[5]=0x40;
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数unsigned char t,无返回值
unsigned char是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编
{
case 0xfe:return 1;break;
case 0xfd:return 2;break;
case 0xfb:return 3;break;
case 0xf7:return 4;break;
case 0xef:return 5;break;
case 0xdf:return 6;break;
显示函数,用于动态扫描数码管
输入参数FirstBit表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、LCD(LM044L)多功能可调时钟设计设计思路:利用单片机的定时器定时,产生时钟的时、分、秒,年、月、日,用LCD(LM044L)显示出时间的时、分、秒,年、月、日,并用英文显示“星期几”。
具有百分之一秒,秒,分,跑表功能。
一键开始并记录4组结果。
使用若干个按键调整时间,一个用于选择调整的时间位,一个用于调整时间。
也可以使用多个键,用于调整各自的时间位。
首先在proteus上绘制电路,编程模拟运行实现。
运行效果代码#include<reg51.h> //包含单片机寄存器的头文件#include<stdlib.h> //包含随机函数rand()的定义文件#include<intrins.h> //包含_nop_()函数定义的头文件sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚unsigned char code table[]="2011-12-01"; //初始化液晶显示10 unsigned char code table1[]=" 12:00:55"; //12 unsigned char code table2[]="week 3 00:00:00"; //15 unsigned char code table3[]="00:00:00 00:00:00 00:00:00 00:00:00"; unsigned char count,s1num,s5num;char second,minute,hour,day,month,year,week;char ms,sec,minu;sbit s1=P1^0; //功能键sbit s2=P1^1; //加键sbit s3=P1^2; //减键sbit s4=P1^3; //保存并退出sbit s5=P1^4; //秒表void delay1ms() //计算延迟1ms{unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}/***************************************************** 函数功能:延时若干毫秒入口参数:n***************************************************/void delay(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。
result=1,忙碌;result=0,不忙***************************************************/unsigned char BusyTest(void){bit result;RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态RW=1;E=1; //E=1,才允许读写_nop_(); //空操作_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间result=BF; //将忙碌标志电平赋给resultE=0; //将E恢复低电平return result;}/*****************************************************函数功能:写指令入口参数:dictate***************************************************/void WriteInstruction (unsigned char dictate){while(BusyTest()==1); //如果忙就等待RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令RW=0;E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,// 就是让E从0到1发生正跳变,所以应先置"0"_nop_();_nop_(); //空操作两个机器周期,给硬件反应时间P0=dictate; //将数据送入P0口,即写入指令或地址_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:写数据入口参数:y(为字符常量)***************************************************/void WriteData(unsigned char y){while(BusyTest()==1);RS=1; //RS为高电平,RW为低电平时,可以写入数据RW=0;E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,// 就是让E从0到1发生正跳变,所以应先置"0"P0=y; //将数据送入P0口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:对LCD的显示模式进行初始化设置***************************************************/void LcdInitiate(void){unsigned char num;second=55;minute=0;hour=12;week=3;day=1;month=12;year=11;count=0;s1num=0;s5num=0;ms=0;sec=0;minu=0;E=0;delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口delay(5); //延时5ms,给硬件一点反应时间WriteInstruction(0x38);delay(5);WriteInstruction(0x38); //连续三次,确保初始化成功delay(5);WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁delay(5);WriteInstruction(0x06); //显示模式设置:光标右移,字符不移delay(5);WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除delay(5);WriteInstruction(0x80);for(num=0;num<10;num++) //让液晶显示日期{WriteData(table[num]);delay(5);}WriteInstruction(0xc0);for(num=0;num<12;num++) //让液晶显示时间{WriteData(table1[num]);delay(5);}WriteInstruction(0x80+20);for(num=0;num<15;num++){WriteData(table2[num]);delay(5);}WriteInstruction(0xc0+20);for(num=0;num<17;num++){WriteData(table3[num]);delay(5);}TMOD=0x11; //定时器中断初始化TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;TH1=(65536-50000)/256;TL1=(65536-50000)%256;ET1=1;TR1=0;}//-------写年月日---------------void write_nyr(unsigned char add,unsigned char date){unsigned char i,j;i=date/10;j=date%10;WriteInstruction(0x80+add);WriteData(0x30+i);WriteData(0x30+j);}//--------写时分秒----------------------void write_sfm(unsigned char add,unsigned char date){unsigned char i,j;i=date/10;j=date%10;WriteInstruction(0xc0+add);WriteData(0x30+i);WriteData(0x30+j);}//-------------写星期----------------------------void write_week(unsigned char add,unsigned char date){WriteInstruction(0x80+10+add);WriteData(0x30+date);}void write_ms(unsigned char add,unsigned char date) //写毫秒{unsigned char i,j;i=date/10;j=date%10;WriteInstruction(0x80+10+add);WriteData(0x30+i);WriteData(0x30+j);}void write_mb(unsigned char add,unsigned char date) //记录跑秒时间{unsigned char i,j;i=date/10;j=date%10;WriteInstruction(0xc0+20+add);WriteData(0x30+i);WriteData(0x30+j);}//----------键盘扫描--------------------void keyscan(){if(s1==0) //第一个键是否按下{delay(5);if(s1==0){while(!s1);s1num++;if(s1num==1) //第一个键被按一次{TR0=0;WriteInstruction(0xc0+11);WriteInstruction(0x0f);}if(s1num==2){WriteInstruction(0xc0+8);}if(s1num==3){WriteInstruction(0xc0+5);}if(s1num==4){WriteInstruction(0x80+9);}if(s1num==5){WriteInstruction(0x80+6);}if(s1num==6){WriteInstruction(0x80+3);}if(s1num==7){WriteInstruction(0x80+20+5);//s1num=0; //循环一次}}}if(s1num!=0) //如果功能键被按下{if(s2==0) //第二个按下{delay(5);if(s2==0){while(!s2);if(s1num==1) //第二个键被按一次,秒钟加一{second++;if(second==60)second=0;write_sfm(10,second);WriteInstruction(0x80+0x40+11);}if(s1num==2) //第二个键被按二次,分钟加一{minute++;if(minute==60)minute=0;write_sfm(7,minute);WriteInstruction(0x80+0x40+8);}if(s1num==3) //第二个键被按三次,时钟加一{hour++;if(hour==24)hour=0;write_sfm(4,hour);WriteInstruction(0x80+0x40+5);}if(s1num==4) //日期加一{day++;if(day==32)day=1;write_nyr(8,day);WriteInstruction(0x80+9);}if(s1num==5) //月加一{month++;if(month==13)month=1;write_nyr(5,month);WriteInstruction(0x80+6);}if(s1num==6) //年加一{year++;if(year==99)year=0;write_nyr(2,year);WriteInstruction(0x80+3);}if(s1num==7) //星期加一{week++;if(week==8)week=1;write_week(15,week);WriteInstruction(0x80+25);}}}if(s3==0) //第三个键被按下{delay(5);if(s3==0){while(!s3);if(s1num==1) //秒减一{second--;if(second==-1)second=59;write_sfm(10,second);WriteInstruction(0x80+0x40+11);}if(s1num==2) //分减一{minute--;if(minute==-1)minute=59;write_sfm(7,minute);WriteInstruction(0x80+0x40+8);}if(s1num==3) //时减一{hour--;if(hour==-1)hour=23;write_sfm(4,hour);WriteInstruction(0x80+0x40+5);}if(s1num==4) //日减一{day--;if(day==0)day=31;write_nyr(8,day);WriteInstruction(0x80+9);}if(s1num==5) //月减一{month--;if(month==0)month=12;write_nyr(5,month);WriteInstruction(0x80+6);}if(s1num==6) //年减一{year--;if(year==-1)year=99;write_nyr(2,year);WriteInstruction(0x80+3);}if(s1num==7) //日期减一{week--;if(week==0)week=7;write_week(15,week);WriteInstruction(0x80+20+15);}}}if(s4==0) //保存并退出{s1num=0;WriteInstruction(0x0c);TR0=1;}}if(s5==0){while(!s5);TR1=1;s5num++;if(s5num==2){write_mb(0,minu);write_mb(3,sec);write_mb(6,ms);}if(s5num==3){write_mb(9,minu);write_mb(12,sec);write_mb(15,ms);}if(s5num==4){s5num=0;TR1=0;ms=0;sec=0;minu=0;write_ms(20,sec);write_ms(17,minu);write_ms(23,ms);write_mb(0,minu);write_mb(3,sec);write_mb(6,ms);write_mb(9,minu);write_mb(12,sec);write_mb(15,ms);}}}/********************************************************************** main function***********************************************************************/ void main(void){LcdInitiate(); //调用LCD初始化函数while(1){keyscan();}}/*******************************************************函数功能:定时器T0的中断服务函数********************************************************/void timer1() interrupt 3{TH1=(65536-10000)/256;TL1=(65536-10000)%256;ms++;if(ms==100){ms=0;sec++;if(sec==60){sec=0;minu++;}write_ms(20,sec);write_ms(17,minu);}write_ms(23,ms);}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;if(count==18){//ms=0;count=0;second++;if(second==60) //秒计满60,秒归0,分+1{second=0;minute++;if(minute==60) //分计满60,分归0,时+1{minute=0;hour++;write_led();if(hour==24) //时计满24,时归0,星期+1,日+1{hour=0;week++;day++;if(week==8) week=1; //星期计满7,星期归1if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) //大月三十一天{if(day==32) //大月天数计满31,日归1,月+1{day=1;month++;}}if(month==4||month==6||month==9||month==11) //小月三十天{if(day==31){ //小月天数计满30,日归1,月+1day=1;month++;}}if(month==13) //月计满12,月归1,年+1{month=1;year++;if(year==99) //年计满99,年归0{year==0;}write_nyr(2,year);}write_nyr(5,month);}write_nyr(8,day);write_week(15,week);}write_sfm(4,hour);}write_sfm(7,minute);}write_sfm(10,second);}。