课程设计音乐倒数计数器引言随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它给人带来的方便也是不可置否的,人们对它的要求越来越高,要为现代人工作、科研、生活、提供更好的更方便的设施就需要从单片机技术入手,一切向着数字化控制,智能化控制方向发展。
本设计利用AT89C51单片机结合字符型LCD显示器设计一个简易的倒数计数器,可用来煮方便面、煮开水或小睡片刻等。
做一小段时间倒计数,当倒计数为0时,则发出一段音乐声响,通知倒计数终了,该做应当做的事。
1 项目概述和要求1.1 设计要求利用数字AT89C51单片机实现倒数计数器的功能,设定时间后在LED数码管上显示相应的时间。
其功能和性能指标如下:⑴字符型LCD(16×2)显示器,显示格式为“TIME 分分:秒秒”。
⑵用4个按键操作来设置当前想要倒计数的时间。
⑶一旦按下键则开始倒计数,当计数为0时,发出一阵音乐声。
⑷程序执行后工作指示灯LCD闪动,表示程序开始执行,按下操作键K1~K4动作如下:● K1---可调整倒计数的时间1~60分钟。
● K2---设置倒计数的时间为5分钟,显示“0500”。
● K3---设置倒计数的时间为10分钟,显示“1000”。
● K4--设置倒计数的时间为20分钟,显示“2000”⑸复位后LCD的画面应能显示倒计时的分钟和秒数,此时按K1键,则在LCD上显示出设置画面。
此时,若:●按K2键---增加倒计数的时间1分钟。
●按K3键---减少倒计数的时间1分钟。
●按K4键---设置完成。
1.2 设计方案音乐倒数计数器所倒数的时间由数字显示,控制器使用单片机AT89C51。
本设计基于单片机技术原理,以单片机芯片AT89C51作为核心控制器,通过硬件电路的制作以及软件程序的编制,设计制作出一个计数器,包括以下功能:输出时间,按下键就开始计时,并将时间显示在LCD1602显示器上。
当倒计数为0时,蜂鸣器就发出音乐声响等等。
该计数器系统主要由计数器模块、LCD显示器模块、蜂鸣器模块、键盘模块、复位模块等部分组成。
总体设计方框图如图1-1所示。
图1-1 总体设计方框图2 系统硬件电路设计2.1主控制器——AT89S51单片机AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。
AT89C2051是一种带2K字节闪烁可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除100次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU 和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。
AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
●与MCS-51 兼容● 4K字节可编程闪烁存储器●寿命:1000写/擦循环●数据保留时间:10年●全静态工作:0Hz-24Hz●三级程序存储器锁定● 128*8位内部RAM● 32可编程I/O线●两个16位定时器/计数器● 5个中断源●可编程串行通道●低功耗的闲置和掉电模式●片内振荡器和时钟电路2.2显示电路——LCD数码管采用静态显示,静态显示是指LCD显示某一屏字符时,时钟保持当前字符的显示,不使用移屏显示。
便于控制,同时能够满足正常的显示效果。
由于在显示中存在播放时间的动态变化,这样的话,即使是不产生整屏移动,也能给人动态感,也易于控制。
3 系统设计3.1电路原理图电路原理图如图3-1所示。
图3-1 电路原理图3.2元件清单3.2.1 AT89C51芯片AT89C51芯片图如下图3-2所示。
图3-2 AT89C51芯片①简介:AT89C51是一种带4K字节闪存可编程可擦除只读存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压、高性能CMOS8位微处理器,俗称单片机。
AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除1000次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。
AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
②主要特性:与MCS-51 兼容;4K字节可编程闪烁存储器;寿命:1000写/擦循环;数据保留时间:10年;全静态工作:0Hz-24MHz;三级程序存储器锁定;128×8位内部RAM;32可编程I/O 线;两个16位定时器/计数器;5个中断源;可编程串行通道;低功耗的闲置和掉电模式;片内振荡器和时钟电路。
3.2.2 字符型LCD1602字符型LCD1602如下图3-3所示。
图3-3字符型LCD16021602字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线。
VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,各引脚符号及其功能表如下表3-1所示。
引脚符号功能说明1 VSS 一般接地2 VDD 接电源(+5V)3 V0 液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比表3-1 LCD各引脚及其功能表3.2.3 按键控制模块按键用于控制数码显示、LCD显示、扬声器等模块的工作。
通过扫描按键是否按下,来设定各模块的工作情况,使各模块可以在按键的控制下,有序地进行工作。
设计中使用单个按键实现单个功能,属于较为简单的控制方式。
在多功能系统设计的试验中我们使用五个按键分别与单片机的p1.0、p1.1、p1.2、p1.3、p1.4相连。
通过按下相应的按键来处理相应的程序。
如下图3-4所示。
图3-4 按键控制模块图3.2.4 其它元件其它元件图如下图3-5所示。
图3-5 其它元件图4 系统软件程序设计4.1 程序流程图主程序开始初始化,然后扫描键盘、复位电路和计数器。
当键盘按键有按下时,调整计数器值,LCD显示新值。
当复位键有按下时,计数器复位为初值,重新倒计数。
当计数器值倒计为0时,蜂鸣器发出声音,计数器停止倒计,程序结束。
主程序流程图、LCD显示流程图和按键流程图分别如下图4-1、图4-2和图4-3所示。
图4-1 主程序流程图图4-3 按键流程图5 系统的仿真与调试5.1 硬件调试硬件调试分为静态调试和动态调试,对于硬件调试而言,只要认真焊接,硬件一般不会出现什么问题的。
静态调试一般采用的工具是万用表,它是在用户系统未工作时的一种硬件检测。
动态调试是在用户系统工作的情况下发现和排查错误的一种硬件检测。
调试步骤是:首先把电路分为若干模块,调试过程中与该模块无关的元件可以不加考虑,这样可把故障限定在一定的范围内;故障清除后,把各个模块合在一起进行联调,即可完成整个硬件调试工作。
5.2 软件调试软件调试是通过对程序的汇编、连接、执行来发现程序中存在的语法错误与逻辑错误并加以排除纠正的过程。
5.3 软硬件调试软硬件联调是指把调试无误的软件程序烧制进单片机芯片内部,通上电源后,检查硬件工作是否有预期的效果,如果没有则需要检测软件是否在实现功能上有欠缺。
若有错误,通过改写软件来调试,直至达到预期效果,则设计圆满成功。
本课程设计调试结果如下图5-1所示。
图5-1课程设计调试结果5总结经过这次的的课程设计,简单带有LCD显示的音乐倒数计数器基本完成,系统基本功能基本实现,测试运行也基本正常。
该系统基本上完成了日期的显示与计数的功能。
当然这个系统还存在许多有待完善的地方:▲功能相对较少,有待于添加,比方说时钟与闹钟功能;▲界面设计得不够精致完美;这次课程设计的时间虽然不算很长,但使我对很多东西有了更深刻的认识。
总结如下:●查阅资料和阅读相关文献的重要性。
●向同学请教的重要性,团结协作的重要性。
●勤动手的重要性,自己动手,丰衣足食!在一次次调试代码的过程中,我才明白“代码不是写出来的,是调出来的”的道理。
●对待任何事情都要有耐心和恒心,遇到问题要冷静地思考,积极找出症结所在,逐个解决。
通过本次课程设计,我更深刻的认识到了教学实践在大学课程中的重要性,同时也发觉到了自己在学习方面存在的许多不足之处,在以后的学习中我会努力改进这些不足,不断提高自己的动手实践能力。
附件源程序#include<reg52.h>#include<intrins.h>#define time 100#define uint unsigned int#define uchar unsigned charuint t,flag,flag0,flag1,flag2,flag3,flag4,flag5,minute,second=60; uchar num,j,i,k=0;uchar code table[]="TIME 00:00";uint code table1[]={64580,64684,64777,64820,64898,64968,65030};sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;sbit P1_5=P1^5;sbit RS=P2^0;sbit RW=P2^1;sbit E=P2^2;sbit led_red=P2^3;void write_time(uint addr,uint date);/////////延时函数///////void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}///////延时1S////////////void delay1(void){uchar a,b,c;for(c=13;c>0;c--)for(b=247;b>0;b--)for(a=142;a>0;a--);_nop_;}////////1602写命令函数//////void write_com(uchar com){RS=0;P3=com;delay(5);E=1;delay(10);E=0;}//////1602写数据函数//////void write_date(uchar date){RS=1;P3=date;delay(5);E=1;delay(10);E=0;}//////按键1处理函数///////void KEY1(){while(flag1){if(key2==0){delay(time);if(key2==0){if(minute<=60)minute=minute+1;write_time(7,minute);}}if(key3==0){delay(time);if(key3==0){if(minute>0)minute=minute-1;write_time(7,minute);}}if(key4==0||key5==0){delay(150);if(key4==0||key5==0){flag1=0;flag =1;TR0=1;}}}}//////按键2处理函数////// void KEY2(){minute=5;write_time(7,minute);while(flag2){if(key5==0){delay(time);if(key5==0){flag2=0;flag =1;TR0=1;}}}}//////按键3处理函数////// void KEY3(){minute=10;write_time(7,minute);while(flag3){if(key5==0){delay(time);if(key5==0){flag3=0;flag =1;TR0=1;}}}}//////按键4处理函数//////void KEY4(){minute=20;write_time(7,minute);while(flag4){if(key5==0){delay(150);if(key5==0){flag4=0;flag =1;TR0=1;}}}}void write_time(uint addr,uint date) {uint ge,shi;ge=date%10;shi=date/10;write_com(0x80+addr);write_date(0x30+shi);write_date(0x30+ge);if(addr==7&&date==0)j=1;if(j==1&&addr==10&&date==0){flag0=1;TR0=0;TR1=1;flag5=1;}}//////初始化函数//////void init(){P1=0xff;RW=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x80);TMOD=0x11;TH0=(65536-50000)/256;TL0=(65536-50000)%256;TH1=0xfc;TL1=0x44;ET1=1;ET0=1;// TR1=1;// TR0=1;EA=1;flag0=1;for(num=0;num<12;num++){write_date(table[num]);delay(20);}}void start(){if(key1==0){delay(time);if(key1==0){flag0=0;flag1=1;KEY1();}}if(key2==0){delay(time);if(key2==0){flag0=0;flag2=1;KEY2();}}if(key3==0){delay(time);if(key3==0){flag0=0;flag3=1;KEY3();}}if(key4==0){delay(150);if(key4==0){flag0=0;flag4=1;KEY4();}}}void write_time0(){minute=minute-1;write_time(7,minute);write_time(10,59);flag=0;}void counter(){if(t==20){led_red=led_red^1;if(flag==1)write_time0();t=0;second=second-1;write_time(10,second);if(k==1&&second==59){if(minute>0)minute=minute-1;write_time(7,minute);}if(second==0){k=1;second=60;}}}int main(){init();while(1){while(flag0)start();counter();while(flag5){delay1();i++;if(i>7)i=0;}}return 0;}void inter0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;t++;}void initer1() interrupt 3{TH1=table1[i]/256;TL1=table1[i]%256;P1_5=~P1_5;if(key5==0){delay(100);if(key5==0){TR1=0;flag5=0;k=0;j=0;}}}。