ImageVerifierCode 换一换
格式:DOCX , 页数:43 ,大小:236.51KB ,
资源ID:2574127      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-2574127.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于AT89C51单片机的定时闹钟设计.docx)为本站会员(b****2)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

基于AT89C51单片机的定时闹钟设计.docx

1、基于AT89C51单片机的定时闹钟设计学号: 班级: 姓名:基于89C51单片机的电子闹钟设计一、设计要求(1)设计并实现一个具有计时功能的电子时钟系统,电子表的时间精确到秒,并可以显示年、月、日、时、分、秒。(2)利用液晶显示器显示定时器的日期和时间。(3)使用键盘进行设置时间和设置闹钟。(4)定时时间到通过蜂鸣器报警和发光二极管闪烁通知,并持续60s。二、硬件设计(1)系统设计框图(2)选择硬件设备单片机:选择AT89C51;液晶显示器:具有16字符显示功能的1601键盘:选择4行*4列的矩阵键盘LED:选择红色的发光二极管E2PROM:X2545图2时钟信号发生单元基本元件:蜂鸣器,电容

2、,晶体振荡器 ,电阻,开关电源:使用+5v直流稳压源基本模块的构成时钟信号发生单元如右图2利用晶振和电容以及单片机内部电路,构成晶体并联振荡器,产生12MHz的时钟频率复位电路如右图3利用一个简单的电容和按键实现图3复位单元电路实现对系统的复位功能由此基本模块可以实现最小的单片机系统(3)电子时钟硬件原理图图4硬件电路原理电路(4)主要器件的原理液晶显示原理液晶显示器种类繁多,按输出样式分为,图案式,数码式,点阵式。本设计方案利用的是点阵式液晶显示器,而液晶驱动方式又和数码管驱动截然不同,虽然比数码管需要更小的工作电压,但是其结构所需要的扫描方式较数码管来说,是比较复杂的,而且输入输出数据速度

3、慢,市场上是常用点阵式液晶驱动器的,常用的有1601、1602,“16”代表显示字符共有几列,“01”、“02”代表输出字符共有几行。下面是驱动1601的驱动方法。驱动1601的一个很重要的方面就是液晶显示器的初始化,主要是利用控制、数据复用总线来输入指令,进行初始化。基本操作读状态:输入:RS=L,RW=H,E=H 输出:D0D7=状态字写指令:输入:RS=L,RW=L,D0D7=指令码,E=高脉冲 输出:无读数据:输入:RS=H,RW=H,E=H 输出:D0D7=数据写数据:输入:RS=H,RW=L,D0D7=数据,E=高脉冲 输出:无状态字说明Sta7(读写操作能)D7Sta6D6Sta

4、5D5Sta4D4Sta3D3Sta2D2Sta1D0Sta0D01:禁止0:允许当前数据指针的数值利用Sta7可以用来检测当前驱动器是否处于忙状态,这样的话可以避免在忙状态的情况下,进行写数据会产生漏写的错误;或者可以利用延时,具体时间可以参照datasheet,一般都为几毫秒左右。初始化设置初始化时首先要进行写命令操作,然后按照datasheet的说明进行写指令显示模式设置指令指令使能指令码描述RSRWDB7DB6DB5DB4DB3DB2DB1DB0显示模式00001110005*7点阵显示,8位数据接口1)常用显示指令指令指令使能指令码描述RSRWDB7DB6DB5DB4DB3DB2DB

5、1DB0清屏0000000001数据指针清零所有显示清零回车0000000010数据指针清零显示控制0000001DCBD=1:开;D=0:关C=1:光标显示C=1:光标不显示B=1:光标闪烁B=0:光标不闪烁2)屏幕移动指令指令指令使能指令码描述RSRWDB7DB6DB5DB4DB3DB2DB1DB0入口方式设置00000001I/DSI/D=1:c increase;I/D=0:c decrease;S=1:整屏移动;S=0:指针或显示移动000001S/CR/L*S/C=0,R/L=0:指针左移显示不移S/C=0,R/L=1:指针右移显示不移S/C=1,R/L=0:显示和指针左移S/C=

6、1,R/L=1:显示和指针右移3)设置内部RAM地址指令指令使能指令码描述RSRWDB7DB6DB5DB4DB3DB2DB1DB0设置CGADDR0001AAAAAA对字符的点阵进行编程设置DDADDR001AAAAAAA设置显示数据存储器地址键盘扫描原理键盘分为编码键盘,和非编码键盘。编码键盘是靠硬件电路对每个键位进行编码,当有键按下时,输出固定的数码,并用来判断键位。常见的编码键盘如PC键盘;非编码键盘是指,键盘不是靠固定的编码来实现对键位的识别的,而是靠一定的算法来对键位进行扫描,矩阵键盘就是常见的一种非编码键盘。编码键盘一般需要较多的硬件电路,所以成本较非编码键盘较高,故一般的单片机系

7、统都采用非编码键盘,目的是充分利用单片机的丰富的软件资源,弥补硬件的不足。机械按键在按动的过程中,往往会产程抖动,这又是对一个控制系统的致命伤,因此必须采取措施消除抖动。目前,消除抖动的方法主要有两种:利用硬件RS锁存器进行消除抖动,将复杂跳变的信号变成稳定的信号;利用软件算法实现对抖动的排除,灵活性大,较常用,一般的,抖动的持续时间为数毫秒,所以为了简单起见,本设计方案利用延时来消除抖动。对于键盘的扫描常用的有逐行扫描法和线反转法。逐行或列扫描法的思路是,利用列线,做输入,行线做输出。首先使四根列线的某一根置零,当在此列的某一行有键按下时,该行线即为低电平,其余均为高电平,这样这个键就被编码

8、;然后再使另一列线置零,检测下一列是否有键按下;不断这样循环,就可以对整个键盘进行逐列扫描了。线翻转法的思路是,把列线当做线,所以,对其中某条线置低电平,其余为高电平,然后去读行线状态,那么线的状态和行的状态相连就是当前按下的键的键值,例如,线的状态为1011,读得行的状态为1101,则当前按键的键值为10111101。综观这两种方法,逐行扫描法,需要多次循环才能对整个键盘进行全扫描,速度慢,而且还有可能导致有些键检测不出,而线翻转法只需两句程序就可以扫描到键值,因此本设计采用先翻转法对键盘进行扫描。键名789编码值0x0EE0x0DE0x0BE0x07E索引值78915键名456编码值0x0

9、ED0x0DD0x0BD0x07D索引值45614键名123编码值0xEb0xDB0xBB0x07B索引值12313键名0编码值0x0E70xD70x0B70x077索引值1101210E2PROM原理 三、软件仿真设计(1)不同软件模块间的同步调度的总体设计本系统的软件部分的功能模主要有初始化模块、定时器模块、液晶显示模块、键盘扫描模块、键盘识别模块、模式转换模块、常用调用子程序模块。为了充分利用单片机的资源,对不同模块之间需要合理调度,对于只有一个任务的系统来说,实现该系统的程序往往是顺序执行的程序,各种模块之间也只是调用与被调用的关系,对于更复杂的系统,如菜单系统,也只不过是一个分支结构

10、,菜单反复在死循环里检查输入状态,一旦选中某个选项,马上跳入分支当中顺序执行,执行完毕后立即返回到菜单检测模块。对于这样的系统,往往不用考虑模块之间的并行关系,只需考虑顺序执行即可。但是对于本次实现的系统中定时器模块属于中断模块,独立于任何模块;液晶显示模块,键盘扫描模块,键盘识别模块,模式转换模块均为同步的模块(从宏观上讲,各个模块是同步执行的,从微观上讲,是各个模块之间通过一定的标志变量顺序执行的),而初始化模块,子程序调用模块为调用与被调用的模块,无需考虑它与其他模块之间的同步关系。现在介绍本次设计的各相互同步模块之间的调度关系。定时器模块为本设计最为独立模块主要又定时器0和定时器1构成

11、:定时器0工作在方式1,为50ms的定时器,中断服务程序中软计数为键盘扫描模块、计时器运算模块的执行标志变量置位。键盘扫描的执行可以是随机顺序执行或者时间片轮转方式执行,但是通过分析可以明确,随机顺序方法容易出现扫描失误。所以采用中断方式的时间片轮转法调度键盘扫描模块,实践证明30ms的周期扫描键盘调度较为合适,但是考虑到计时器的计数触发基本单元是依靠定时器0得到1s的脉冲,而定时器0为50ms的定时间隔,所以利用定时器0产生的每50ms的中断信号,进行为键盘扫描模块的执行标志变量置位。键盘扫描执行完毕后,进行键位判断,对于模式键的识别时,要调用模式变换模块。软件框图如下:(2)主要的功能模块

12、设计说明.应用的主要C语言关键字A位域的使用设计中会用到很多标志变量,状态控制变量,如果单单利用CHAR型变量,会有0255的个状态,会浪费很多存储器容量;所以这里使用位域,可以对一字节的某一位或者几位来操作,可以节省很多空间,利用一字节就可以设计出很多标志变量;然而对于状态变量,对状态变量会进行加减操作,往往还要判断是否溢出,而使用几位的位域变量来说,他的状态只在那几位所允许的状态,如3位,状态为07。 位域的声明方法: Struct 位域结构名 类型说明符 位域名: 位域长度; ; ;B.将数组声明成code类型的数据(Const) 数据类型名 code 变量名=,这样做可以节省较少的RA

13、M空间,利用较大的ROM空间。.初始化模块A.定时器模块初始化:定时器0和定时器1的初始化:定时器0工作在方式1,初值为#3CB0,定时时间为50ms;定时器1工作方式1,初值为#FB1E,定时时间为1.25ms,产生400hz的脉冲。B.液晶显示器驱动模块显示模式初始化,数据总线初始化,光标显示初始化,当输入数据时,光标和显示右移。C.标志变量初始化,系统变量初始化,状态变量初始化。.定时器模块键盘执行标志变量置位,计时器执行计数标志变量置位,闹钟检测模块执行标志变量置位.液晶显示模块反复对LcdStr字符数组进行扫描显示.键盘扫描模块利用线反转法进行扫描,调用keyscan()子程序。.计

14、时器模块主要包括闹表检测,闹表输出系统,冒号闪烁,闰年检测和月份检测,时间运算及时间显示。另外还有加减校时系统,当本系统工作模式0时,可进行加减校时,并可以进行转换,进而加减校分。.键位识别模块当检测到有键按下时,读取返回键的编码,利用Switch语句进行分支判断,利用各个键的索引进行判断,分别调用不同的模块。.模式变换模块模式共有四个模式分别为模式0、模式1、模式2、模式3;模式0:计时器模块,显示万年历功能,精确到秒,可以显示年月日,并可以进行加减校时,并可以像真正的电子时钟一样,“:”一闪一闪的显示,以体现秒的计时。模式1:闹表预置数定义,可以逐个置数,若置数值为非法值则显示错误信息,按

15、确定键返回,继续输入当前的闹表预置数;在预置数时,可以按“+/-”来设置当前设置的闹钟索引。模式2:可以直接定义当前的时间,只能定义时分秒,同样具有非法值检测,可以重新输入,输入正确后可以继续设置新值,或者转换到其他模式。模式3:显示已设置闹表的时刻值,同样利用“+/-”可以进行显示当前闹表时刻值的索引,进行加减变化对于这些模块中的可以输入的模块,可以利用“=”进行将已输入的值清空。常用的调用子程序模块常用的子程序有:延时子程序,键盘扫描子程序,清屏子程序,字符串复制子程序,显示子程序。(3)程序流程图四、系统总体功能实现具体功能:在开机时刻,欢迎界面滚动显示“welcome”,按“on/c”

16、进入正常模式。数字输入功能:在模式1,模式2可以进行手动输入时刻值。模式切换模式:按“除”号进行切换模式加减校时、校分的功能,并可以正常溢出返回初值。利用“*”进行时分切换校准。在闹表设置和显示的模式中,可以利用“+”,“-”进行选择设置闹表预置数的索引。键名789功能数字7数字8数字9切换工作模式键名456功能数字7数字5数字6确定/分时切换键名123功能数字1数字2数字3时刻减一/闹表索引减一键名0功能启动电子时钟数字0模式1/2清屏时刻加一/闹表索引加一键盘各键位的功能五、程序清单 /*电子时钟设计实验(fosc=6MHZ)*/#include reg51.h/extern char *

17、strcpy (char *s1, char *s2);sbit P3_0=P30;sbit RS=P33; /* 寄存器选择信号*/sbit RW=P34; /* 读/写控制信号 */sbit E =P35; /* 使能信号 */sbit CON=P36;sbit CLK=P37;sbit Acc_b=ACC7;/* 定义累加器的第七位*/sbit P0_0=P00;sbit sign=PSW5;unsigned char key_value;struct fg unsigned tim:1;/秒增一允许标志位 unsigned dip:1;/欢迎界面标志位 unsigned key:1;/

18、有键按下标志位 unsigned key1:1;/键盘扫描调度时钟标志位 unsigned mode:2;/状态模式控制 unsigned error:1;/写数据超出范围错误标志位 unsigned smart:1;/闹表信号翻转标志位 flag;struct ffg unsigned f1:1;/ unsigned clk:1;/ unsigned dm:1;/校时较分标志位 unsigned clock:3;/设置闹表时间索引 unsigned fclk:1;/ unsigned f:1;/ffg,ffg1;struct year unsigned ren:1; unsigned eve

19、n:1; unsigned er:1; unsigned odd:1; unsigned fff:4;y;unsigned char time,n,nn,sec,min,hour ,day, month ,cmin8=0,chour8=0;unsigned int year;const char code dday=32,31,30,29;const char code error=pleaseinputagain;const char code clock=CLOCK: ; const char code time1=settime:;const char code curclk=CURCL

20、OCK: ;unsigned int code tab=0xD7,0xEb,0xDB,0xBB,0x0ED,0x0DD,0x0bd,0x0EE, 0x0DE,0x0BE,0x077,0x0E7,0x0B7,0x07B,0x07D,0x07E; /*键码表*/unsigned char code lt=0x7f,0x0bf,0x0df,0x0ef; /*行扫描码*/unsigned char code digit=0xc0,0xf9,0xa4,0xb0;void delay(unsigned char n) unsigned char i,j; while(n-) for(i=0;i9;i+)

21、for(j=0;j11;j+) ; void strcpy(char *p1,char *p2) while(*p2!=0) *(p1+)=*p2; p2+; *p1=0;void Print(void) /*写指令子程序 */ unsigned char j; RW=0; /*RW=0,写指令*/ E=1; E=0; for(j=0;j+100;); /* 延时 */ return;void clear(char * p) char * pstr; pstr=p; while(*pstr!=0) *(pstr+)= ; pstr=p;void _clo_ck() interrupt 3 /f

22、fg.clk=ffg.clk; CLK=CLK; TH1=0xFB; TL1=0x1E; return;void timeint() interrupt 1 using 3 /*定时器0 中断程序,使用第3组寄存器*/ time-; /*循环次数减1*/ n- ; flag.key1=1; if(time=0) /*若循环值为0,则对P1.0取反*/ / ci bu wei fu zhu gong neng bu shi bi xu de time=20;/*恢复循环初值*/ flag.tim = 1; if(n=0) n=10; flag.smart=1; sign=sign; TH0=0x

23、3c; /*恢复计数初值*/ TL0=0x0b0; return; /*中断返回*/ char scankey(void) unsigned int i,a,b,y; P2=0x0f; /*行线输出低电平,并判断是否有键按下*/ i=0; /*行计数器清零*/ b=lti; for(i;i4;i+) /*取行扫描码*/ b=lti; P2=b; /*送行扫描码到P2口*/ a=P2; /*读入列值*/ a=a&0x0f; /*保留低4位*/ if(a!=0x0f) break; if(i=3) /*循环到该列有键按下为止*/ b=b&0x0f0; /*取行扫描码的高4位*/ b=b|a; /*

24、合并成为按键的扫描码*/ i=0; /*计数器清零*/ for(; b!=tabi; i+); /*在键值表中查找相应的键值*/ for(y=0; y2000; y+); /*延时,去抖动*/ key_value = i; for(P2=0x0f; P2!=0x0f;); /*判断按键是否结束*/ for(y=0; y2000; y+); /*延时*/ flag.key = 1; return(key_value); display(unsigned char temp) unsigned k; for(k=0;k+100;); RS=1; /*送出一个字母*/ RW=0; E=1; P1=t

25、emp; for(k=0;k+0;i-) E=1; E=0; for(j=0;j+100;); /* 延时 */ P1=0x38; /* 设置8位数据总线方式 */ print(); P1=1; /* 清屏指令01H */ Print(); /* 调向LCD写指令子程序*/ P1=6; /* 设置输入方式:AC加1计数,光标右移1个字符 */ Print(); /* 设置显示方式:开显示,光标显示 ;闪烁*/ P1=0x0c; Print(); E=1; E=0; /j=0; /*显示计数器*/ RS=0; RW=0; P1=1; /* 设置8位数据总线方式 */ print(); E=1;

26、E=0;void init(void) P0=0xc0; n=10; nn=12; flag.tim = 0; ffg.f1=1; ffg.clock=0; time_init(void) TMOD=0x11; /*设置计数器 0 工作方式1*/ TH0=0x3c; /*送计数器初值*/ TL0=0x0b0; TH1=0xFB; TL1=0x1E; ET1=1; TR1=1; EA=1; /*开中断*/ ET0=1; TR0=1; time=20; /*设置循环次数初值*/ / TR0=1; /*开始计时*/main() /*主程序*/ unsigned char i,j,k,m,p=0,vp; char LcdStr16= welcome ; /* 定义数组并初始化*/ char *pstr=LcdStr; m=10; lcd_init(); init(); time_init(); j=0; /*显示计数器*/ CON = 0; for(i=0;i16;i+) /*显示字母*/ / busy(); /*判忙*/ RS=1; /*送出一个字母*/ RW=0; E=1; P1=LcdStri; for(k=0;k+100;); /* 延时 */ E=0; j+; /*显示计数器加1*/ / if(j=8) /* 不到显示位置9跳转*/ / / for(k=

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2