为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

定时闹铃的设计

2017-09-19 11页 doc 129KB 44阅读

用户头像

is_337177

暂无简介

举报
定时闹铃的设计目录 1设计方案    1 1.1方案一    1 1.2方案二    1 1.3方案选择    1 2设计总体框图    2 3设计单元电路    4 3.1显示模块    4 3.2控制模块    4 4电路原理说明    5 4.1单片机    5 4.2数码管    5 5设计心得    6 6参考文献    6 附录:    7 附录1:调试报告    7 附录2:元器件清单    14 定时闹铃的设计 1设计方案 1.1方案一 本次课设是以89s51单片机为核心芯片,设计一个定时闹铃。使其能够显示定时的时间,且在定...
定时闹铃的设计
目录 1设计    1 1.1方案一    1 1.2方案二    1 1.3方案选择    1 2设计总体框图    2 3设计电路    4 3.1显示模块    4 3.2控制模块    4 4电路原理说明    5 4.1单片机    5 4.2数码管    5 5设计心得    6 6参考文献    6 附录:    7 附录1:调试报告    7 附录2:元器件清单    14 定时闹铃的设计 1设计方案 1.1方案一 本次课设是以89s51单片机为核心芯片,设计一个定时闹铃。使其能够显示定时的时间,且在定时时间到来时,可以使相应的发光二极管发光。在仿真实验中可是使用ISIS,Keil软件,并且还要画出硬件连接图。 系统采用Delay延时函数来计时,将用delay函数延时10us秒,然后在累计100000次使秒针加一来达到计时的作用。秒针变量加一后在通过if判断语句来进位,而时间到达23:59:59在给时间变量清零。定时功能采用判断按键是否按下来完成调节。 void delay10us(void)  //误差 -0.234375us {     unsigned char a;     for(a=2;a>0;a--); } 这样使编程变得简单,不同考虑中断的问题,但也有很多缺点。时间的显示函数与延时函数都在主函数内部,这样会使他们相互影响,使计时功能不准确,数码管的动态显示会出现闪烁。而且定时功能也不人性化,不方便观看。 1.2方案二 为了克服方案一的种种缺点,方案二采用定时中断。这样把计时模块独立起来就不会收到外接的影响,不仅使计时时间准确,而且还不影响数码管的动态显示。其定时器中断是定时器0方式1工作方式。其中断函数不仅要使秒针加一,还有给定时器相应的寄存器附初值以保证下一次计时正常。 但方案二加入了定时器中断就要编写相应中断初始化,附的初值要根据单片机的机器周期来计算出来。这些都会给编程带来一些工作量。 1.3方案选择 以上已经叙述了各个方案的优缺点。方案二是针对方案一设想的,可以很好的解决方案一的各种问题。当然方案二还有很多地方没有提到,下面将补充说明一下。 2设计总体框图 对于在给闹钟定时时,数码管就不能显示计时的时间了。为了人性化一些,应该显示定时的具体时间,并且定时时间要时针、分针、秒针分开定时。于是要有一个状态标志变量来实现,再加上显示时间状态,这个变量要有四个状态。同时定时动作有随机性,所以要用外部中断来改变状态标志变量。 void int0() interrupt 0 {            flag++;     flag=flag%4; } 对于闹钟是否该响,则需要一个判断模块。对于时间时针、分针和秒针6个变量采用6位数组的方法管理,同时对于定时的时间也采用相同的方法进行管理。则判断模块就是数组比较函数。 int s=0; if(flag==0)    //使定闹钟时不会是闹钟响 for(m=0;m<8;m++) s=s+TIME[m]-ALARM[m];led=1; 另外还有一些小问题还是要注意的。比如在对闹钟定时时,按键需要进行消抖。这样防止按错和按键太灵敏。消抖程序就是在检测到按键按下时,延时几个为毫秒,然后在检测相同的按键是否按下。这样的话,只有较长的按键按下信息可以接收,其他的短信号不会接受。而对于外部中断相连的按键则不需要这样的消抖,这是因为中断可以采用下降沿触发方式触发,这本身就可以起到消抖的作用。但如果不是仿真,而是用实体做这个实验,还是需要进行消抖,因为按键本身接触不良的话还是会有多个下降沿发生的。 中断函数也不能有太多程序以防影响到数码管的动态显示。因为单片机在没有中断时是正常运行主函数的;若有中断发生,则会停止主函数运行,进入中断函数中去。当中断函数运行完毕后再接着主函数停下的位置运行,所以会使主函数中发生顿卡的现象。 以下是改进后方案二的流程图。该流程图分为三个部分,一个主函数,一个定时器中断还有一个是外部中断。 定时分钟时钟调节 图1 方案二的流程图 3设计单元电路 3.1显示模块 图2是数码管的显示模块。其中数码管段选与P0口相连,而数码管的位选育P1口相连。单片机通过向P0口写入DIG_CODE数组的内容,向P1口写入WEI数组的内容来控制数码管显示的数组。 其中数码管的段选在与P0口连接之间还要有上拉电阻,因为单片机P0口自己不能使其端口变为高电平。而P1口则没有这种问题,所以不用上拉排阻。 图2 数码管的显示模块 3.2控制模块 图3是2个按键和1个开关组成的控制模块。其中sw1开关是开、关闹钟状态的开关,需要两个状态,所以不能用按键而用开关。在与P3.2连接的按键是调节flag状态量,其下降沿触发。由于触发的方式,所以不用消抖。而与P2.1是定时加一按键,是低电平触发需要消抖。 图3 按键控制模块 4电路原理说明 4.1单片机 AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,可稳定地工作于5V的电源下。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器。 P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。当P0口要求输出高电平时,必须在与外设的连线中有上拉电阻。 P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。 对于定时器中断采用方式一中断,是16位再填装减一计数器。对于11.0592MHz的单片机来说,需要走46080次机器周期才能到达一秒。 4.2数码管 led数码管(LED Segment Displays)由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。这些段分别由字母a,b,c,d,e,f,g,dp来表示;而八个公共电极排在在一起,然后编程为八个数来表示。因为数码管是单向导通的,所以当一位数码管选通时,不用担心其他数码管会发亮。 图4 七位数码管 5设计心得 在这次课设中,我使用isis仿真软件,keil单片机编译器来实现对定时时钟的仿真。让我在课堂外更深刻得运用了单片机,C语言以及数模电的相关知识。通过这次仿真,是我不仅巩固了书本的知识,更掌握了怎样思考来制作实物。 对于以上提到的知识点,我掌握的都很牢固,所以在做课设的时候游刃有余。知道了怎样实现数码管的动态显示,再加上C语言的相关知识(如怎样建立和管理数组,怎样实现秒分时钟的进位以及怎样实现两个数组的比较)就可以很好的编写程序进行仿真。 但编写中还需注意一些地方,这些都使我感到头疼,花了不少时间。一个是单片机的计时功能模块,本来我只是想到使用delay函数进行简单的延时,但发现这样做如果有外部中单时就会影响计时的准确性,然后还是改为定时器中断计时,这样把计时模块独立起来就不会收到外接的影响。还有一个是中断函数中语句的多少,我总结应该越少越好。因为在主函数中是个不断循环显示函数过程,且中断的发生时间是随机性的。若中断函数语句太多,会影响数码管动态显示。把中断的语句大多留在外面,只剩下一个改变标志变量的语句,然后再在主函数显示前加个判断语句就大大减少了对显示函数的影响。 另外在编写模块我又想到一些新的想法,可以使用新的芯片。如在显示模块中用液晶显示屏LCD1602来替代数码管,还有用外设DS1302这种专门针对计时设计的芯片来替代单片机的定时中断。这些我都尝试了,但由于时间有限,再加上对芯片的时序不是很了解就知道放弃了。 经过这次课设,我对于单片机的了解更深一步了。知道了P0口与其他端口的不同,P0口本身没有能力输出高电平。所以需要上拉电阻来对外输出高低电平。但是如果单片机的外设过多,则各个端口都需要这种上拉电阻才能带动各个外设。这也是51单片机的弊端,若是更高级的单片机则能驱动更多的外设。 6参考文献     [1] 张迎新.单片机原理、应用及接口技术.北京:国防工业出版社,1993     [2] 王青林,张伟,赵静波.Protel99se基础教程.北京:人民邮电出版社,2013     [3] 邓兴成.单片机原理与实践指导.北京:机械工业出版社,2010     [4] 阎石.数字电子技术基础.北京:高等教育出版社,2009 附录: 附录1:调试报告 在调试开始时,可以看到数码管显示时间。但数码管显示的时间是乱码的,但是他还是会随时间或按键按下而改变。我想对于计时功能和键盘按键应该没有问题,而数码管的乱码应该是程序的显示码型与数码管不匹配。共阴极还是共阳极没有完全弄清楚,我尝试让数码管显示码全部取反,然后再加载到程序中。这样果真解决了这种问题,使数码管正常显示。 并且时间是一秒加一的,时间的个个进位也是正常的。时间不会超过24小时,在满24小时后就会清零。与外部中断一相连的按键是调整数码管显示状态的,使时钟显示变为闹钟定时。接着按按键可以使闹钟定时从秒针、分针和时针调制,在相应的调整位上,按与P2.1相连的按键可以调制闹钟定时的多少。但不管是时间显示还是定时显示,数码管动态显示中,小时的最高位都会发生闪烁。 我想是因为在数码管动态显示之前会有许多if判断语句以及其它的赋值语句,有的是判断LED灯是否该亮,有的是判断数码管应该显示时间还是定时时间。这些都需要花时间。虽然这对开始的显示没影响,但程序总体是个大的死循环。所以会影响数码管最高位的延时时间的长短。会让最高位与其他位相比延时会长一些,这就会导致数码管最高位显示发生闪烁。 图5 时间显示 图6 闹钟LED灯发光 以下是最终方案的编程代码: #include #define uint unsigned int #define uchar unsigned char #define duan P1#define wei  P0 sbit setting=P3^2; sbit led    =P2^0; sbit add    =P2^1; sbit enable =P2^3; uchar code DIG_CODE[17]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40}; //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、|的显示码 uint WEI[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; uint TIME[8]={2,3,16,5,9,16,5,0}; uint ALARM[8]={0,0,16,0,0,16,0,0}; uint black=0; uint n,m; uint flag=0; void Delay(uint n) {int x,y;     for(x=0;x=20)     {         black=0;         TIME[7]++;     }} void Carry() {if(TIME[7]>=10)     {         TIME[7]=0;         TIME[6]++;         if(TIME[6]>=6)         {             TIME[6]=0;             TIME[4]++;             if(TIME[4]>=10)             {                 TIME[4]=0;                 TIME[3]++;                 if(TIME[3]>=6)                 {                     TIME[3]=0;                     TIME[1]++;                     if(TIME[0]>=2&&TIME[1]>=4)                     {                         TIME[0]=0;                         TIME[1]=0;                     }                     if(TIME[1]>=10)                     {                                                 TIME[1]=0;                         TIME[0]++;                     }                 }             }         }     } } void TimeDisplay() {     for(n=0;n<8;n++)     {                duan=WEI[n];         wei =DIG_CODE[TIME[n]];         Delay(8);        }    } void AlarmAddCarry() {     switch(flag)     {         case 1:    if(add==0)                 ALARM[7]++;                 if(ALARM[7]>=10)                 {                     ALARM[7]=0;                     ALARM[6]++;                     if(ALARM[6]>=6)    ALARM[6]=0;                 }                 while(add==0);                 break;         case 2:if(add==0)                 ALARM[4]++;                 if(ALARM[4]>=10)                 {                     ALARM[4]=0;                     ALARM[3]++;                     if(ALARM[3]>=6)    ALARM[3]=0;                 }                 while(add==0);                 break;         case 3:if(add==0)                 ALARM[1]++;                 if(ALARM[0]>=2&&ALARM[1]>=4)                 {                     ALARM[0]=0;                     ALARM[1]=0;                 }                 if(ALARM[1]>=10)                 {                                         ALARM[1]=0;                     ALARM[0]++;                 }                 while(add==0);                 break;     } } void AlarmDisplay() {     for(n=0;n<8;n++)     {         duan=WEI[n];         wei =DIG_CODE[ALARM[n]];         Delay(8);        }    } void main() {     Init();        while(1)     {             Led();         Addone();//black逢20进1秒         Carry();//时间进位         if(flag==0)                TimeDisplay();         else         {             AlarmAddCarry();//定时调节和进位             AlarmDisplay();//定时显示         }            }        } void time0() interrupt 1 {     TH0=(65536-46080)/256;     TL0=(65536-46080)%256;     black++; } void int0() interrupt 0 {    flag++;     flag=flag%4;} 附录2:元器件清单 AT89C51芯片                    1个 LED-RED                        2个 RESPPPACK-8排阻            1个 7SEG-MPX8-CA                1个 BUTTON开关                    2个 SW-SPST-MOM                1个
/
本文档为【定时闹铃的设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索