《495202684单片机课程设计(论文)校园作息时间控制系统(.doc》由会员分享,可在线阅读,更多相关《495202684单片机课程设计(论文)校园作息时间控制系统(.doc(37页珍藏版)》请在三一办公上搜索。
1、目录1 系统设计方案与论证321设计要求322系统设计总体方案.32系统的硬件设计与实现.4211时钟芯片DS12887性能简介.4212时钟芯片读写时序.6213 时间寄存器地址6214 特殊控制寄存器功能7221 液晶SYB12864介绍8222 液晶与单片机的接口8223 液晶写操作时序9231 红外发送与接收10232 遥控码数据分析10233 接收电路11241电源部分电路图 113程序设计 123 主程序流程图122 按键识别.1333 课表计算1334 遥控解码144系统测试与总结 16附录1主要元器件清单.17附录2程序清单.18附录3原理图与印制板图. 35附录4系统使用说明
2、. 36附录5系统实物图片. 371系统设计方案与比较设计要求一、时钟功能:能显示年、月、日、星期、时、分、秒 二、调整功能:能校正年份、日期、时间等三、打铃功能:按指定时间表播放音乐、现场修改作息时间表四、设置的作息时间表数据在单片机掉电后不会丢失2系统设计总体方案 根据设计要求实现的功能,可以采用不同的设计系统方案如下:方案一:采用单片机自带定时器进行计时,外加存储器保存课表数据,普通键盘输入。由于单片机进行软件计时,硬件成本比较低,但是误差比较大,需要校准,日后的维护工作量比较大。可用廉价的AT24C04等存储器保存数据,读写比较容易。对于普通的独键盘,设置量比较大,改用矩阵键盘又会占用
3、较大的电路板空间。方案二:采用实时时钟芯片计时,红外数据输入。时钟芯片常见的有美信公司的DS1302、DS12887等前者与后者的最大区别在于有没有自带的备份电池。前者需要增加额外的电池以及相关的充电电路,后者DS12887本身已经集成了锂电池,而且掉电后相当长一段时间还可以正常走时,最重要的是它还剩下114字节的非易失RAM,由于有备份电池供电,相当于一个存储器,可以充分利用,而不需要增加另外的存储器,减少了外围电路。电视红外遥控比较常见,只要解码出来,可以充分利用面板上的多个数字键,接收电路也相当简单,另外由于是非接触式按键,避免了普通机械按键的磨损弊端。故本设计选用第二种方案总体方框图如
4、下:单片机89S52时钟芯片DS12887红外接收头遥控液晶显示蜂鸣器系统的硬件设计与实现1时钟芯片DS12887性能简介11 时钟芯片特点功能简介及引脚分布如图: 12读写时序13时间寄存器地址值得注意的是上表中最后的寄存器地址0EH-7FH,这里就是剩余的144字节RAM,在本设计中实际使用的是10H13H四个字节,用于保存课表上午和下午的起始数据。214 特殊控制寄存器功能22液晶显示块部分电路221液晶SYB12864功能与技术参数简介 SYB12864是一种图形点阵液晶显示器,它主要由行驱动器/ 列驱动器及12864全点阵液晶显示器组成.可完成图形显示,内置汉字库,可以显示84个(1
5、616点阵)汉字.主要技术参数和性能:1.电源:VDD:+5V;LCD外接驱动电压为 3.08.0V 2.显示内容:128(列)64(行)点3.全屏幕点阵4.七种指令5.与CPU接口采用8位数据总线并行输入输出和8条控制线.222液晶与单片机接口 外部接口信号如下表所示:管脚号管脚名称LEVER管脚功能描述1VSS0V电源地2VDD5.0V电源电压3V0-液晶显示器驱动电压4RSH/LRS=“H”,表示DB7DB0为显示数据RS=“L”,表示DB7DB0为显示指令数据5R/WH/LR/W=“H”,E=“H”,数据被读到DB7DB0R/W=“L”,E=“HL”, DB7DB0的数据被写到IR或D
6、R6EH/L使能信号:R/W=“L”,E信号下降沿锁存DB7DB0 R/W=“H”,E=“H” DRAM数据读到 DB7DB0 7DB0H/L数据线8DB1H/L数据线9DB2H/L数据线10DB3H/L数据线11DB4H/L数据线12DB5H/L数据线13DB6H/L数据线14DB7H/L数据线15PSBH/LH:8或4位并口,L串口(本设计中硬件置高电平)16NC17RETH/L复位信号,低电平复位(如不需要经常复位可以悬空)18VOUT10VLCD驱动电压19LED+-LED背光板电源20LED-LED背光板电源数据线D0D7与单片机P0口相连,完成数据传送。单片机P1.0与液晶RS相连
7、,控制显示数据和显示指令数据. 单片机P1.1与液晶RW相连,控制数据读写. 单片机P1.2与液晶E相连,液晶REST与电源相连,控制液晶复位信号。18脚是液晶背光驱动端,通过限流可变电阻调节对比度,由于经过试验测量可变电阻大概是16K,为了方便电路布局,用15K的固定电阻。液晶与单片机接口图223液晶写操作时序写操作时序R/W为低电平,CS为低电平写入指令,R/W为低电平,CS为高电平写入数据23红外遥控231 发送与接收通用红外遥控系统由发射和接收两大部分组成。应用编/解码专用集成电路芯片来进行控制操作,如图 所示。发射部分包括键盘矩阵、编码调制、LED 红外发送器;接收部分包括光、电转换
8、放大器、解调、解码电路。232 遥控码数据分析遥控发射器专用芯片很多,这里我们以运用比较广泛,解码比较容易的一类来加以说明,以东芝公司的TC9012组成发射电路为例说明编码原理。当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。这种遥控码具有以下特征:采用脉宽调制的串行码,以脉宽为 0.565ms、间隔0.56ms、周期为1.125ms 的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms 的组合表示二进制的“1”,其波形如图 所示。遥控码的“0”和“1” 上述“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制,然后再通过红外发射
9、二极管产生红外线向空间发射。一般电视遥控器的遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。后16位为8位的操作码和8位的操作反码,用于核对数据是否接收准确。根据红外编码的格式,发送数据前需要先发送4.5ms的起始码和4.5ms的结果码作为引导码。遥控串行数据编码波形如下图所示:233接收电路接收电路较为简单,采用一体化接收头HS0038,滤波电容在这里可以减少电源带来的干扰。如图:24电源233接收电路241电源部分电路图为达到提供稳定5V供电电压,变压器采用了玩具车电池充电适配器,由于此电源只包含了全波整流电路,在此加上滤波
10、电路和稳压电路,如图。3系统的软件设计31主程序流程图主程序流程图:读取课表数据并计算读取时间欢迎界面时钟与液晶复位上电显示时间比较课表True显示课次,播放音乐FalseTrue键扫退出菜单选择修改课表选择查看课表选择调整时间调整时间上午课表修改课表保存设置下午课表保存设置32按键识别为了输入简单,用数字键直接输入要设置的数字,而且没有另外设置专门的光标移位键,即输入一个数字后自动换到一个位置,如果有现成的不需要修改的数字,可以直接按任意非数字键跳过。由于进行年月日等数据的保存时是以两个键为一个单位(比如23),由此将产生一个问题,怎样保存无效的键值,即如果第一个键是无效键或者第二个键是无效
11、键,这个数据怎么保存。具体解决办法如下:从遥控按键解码结果可知,键值和数字键的数字对应关系为:如果键值小于9(0x09),按键数字就是键值加上1,而键值9对应按键“0”。所以两个按键的要分九种情况,第一个按键有三种情况,无效键,19键,0键,第二个键也有三种情况,考虑到第二个键有可能是无效键,所以按第一个键(十位)时候要保存个位数字,具体赋值如下:(以年为例,year0,year1,year2分别是原值、第一次按键后赋值、第二次按键后赋值)第一个按键后赋值如下表:key 9(无效键)year1 = year0key 9(19键)year1 = 10*( key +1)+year0%10key
12、= 9(0键)year1 = year0%10第二个按键后赋值如下表:第一个键第二个键赋值无效键0键year2= year1/10*1019键0键year2= year1/10*100键0键year2= year1/10*10 为方便编程没有用year2= 0无效键19键year2= year1/10*10 + key+119键19键year2= year1/10*10 + key+1 0键19键year2= key+1无效键无效键year2= year119键无效键year2= year10键无效键year2= year1事实上第二个键是无效键的情况在刚开始已经考虑,所以键值不变,可以不做处
13、理。33课表计算以上午为例,当设定好第一节课上课时间,以后的时间在此基础上往上加。第一节课下课第二节课上课第二节课下课第三节课上课第三节课下课第四节课上课第四节课下课小时增量0012223分钟增量4555400455540实际编写程序计算时,为了对齐,插入了无效的0值,当然如果schedule1表同样采用二维数组可避免此弊端,这也是当时编程时候总体设计考虑不周造成的,以至于要修改就要改动其很多的数据。34 遥控解码具体解码过程如下:通过定时器读出相应的高低电平,先读出低电平,再读出高电平,如果中间有非正常的值则重新接收。每八个位为一个字节数据,总共四个有效数据,最后在数码管上显示。#inclu
14、de #define c(x) (x*110592/120000)/便于数据分析sbit Ir_Pin=P36;/接收管脚unsigned char code Led_Tab=0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E; /共阳极数码显示码0-F.unsigned char code Led_Sel=0xfe,0xfd,0xfb,0xf7; /显示位控unsigned char Led_Buf4; /显示缓冲区unsigned char Led; /位选unsigned char
15、 Ir_Buf4; /用于保存解码结果/=timer0() interrupt 1 using 1 /防止按键时 LED显示闪烁 TL0=(65536-1000)%256; TH0=(65536-1000)/256; /定时器0设定约1000us中断一次,用于数码管扫描 P0=0xff; P2=Led_SelLed; /位选 P0=Led_TabLed_BufLed; /段选 if(+Led 3) Led =0; /四个扫描完了,到第一个数码管/=unsigned int Ir_Get_Low() /获取低电平时间 TL1=0; TH1=0; TR1=1; while(!Ir_Pin ); /
16、当P3.6为低 等待 TR1=0; return TH1*256+TL1;/=unsigned int Ir_Get_High() /获取高电平时间 TL1=0; TH1=0; TR1=1; while(Ir_Pin ); /当P3.6为高 等待 TR1=0; return TH1*256+TL1;/=main()unsigned int temp;char i,j;TMOD=0x11;TL0=(65536-1000)%256;TH0=(65536-1000)/256; /定时器0设定约1000us中断一次,用于数码管扫描EA=1;ET0=1;TR0=1;while(1) restart: w
17、hile(Ir_Pin); temp=Ir_Get_Low();/允许有一定的误差 if(tempc(5000) continue; /引导脉冲低电平4500 temp=Ir_Get_High(); if(tempc(5000) continue; /引导脉冲高电平4500 for(i=0;i4;i+) /4个字节 for(j=0;j8;j+) /每个字节8位 temp=Ir_Get_Low();/560us 低电平 if(tempc(800) goto restart; temp=Ir_Get_High();/560us 或 1680us 高电平 if(tempc(2000) goto re
18、start; Ir_Bufi=1; /先写“0” if(tempc(1120) Ir_Bufi|=0x80; /再写“1” Led_Buf0=Ir_Buf2&0x0f; /低四位数据码 Led_Buf1=Ir_Buf24; /高四位数据码 Led_Buf2=Ir_Buf0&0x0f; /低四位系统码 Led_Buf3=Ir_Buf04; /高四位系统码 解码结果如下,系统码为0x0E(由于设置键和屏显键的键值相同,故有同样的功能)4总结经过各方面的测试,达到设计的要求。一、在系统硬件的设计方面,充分考虑了电路元器件的布局,整个系统板小巧精致。刚开始用万能板做实验时,红外接收头由于没有使用滤波电
19、路,抗干扰能力比较弱,单片机容易进入死机状态,经过改进后,恢复正常,只有极少数情况下会出现死机,可能是电源干扰所致,如果加入看门狗电路可以避免死机。在设计的过程中,曾遇到了许多的问题,比如内存溢出、液晶的判忙、按键识别、菜单设置等,经过了大量的调试修改工作,得以解决,在这过程中积累了宝贵的经验。二、本设计还可以进一步改进和添加新的功能1、加入温度测量。采用DS18B20,只占用一根单片机口线,精度也比较高。2、闹钟功能。DS12887上自带闹钟功能。如果只是用来做普通的闹钟,实用性不强,其实在本设计中可以用来打铃,只要把课表计算好,每次上课或者下课后由单片机自动把下一个打铃点设置为闹钟,这样就
20、不用单片机来比较打铃点。3、加入液晶屏保功能。在没有操作时把液晶电源关掉,当有按键出现时点亮液晶,可以延长液晶使用寿命,还可以节省电能。不过具体操作时候必须把液晶的电源和地线全部断开。4、添加任意打铃点,并可以删除。其实还有一百多字节的非易失RAM剩余,可以保存数据。附录1:主要元器件清单序号名称型号,规格数量备注1单片机AT89S521AT89S522电阻色环电阻10k1k20015k1211误差10%3电容0.1uF,470uF10 uF33p,0.01 uF1000 uF221211104470 uF /25V10 uF /10v1031000uF /10V4三极管90121PNP5蜂鸣
21、器16时钟芯片DS12CR8871DS12CR8877电视遥控器1TC90128液晶128641128649单片机插座40座1DIP4010插座单排插座1SIP2011排阻10K1103J12发光二极管红色发光二极管13直流插座1三脚直流座14晶振112MHZ16稳压管LM78051LM7805附录:程序清单#include #define uchar unsigned char#define uint unsigned intuchar week,key,high;/12864液晶操作口sbit rs = P10; sbit rw = P11;sbit en = P12;/ds12cr887
22、操作口sbit ds = P33; sbit Rw = P32;sbit as = P31;sbit cs = P30;sbit Ir_Pin=P35; /红外接收uchar Ir_Buf4; /保存解码数据bit enable = 1;/允许进入设置菜单bit flag;/音乐开关sbit buzzer = P36;/蜂鸣器uchar code schedule0213= 0, 0, 0 ,0, 1 , 0, 2, 0, 2 , 0, 2 , 0, 3 , /课表小时增量 45,0, 55,0, 40,0, 0, 0, 45,0, 55,0, 40;/课表分钟增量uchar table6;/
23、依次为 年月 日 时 分 秒uchar table14;/依次为设置课表 上午*时*分,下午*时*分uchar idata schedule116;/上午课表uchar idata schedule216; /下午课表uchar idata displayschedule1413;/上午课表 显示缓冲区uchar idata displayschedule2413;/下午课表 显示缓冲区uchar code ytable=2,4; /显示 第二行 第四行坐标uchar code xtable=1,2,4,5,7,8;/显示 列设置时间显示位置uchar code xtable1=2,3,5,6
24、;/显示 列 设置课表显示位置/=延时=void delay(uint m) while( m-);/=/* 液晶 */=判忙= void checkbusy() rs=0; rw=1; P0=0xff; while(1) en = 1;if(P0 0x80)break;/P0的最高位为忙标志为,H:忙,L:空闲 en = 0; en=0;/=液晶写指令=void writecommand(uchar command) checkbusy(); rs=0; rw=0; en=1; P0=command; /液晶数据线P0 en=0; /=液晶写数据=void writedata(uchar d
25、ate) checkbusy(); rs=1; rw=0; en=1; P0=date; en=0; /=液晶设置= void lcdset(void) writecommand(0x30); /基本指令集 writecommand(0x01); /清屏,DDRAM的地址归零 writecommand(0x02); /地址归位 writecommand(0x0c); /显示开,光标关,反白关 writecommand(0x06); /DDRAM地址加1 /=设置光标=void cursor(uchar y,uchar x)uchar command = 0x80;writecommand(0x
26、0f);/开光标 闪烁 if( y = 2) y = 3; else if(y = 3) y = 2; command |= (y-1) 3; command += (x-1); writecommand(command); /=设置反白=void convert(uchar yy) /反白一行 uchar x,y,i,j; y=0x80; x=0x80; writecommand(0x36); /绘图开 for (i=0;i32;i+) writecommand(y+);writecommand(x); for (j=0;j16;j+) writedata(0x00); y=0x80; x=
27、0x88; for (i=0;i32;i+) writecommand(y+); writecommand(x); for (j=0;j2) x= 0x88; y=( yy-3 )4)+0x80; else x=0x80; y=(yy-1)4)+0x80; writecommand(0x36); for (i=0;i16;i+) writecommand(y+);writecommand(x); for (j=0;j16;j+) /一行宽度是16的点 writedata(0xff); writecommand(0x30); /=字符显示=void display(uchar y, uchar
28、x, uchar *p) switch (y) case 1:writecommand(0x7f+x); break; /液晶第一行 case 2:writecommand(0x8f+x); break; /0x90+(x-1) case 3:writecommand(0x87+x);break; case 4:writecommand(0x97+x);break; default:break;while(*p) writedata(*p+); /=显示数字=void displayNumber(uchar y,uchar x,uchar number)switch (number)/引号内数
29、字为中文全角输入 占据一个汉字位置case 0:display(y,x,);break; case 1:display(y,x,);break; case 2:display(y,x,);break;case 3:display(y,x,);break;case 4:display(y,x,);break;case 5:display(y,x,);break;case 6:display(y,x,);break;case 7:display(y,x,);break;case 8:display(y,x,);break;case 9:display(y,x,);break;default:bre
30、ak; /=显示星期=void displayweek (uchar week)switch (week)case 1: display(3,3,一);break;case 2:display(3,3,二);break;case 3:display(3,3,三);break;case 4:display(3,3,四);break;case 5:display(3,3,五);break;case 6:display(3,3,六);break;case 7:display(3,3,日);break; default: break;/=显示课次=void displaylesson (uchar l
31、esson)switch (lesson)case 1: display(3,5,第一节课);break;case 2:display(3,5,第二节课);break;case 3:display(3,5,第三节课);break;case 4:display(3,5,第四节课);break;case 5:display(3,5,第五节课);break;case 6:display(3,5,第六节课);break;case 7:display(3,5,第七节课);break; case 8:display(3,5,第八节课);break; default: break;/=显示菜单=void m
32、enu (void)writecommand(0x01);/清屏 display(1,3,设置时间);display(2,3,查看课表);display(3,3,修改课表);display(4,3,退出菜单 ); /=显示时间= void displaytime0(void) /静态数据 display(1, 2, 校园作息系统);display(2, 3, 年);display(2, 6, 月); display(3, 1, 星期); display(4, 3, ); /全角输入display(4, 6, ); void displaytime1(void) /动态数据displayNumb
33、er(2,1,table0/10);displayNumber(2,2,table0%10);displayNumber(2,4,table1/10);displayNumber(2,5,table1%10);displayNumber(2,7,table2/10);displayNumber(2,8,table2%10);displayweek(week);displayNumber(4,1,table3/10);displayNumber(4,2,table3%10);displayNumber(4,4,table4/10);displayNumber(4,5,table4%10);displayNumber(4,7,table5/10);displayNumber(4,8,table5%10); /=/* 红外 */=取回低电平=uint Ir_Get_Low()TL1=0;TH1=0;TR1=1;while(!Ir_Pin );/等待高电平到来TR1=0;return TH1*2