1、单片机综合实验报告题 目: 多功能数字时钟 班 级: 姓 名: 学 号: 一、实验内容:设计一个单片机控制的秒表系统。利用单片机的定时器的原理,结合显示电路、LED数码管以及按键来设计计时器,使系统能够正确地进行加、减(倒)计时,数码管能够正确地显示时间。 目的要求1) 两位 LED 显示,显示时间为 0099 秒。2) 每秒自动加 1。3) 一个开始按键、一个复位按键和一个暂停按钮。 4) 翻页按钮查看四个不同的计时值 。 5) 添加倒计时初始值设置功能6) 不同功能通过功能键 Setup 实现切换。二、实验电路及功能说明本实验以 51 单片机为核心,应用其中断来定时,通过按键来控制时间和日
2、期的调整,通过 1602LCD 来数字显示时钟,做成一个简易的数字时钟。本实验要求能定时,还要能设置闹铃,由于对 C51 程序代码的写法不是很熟,没能实现闹铃功能。所以,最后该实验能实现的功能为时间和日期的调整。其原理图如下图所示:三、实验程序流程图:主程序:主程序流程图子流程图(按键功能设置)四、实验结果分析经过 proteus 仿真可知:该方案可行,能够对时间进行精确的调整,也能对日期进行更正,基本上能实现上述功能。五、心得体会通过该试验我对 51 的了解更加深入了一层,特别是对 C51 的写法更加了解,还对 1602的基本操作有了一定的了解。同时,也发现 C 语言的重要性,以后要多加强对
3、 C 语言的学习.六、程序清单#include #include /库函数头文件,代码中引用了_nop_() 函数/ 定义控制信号端口sbit RS=P24; /P2.4sbit RW=P25; /P2.5sbit E=P26; /P2.6sbit set=P14; /设置键sbit add1=P15; /加 1 键sbit sub1=P16; /减 1 键sbit enter=P17; /确认键bit k=0,f=0;/k 为 0 表示运行状态, k 为 1 表示设置状态;f 为 0 表示第一行显示,f 为 1 表示第二行显示char sec,n,m;unsigned char count,
4、key;unsigned char lcdd=“0123456789“; /*声明调用函数*/void dispd(); /日期显示函数void dispt(); /时间显示函数unsigned char keys();/按键扫描函数void lcd_w_cmd(unsigned char com); /写命令字函数void lcd_w_dat(unsigned char dat); /写数据函数unsigned char lcd_r_start(); /读状态函数void int1(); /LCD 初始化函数void delay(unsigned char t); /可控延时函数void d
5、elay1(); /软件实现延时函数,5 个机器周期/*主函数*/void main() TMOD=0x01; /设置为定时器模式 1TH0=(65536-50000)/256; /晶振 6MHz,定时时间 100msTL0=(65536-50000)%256;IE=0x82; /开全局中断和定时中断TR0=1; /启动定时器sec=0; /秒count=0; /中断次数清 0n=-3; /设置键按下次数,第一行日期m=-3; /设置键按下次数,第二行时间P0=0xff; / 送全 1 到 P0 口int1(); / 初始化 LCDdelay(255);while(1) key=keys();
6、 /读取按键switch(key) case 0xe0: /按下设置键 TR0=0;k=1;if(f=0) n=n+3;if(n=9) n=0;m=0;f=1;elsem=m+3;if(m=12)m=0;n=0;f=0;if(f=0)lcd_w_cmd(0x0d);lcd_w_cmd(0x86+n);elselcd_w_cmd(0x0d);lcd_w_cmd(0xc4+m); break;case 0x70: /按下确认键k=0;TR0=1;n=-3; m=-3;f=0; break;case 0xd0: /按下加 1 键if(k=1)if(f=0) (m=6)sec+;if(sec=100)
7、 sec=0;dispt(); /调用第二行显示函数lcd_w_cmd(0x0d); /光标闪烁lcd_w_cmd(0xc4+m);/返回设置值显示地址 break;case 0xb0: /按下减 1 键if(k=1)if(f=0)if(m=6)sec-;if(sec0) sec=99;dispt(); /调用第二行显示函数lcd_w_cmd(0x0d); /光标闪烁lcd_w_cmd(0xc4+m);/返回设置值显示地址 break;if(k=0) dispd();dispt(); /调用 LCD 显示函数/*延时函数*/void delay(unsigned char t) unsigne
8、d char j,i;for(i=0;it;i+)for(j=0;j20;j+); /*延时函数 1*/void delay1() _nop_();_nop_();_nop_();/*LCD 初始化函数*/void int1() lcd_w_cmd(0x3c); / 设置工作方式lcd_w_cmd(0x0c); / 设置光标lcd_w_cmd(0x01); / 清屏lcd_w_cmd(0x06); / 设置输入方式lcd_w_cmd(0x80); / 设置初始显示位置/*LCD 读状态函数*/返回值:返回状态字,最高位 D7=0,LCD 控制器空闲;D7=1,LCD 控制器忙unsigned
9、char lcd_r_start() unsigned char s;RW=1; /RW=1,RS=0,读 LCD 状态delay1();RS=0;delay1();E=1; /E 端时序delay1();s=P0; /从 LCD 的数据口读状态delay1();E=0;delay1();RW=0;delay1(); return(s); /返回读取的 LCD 状态字/*LCD 写命令函数*/void lcd_w_cmd(unsigned char com) unsigned char i;do / 查 LCD 忙操作i=lcd_r_start(); / 调用读状态字函数i=i / 与操作屏蔽
10、掉低 7 位 delay(2); while(i!=0); / LCD 忙,继续查询,否则退出循环RW=0;delay1();RS=0; / RW=0,RS=0,写 LCD 命令字delay1();E=1; /E 端时序delay1();P0=com; /将 com 中的命令字写入 LCD 数据口delay1();E=0;delay1();RW=1;delay(255);/*LCD 写数据函数*/void lcd_w_dat(unsigned char dat) unsigned char i;do / 查忙操作i=lcd_r_start(); / 调用读状态字函数i=i / 与操作屏蔽掉低
11、7 位 delay(2); while(i!=0); / LCD 忙,继续查询,否则退出循环RW=0;delay1();RS=1; / RW=1,RS=0,写 LCD 数据delay1();E=1; / E 端时序delay1();P0=dat; / 将 dat 中的显示数据写入 LCD 数据口delay1();E=0;delay1();RW=1;delay(255);/*定时中断函数*/void timer0() interrupt 1 TH0=(65536-50000)/256; /晶振 6MHz,定时时间 100msTL0=(65536-50000)%256;count+;if(coun
12、t=20)count=0;sec+; if(sec=99) sec=0; /*按键扫描函数*/unsigned char keys()unsigned char cod,del;P1=0xf0;cod=P1 /读入 P3 口键值if(cod!=0xf0) /先检测有无按键按下delay(100); /去抖if(cod!=0xf0) cod=P1 /读入键值do /等待键释放P1=0xf0;del=P1while(del!=0xf0);return(cod);/返回键值return(0xf0); /返回该值void dispt()lcd_w_dat(lcddsec%10);delay(2); lcd_w_dat( );delay(2);lcd_w_dat(W);delay(2);