片单机原理及应用课程设计学校作息时间控制系统设计--大学毕设论文.doc
单片机课程设计报告系部: 电子与通信工程系 专业年级班级:课 题 名 称 :学 生 姓 名:学 号:指 导 老 师 : 成 绩 评 定: 单片机原理及应用课程设计任务书系(部): 专业: 指导教师:XX课题名称学校作息时间控制系统的设计设计内容及要求(1)课题内容:以单片机为核心,设计一个智能化作息时间控制器。该控制器要求的功能有:按本校作息时间接通/断开电铃;并用B3区的12864液晶屏的第一行显示本人的姓名和学号,第二行显示实时时钟。作息时间控制器用于学校教学楼的时间控制,利用单片机内部定时器实现时间基准定时,显示的内容要求有时、分、秒各两位,并能调节小时和分钟。发挥部分:可以通过键盘任意调整响铃时间。(2)要求:完成该系统的硬件和软件的设计,在Proteus软件上仿真通过后,下载到DP-51PROC单片机实验箱验证。最后就课程设计本身提交一篇课程设计说明书。设计工作量1、汇编或C51语言程序设计;2、程序调试;3、在Proteus上进行仿真后,进行下载;4、提交一份完整的课程设计说明书,包括设计原理、程序设计、程序分析、仿真分析、调试过程,参考文献、设计总结等。进度安排起止日期(或时间量)设计内容(或预期目标)备注第一天课题介绍,答疑,收集材料,C51介绍第二天设计方案论证,练习编写C51程序第三天第六天程序设计第六天第八天 程序调试、仿真第九天第十天系统测试并编写设计说明书教研室意见年 月 日系(部)主管领导意见年 月 日 目 录一设计原理5(1)总体设计:5(2)分模块设计:5(3)设计示意图5二程序设计6(1) LCD显示模块程序9(2)温度模块程序12(3)时间模块程序15(4)声音模块程序16(5)调节模块程序17(6)主函数19三仿真分析19(1)调节工作模式:20(2)闹铃实现:22(3)温度测量:22四设计心得23五参考文献23一设计原理(1)总体设计:首先对设计要求有个整体的了解,明白需要实现哪些功能,实现这些功能需要哪些元器件,要驱动这些元件需要编写什么程序,最后进行总体调试。本次作息时间的设计,使用了单片机AT89C51,LCD为AMPIRE12864,温度元件为DS18B20,还有一个声音播放器SOUNDER。对于LCD和DS18B20 要进行初始化。将本次设计分成5个模块分别进行设计,分成:温度模块 、LCD显示模块、时间模块、声音模块、调节模块。分模块设计好了以后,再综合起来设计主程序main(),实现所需要求。(2)分模块设计:1.LCD显示模块设计:该模块包括的函数为LCD_inti()/LCD 的初始化、 checkbusy()/检查LCD是否忙碌、 writecode() /写命令、 writedata() /写数据、 hanzi()/显示汉字、 zifu()/显示数字或字符。2.温度模块设计:该模块的函数为inti()/DS18B20的初始化、 readchar()/读一个字节、writechar()/写入一个字节、readtemp()/读取温度 、worktemp()/温度计算。3.时间模块设计:本次是采用T0中断的工作方式1获取时间的。其函数为void timer() interrupt 1 /T0中断函数 、workhour()/时间计算。4.声音模块设计:该模块比较简单,其函数为void s_fmq()/蜂鸣器叫 、nling()/判断是否闹铃。5.调节模块设计:该模块要实现5个模式的调节和转变。模式0:正常工作状态; 模式1:修改时间;模式2:选择一个需要改变的闹铃;模式3:修改选定的闹铃的分钟 ;模式4:修改选定的闹铃的小时(3)设计示意图AT 89 C51单片机时间模块温度模块调节模块声音模块LCD显示模块 图一. 总设计示意图 二程序设计:/*名称:学校作息时间控制系统的设计程序,基于AT89C51单片机,用lcd12864显示内容:三个按键:mode(模式)、inc(增加)、dec(减少) 一个LCD12864显示 一个DS18B20数字温度计和一个声音播放器SOUNDER日期:2011-6-7编写:黄健*/#include<reg51.h>#include<intrins.h>#define LCD P0sbit DQ=P37; /定义DS18B20数据端口sbit P07=P07; /小数点控制I0sbit mode=P10;/key1分sbit inc=P11;/kye2时sbit dec=P12;/key3 闹铃sbit fmq=P17;/蜂鸣器接口sbit E=P20; /用于DS18B20接线端口sbit RW=P21;sbit RS=P22;sbit CS1=P24;sbit CS2=P23;sbit BUSY=P00;unsigned char a,i,j,k;unsigned char bai,shi,ge,xiaoshu; /用于表示温度unsigned int realtemp; / 读取的实际温度值unsigned char flag;/正负标志位unsigned char fu;/符号寄存器unsigned char count,hour,minute,second=0; /用于表示时间unsigned char mode_value=0 ,xf; /调节模式unsigned charmonth=6 ,day=7; /用于表示日期unsigned char h1,h2,f1,f2,s1,s2=0; /用于显示时间unsigned char m1,m2;d1,d2; /用于显示日期unsigned char ds202 = 8,0,8,45,8,55,9,40,10,0,10,45,10,55,11,40,14,0,14,45,14,55,15,40,16,0,16,45,16,55,17,40,19,0,19,45,19,55,20,40; /用于定时闹铃unsigned char code zi2816=0x20,0x20,0x24,0xA4,0xA4,0xBF,0xA4,0xE4,0xA4,0xBF,0xA4,0xE6,0xA4,0x30,0x20,0x00 ,/*"黄”,0*/0x00,0x80,0x80,0x5F,0x4A,0x2A,0x0A,0x0F,0x0A,0x2A,0x2A,0x4F,0x40,0x80,0x00,0x00 ,0x40,0x20,0xF8,0x07,0x88,0x48,0x38,0x10,0x54,0x54,0xFF,0x54,0x54,0x7C,0x10,0x00, /*"健",1*/0x00,0x00,0xFF,0x44,0x29,0x19,0x27,0x49,0x89,0x89,0xFF,0x89,0x89,0xCD,0x49,0x00,0x00,0xFC,0x84,0x84,0x84,0xFE,0x14,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x00, /*"时",2*/0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x23,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x98,0x86,0x80,0x80,0x83,0x8C,0x90,0x20,0xC0,0x80,0x80,0x00, /*"分",3*/ 0x01,0x00,0x80,0x40,0x20,0x1F,0x00,0x40,0x80,0x40,0x3F,0x00,0x00,0x01,0x00,0x00, 0x20,0x24,0x24,0xA4,0xFE,0xA3,0x22,0x80, 0x70,0x00,0xFF,0x00,0x10,0x20,0x60,0x00,/*"秒",4*/0x10,0x08,0x06,0x01,0xFF,0x00,0x81,0x80,0x40,0x20,0x17,0x08,0x04,0x03,0x00,0x00,0x10,0x10,0xD0,0xFF,0x94,0x14,0xE4,0xBF, 0xA4,0xA4,0xA4,0xBF,0xF4,0x26,0x04,0x00,/*"模",5*/ 0x04,0x03,0x00,0xFF,0x08,0x89,0x8B,0x4A, 0x2A,0x1E,0x2A,0x2A,0x4B,0xC8,0x48,0x00,0x10,0x10,0x91,0xD6,0xB0,0x10,0xFE,0x82,0x82,0x82,0x82,0x82,0xFF,0x02,0x00,0x00, /* "祝",6*/0x02,0x01,0x00,0xFF,0x80,0x41,0x21,0x18,0x07,0x00,0x3F,0x40,0x41,0x40,0x70,0x00,0x40,0x20,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,0x00, /*“你”,7*/0x00,0x00,0xFF,0x00,0x00,0x08,0x04,0x43,0x80,0x7F,0x00,0x01,0x06,0x0C,0x00,0x00,0x80,0x70,0x00,0xFF,0x10,0x20,0x10,0x10,0xFF,0x10,0x10,0x10,0xF8,0x10,0x00,0x00, /*“快”,8*/0x00,0x00,0x00,0xFF,0x82,0x42,0x22,0x1A,0x07,0x0A,0x12,0x22,0x43,0xC2,0x42,0x00,0x00,0x80,0xC0,0xBC,0x84,0x84,0x84,0xF4,0x82,0x82,0x83,0x82,0x80,0xC0,0x80,0x00,/*”乐“,9*/0x00,0x40,0x20,0x10,0x0C,0x40,0x80,0x7F,0x00,0x00,0x04,0x08,0x30,0x60,0x00,0x00,0x40,0x20,0xF8,0x07,0xF0,0xA0,0x90,0x4F,0x54,0x24,0xD4,0x4C,0x84,0x80,0x80,0x00, /*“修”,10*/0x00,0x00,0xFF,0x00,0x0F,0x80,0x92,0x52,0x49,0x25,0x24,0x12,0x08,0x00,0x00,0x00,0x04,0xC4,0x44,0x44,0x44,0xFE,0x44,0x20,0xDF,0x10,0x10,0x10,0xF0,0x18,0x10,0x00, /*“改”,11*/0x00,0x7F,0x20,0x20,0x10,0x90,0x80,0x40,0x21,0x16,0x08,0x16,0x61,0xC0,0x40,0x00,0x00,0xFC,0x84,0x84,0x84,0xFE,0x14,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,/*"时" ,12*/0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x23,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0xF8,0x01,0x02,0xF6,0x10,0x12,0x12,0x12,0x12,0xFA,0x12,0x02,0xFF,0x02,0x00, /*"间",13*/0x00,0xFF,0x00,0x00,0x3F,0x11,0x11,0x11,0x11,0x11,0x3F,0x40,0x80,0x7F,0x00,0x00, ;/汉字码unsigned char code xuehao208=0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,/*"2",0*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,/*"0",1*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,/*"0",2*/0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,/*"8",3*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,/*"0",4*/0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,/*"4",5*/0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,/*"2",6*/0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,/*"1",7*/0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,/*"2",8*/0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,/*"6",9*/;/学号码unsigned char code shu208=0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,/*"0",0*/0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,/*"1",1*/0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,/*"2",2*/0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,/*"3",3*/0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,/*"4",4*/0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,/*"5",5*/0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,/*"6",6*/0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,/*"7",7*/0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,/*"8",8*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,/*"9",9*/;/数字码unsigned char code fuhao128=0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,/*"-",0*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,/*".",1*/0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,/*":",2*/0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*".",3*/0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,/*"C",4*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",5*/;/符号码/*LCD显示模块程序*/*检查12864LCD中是否忙*/ checkbusy() E=1; RW=1; RS=0; LCD=0Xff; if(BUSY); /*写命令*/writecode(unsigned char dat) /写命令 checkbusy(); E=0; RW=0; RS=0; LCD=dat; E=1; E=0;/*写数据*/writedata(unsigned char dat) /写数据 checkbusy(); E=0; RW=0; RS=1; LCD=dat; E=1; E=0;/*汉字显示程序*/void hanzi(unsigned char page,unsigned char lineaddress,int n,int a, unsigned char table16) unsigned char temp32; if(lineaddress<0X80) CS1=0; CS2=1; /left for(j=2*a;j<n+2*a;j+) if(lineaddress>=0X80) CS1=1; /right CS2=0; lineaddress=lineaddress-0X40; for(k=0;k<16;k+) tempk=tablejk; j+=1; for(k=0;k<16;k+) temp16+k=tablejk; writecode(page); writecode(lineaddress); for(i=0;i<16;i+) writedata(tempi); writecode(page+1); writecode(lineaddress); for(i=16;i<32;i+) writedata(tempi); lineaddress+=16; /*数字和字符显示程序*/void zifu(unsigned char page,unsigned char lineaddress,int n,int a, unsigned char table8) unsigned char temp16; if(lineaddress<0X80) CS1=0; CS2=1; /left for(j=2*a;j<n+2*a;j+) if(lineaddress>=0X80) CS1=1; /right CS2=0; lineaddress=lineaddress-0X40; for(k=0;k<8;k+) tempk=tablejk; j+=1; for(k=0;k<8;k+) temp8+k=tablejk;writecode(page);writecode(lineaddress); for(i=0;i<8;i+) writedata(tempi); writecode(page+1); writecode(lineaddress); for(i=8;i<16;i+) writedata(tempi); lineaddress+=8; /*LCD初始化*/void LCD_inti() writecode(0X3f);/显示开关关 writecode(0XC0);/修改显示起始行 writecode(0Xb8);/修改页地址,x地址 writecode(0X40);/修改列地址,y地址/*显示固定的汉字*/void xingxian() hanzi(0Xb8,0X40,4,0,&zi);/显示姓名 “黄健”zifu(0xb8,0x70,20,0,&xuehao);/显示学?“2008042126”hanzi(0xba,0x60,2,2,&zi);/显示“时”hanzi(0xba,0x80,2,3,&zi);/显示“分”hanzi(0xba,0xa0,2,4,&zi);/显示“秒”hanzi(0xbc,0xa0,2,5,&zi);/显示“模”zifu(0xbc,0x40,2,2,&shu);/显示“年份”zifu(0xbc,0x48,2,0,&shu);zifu(0xbc,0x50,2,1,&shu);zifu(0xbc,0x58,2,1,&shu);zifu(0xbc,0x60,2,0,&fuhao);zifu(0xbc,0x78,2,0,&fuhao);zifu(0xb8,0x60,2,5,&fuhao);/显示空白zifu(0xb8,0x68,2,5,&fuhao);zifu(0xba,0x40,2,5,&fuhao);zifu(0xba,0x48,2,5,&fuhao);zifu(0xba,0xb0,2,5,&fuhao);zifu(0xba,0xb8,2,5,&fuhao);zifu(0xbc,0x90,2,5,&fuhao);zifu(0xbc,0x98,2,5,&fuhao);zifu(0xbc,0xb0,2,2,&fuhao);zifu(0xbe,0x58,2,0,&fuhao);/显示“-” /*温度模块程序*/*延时*/void delayds(unsigned int i) while(i-); /*12M,一次6us,加进入退出14us(8M晶振,一次9us) */*初始化函数*/unsigned char init(void) unsigned char x; DQ=1;/复位delayds(8);DQ=0; /单片机将DQ拉低delayds(80); /复位信号延时大于480usDQ=1; /在复位电平结束之后,单片机应该将数据单总线拉高delayds(14);x=DQ; /判断复位是否成功。如果x=0则初始化成功,x=1则初始化失败delayds(20);return(x);/*读一个字节*/readchar(void)unsigned char i=0;unsigned char dat = 0;for(i=8;i>0;i-) /*/写入ds1820 的bit 数,一个字节8 个bit*/ DQ=0; / 给脉冲信号, “读”起始位dat>>=1;/右移运算,把一个字节data(A)分成8 个bit 环移DQ=1; / 给脉冲信号,“读”停止位if(DQ)dat|=0x80;/按位或,取最高位并存入dat中,DQ=1则dat的最高位也为1delayds(4);return(dat);/*写一个字节*/writechar(unsigned char dat)unsigned char i=0;for (i=8;i>0;i-) DQ=0; /“写”起始DQ=dat&0x01; /通过按位与使送出数据为“0”或“1”,取最低位,先送/低位再送delayds(5); /60us到120us延时DQ=1; /“写”停止dat>>=1; /右移运算,取高一位数据传入delayds(4);/*读取温度*/readtemp()float tt=0;unsigned char a=0;unsigned char b=0;unsigned char t=0;init();writechar(0xCC); / 跳过读序号列号的操作writechar(0x44); / 启动温度转换init();writechar(0xCC); / 跳过读序号列号的操作writechar(0xBE); /写入读取温度指令,读取温度寄存器等(共可读9个寄存器)/前两个就是温度a=readchar(); /读温度值的低字节b=readchar(); /读温度值的高字节fu=b&0x80;if(fu!=0)flag=1;/负温标志位置1b=b;/取反a=a;tt=(b*256)+a+1)*0.0625;/求负的温度t=tt;else flag=0;/正温标志位置0tt=(b*256)+a)*0.0625;/求正的温度t=tt;return(t); /*温度计算*/worktemp(void)realtemp=readtemp();/将读取的温度赋给realtempbai=realtemp/100;shi=(realtemp%100)/10;ge=realtemp%10;xiaoshu=realtemp-(bai*100+shi*10+ge); if(flag=1)/标志位显示判断 zifu(0xbe,0x80,2,0,&fuhao); /显示“符号-” else zifu(0xbe,0x80,2,5,&fuhao);if(bai!=0) /百位显示判断zifu(0xbe,0x88,2,bai,&shu);elsezifu(0xbe,0x88,2,5,&fuhao);if(shi!=0)/十位显示判断zifu(0xbe,0x90,2,shi,&shu);elsezifu(0xbe,0x90,2,5,&fuhao);zifu(0xbe,0x98,2,ge,&shu); /个位显示zifu(0xbe,0xa0,2,1,&fuhao);zifu(0xbe,0xa8,2,xiaoshu,&shu);/小数位显示zifu(0xbe,0xb0,4,3,&fuhao); /显示温度单位“。C” /*