单片机应用系统设计报告
设计题目: 简易数字时钟设计
完 成 人:
班 级:
学 号: 指导教师:
成 绩:
1
目录
一、系统总体框图……………………………3
二、电路设计原理图………………………… 3
三、简易时钟流程图………………..………. 6
四、时钟程序代码……………………………7
五、最后仿真结果……………………………..13
2
一、简易数字时钟系统框图
二、电路设计原理图
2.1实验设计原件 (1)开关按键
(2)52单片机
3
(3)蜂鸣器
(4)数码管驱动器
(5)排阻
(6)6位数码管
4
2.2仿真电路图
5
三、简易时钟流程图
6
四、时钟程序代码
#include #define uchar unsigned char #define uint unsigned int code uchar dis_seg[12]={0x3F, 0x06, 0x5B, 0x4F,0x66, 0x6D,0x7D ,0x07,0x7F ,0x6F,0x00, 0x40}; //段选数组 code uchar dis_1oc[6]={0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf}; //位选数组 data uchar timer[6]={0x0, 0x5, 0x9, 0x5, 0x07, 0x00}; //存放6位数码管显示 07:59:50 data uchar clock[6]={0x00, 0x00, 0x00, 0x00, 0x8,0x00}; //存放闹铃的定时 08:00:00 (到时手动+1设置闹铃 data uchar disp_buf[8]={0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x0a ,0x00}; //存放缓冲区数组 data uchar t0_50ms=0X00; //定义50ms循环 sbit DP=P0^7; //小数点位数 data uchar set_uint=0x00; //调时单元 bit adj_time=0; //时间调节标志 bit adj_clock=0; // 调闹铃标志, 0,不调,1调 data uchar t1_50ms=0x00; // 闪烁50ms循环次数 sbit beep=P3^7; //蜂鸣器 data uint speak_cont ; //发声次数计数 data uint beep_delay ;//发声间隔50ms循环次数 data uint pulse_cont ; //发声脉冲个数 bit time_beep=0 ; //整点报时状态 发声中断用 bit clock_on=0; //闹铃开关标志,0关闹钟,停止报时 bit disp_clock=0; //闹铃显示标志,1显示闹铃,0显示时钟 bit clock_beep=0; //报时状态,1闹铃报时 发声中断用 sfr T2MOD= 0xC9; //T2定时器所需 /************************定时器初始化******************/ void init() {TMOD=0X11; //定时器0与1的工作方式 TH0=0x3C;TL0=0xB0; //闪烁定时器0初始化 7 TH1=0x3C;TL1=0xB0; //蜂鸣定时器1初始化 EA=1; //定时器中断为高优先级 TH2=0x3C; TL2=0xB0; //T2的初始化 RCAP2H=0X3C;RCAP2L=0XB0; //装T2初值 T2CON=0;T2MOD=0;IE=0XA0;TR2=1;ET2=1; //T2的初始化} /****************1ms延时程序**************************/ void delay1ms(uint t) {uint i,j; for(i=0;i for (k=0;k<6;k++) {P2=dis_1oc[k]; //位选,依次选中6个数码管 P0=dis_seg[disp_buf[k]]; //被显示数据存放在disp_buf[k] if(k==2||k==4)DP=1; //分与秒之间,时与分之间,显示小数点 delay1ms(1);}} /************整点滴滴****************/ void speak_time() {TH1=(65536-800)/256; TL1=(65536-800)%256; TR1=1;ET1=1; //启动蜂鸣器定时器T1 time_beep=1; pulse_cont=1000; speak_cont=5;beep_delay=30;} /********************闹铃滴滴******************/ void speak_clock() {uchar q; if (clock[2]==timer[2]&&clock[3]==timer[3]&&clock[4]==timer[4]&&clock[5]==timer[5]) {TH1=0xff; TL1=0x9c; TR1=1; ET1=1; disp_clock=1; {for(q=0;q<6;q++)disp_buf[q]=clock[q];} time_beep=0; clock_beep=1; pulse_cont=500; beep_delay=10; speak_cont=200;}} /************时钟定时器与计时进位*******************/ void time_intt2(void) interrupt 5 //interrupt 5代表 T2 {char q; TF2=0;t0_50ms++; 8 if(t0_50ms==20) {t0_50ms=0x00; timer[0]++; if (timer[0]>=10) {timer[0]=0;timer[1]++; if(timer[1]>=6) {timer[1]=0;timer[2]++; if(clock_on)speak_clock(); if(timer[2]>=10) {timer[2]=0;timer[3]++; if(timer[3]>=6) {timer[3]=0;timer[4]++;speak_time(); //时位进1,顺便整点报时 if(timer[4]>=10) {timer[4]=0;timer[5]++;} if(timer[5]==2&&timer[4]==4) {timer[4]=0;timer[5]=0; //24小时已到,归零}}}}} if(!disp_clock) //如果显示闹铃界面,则不刷新6位数码管的缓冲区 {for(q=0;q<6;q++)disp_buf[q]=timer[q];}}} /*******************闪烁中断定时器********************/ void time_intt0() interrupt 1 {TH0=0x3c;TL0=0xB0; t1_50ms++; if(t1_50ms==10) //每0.5s执行1次 {t1_50ms=0x00; //归零 disp_buf[7]=disp_buf[set_uint]; disp_buf[set_uint]=disp_buf[6]; disp_buf[6]=disp_buf[7]; //这三行导致的结果是这一位置上的disbuf值不会再改 }} /************调时按键功能程序*******************/ void set_time() {if(disp_buf[set_uint]==10) //上同 {disp_buf[7]=disp_buf[set_uint]; disp_buf[set_uint]=disp_buf[6]; disp_buf[6]=disp_buf[7];} set_uint+=2; if(set_uint>=6) //按下第三次的情况 {set_uint=0; //调时单元清0 adj_time=0; //时间调节为0 TR2=1;ET2=1; //时钟定时器启动 TR0=0;ET0=0; //闪烁定时器关闭} else {adj_time=1; //若是前两次 TR0=1;ET0=1; //闪烁定时器启动 TR2=0;ET2=0; //时钟定时器关闭} } /******************闹铃设定键程序*************/ 9 void set_clock() {uchar i; if(set_uint==0){clock_on=~clock_on;} //第一次调,闹铃调节打开 if(clock_on==1) {for(i=2;i<6;i++)disp_buf[i]=clock[i]; disp_buf[0]=1;disp_buf[1]=11; disp_buf[6]=0x0a; set_uint+=2; if(set_uint>=6) {adj_clock=0; set_uint=0; TR0=0;ET0=0;} else{adj_clock=1; TR0=1;ET0=1;}} else {adj_clock=1; for(i=2;i<6;i++)disp_buf[i]=clock[i]; disp_buf[0]=0;disp_buf[1]=11; for(i=0;i<200;i++)disp_scan(); adj_clock=0; }} /***********************修改时间+1******************/ void add_time() {timer[set_uint]++; if(set_uint==2) {if(timer[set_uint]==0x0a) {timer[set_uint]=0;timer[set_uint+1]++; if(timer[set_uint+1]==6)timer[set_uint]=0;} } else {if(timer[set_uint+1]==2&&timer[set_uint]==4){timer[set_uint]=0;timer[set_uint+1]=0;} else if(timer[set_uint]==10){timer[set_uint]=0;timer[set_uint+1]++;}} disp_buf[set_uint]=timer[set_uint]; disp_buf[set_uint+1]=timer[set_uint+1]; disp_buf[6]=0x0a;} /******************修改时间-1************************/ void sub_time() {timer[set_uint]--; if(set_uint==2) {if(timer[set_uint]==0xff) {timer[set_uint]=9;timer[set_uint+1]--; if(timer[set_uint+1]==0xff)timer[set_uint]=5;} } else {if(timer[set_uint]==0xff&&timer[set_uint+1]==0x00){timer[set_uint]=3;timer[set_uint+1]=2;} else if(timer[set_uint]==0xff){timer[set_uint]=9;timer[set_uint+1]--;}} disp_buf[set_uint]=timer[set_uint]; disp_buf[set_uint+1]=timer[set_uint+1]; 10 disp_buf[6]=0x0a;} /*****************闹钟时间+1****************/ void add_clock() {clock[set_uint]++; if(clock[set_uint]==10) {clock[set_uint]=0;clock[set_uint+1]++;} if(set_uint==2) {if(clock[set_uint+1]==6)clock[set_uint+1]=0;} else if(clock[set_uint+1]==2&&clock[set_uint]==4) {clock[set_uint]=clock[set_uint+1]=0;} disp_buf[set_uint]=clock[set_uint] ; disp_buf[set_uint+1]=clock[set_uint+1] ; disp_buf[6]=0x0A;} /*****************闹钟时间-1****************/ void sub_clock() {clock[set_uint]--; if(set_uint==2) {if(clock[set_uint]==0xff) {clock[set_uint]=9;clock[set_uint+1]--;} {if(clock[set_uint+1]==0xff)clock[set_uint]=5; }} else {if(clock[set_uint]==0xff&&clock[set_uint+1]==0x00){clock[set_uint]=3;clock[set_uint+1]=2;} else if(clock[set_uint]==0xff){clock[set_uint]=9;clock[set_uint+1]--;}} disp_buf[set_uint]=clock[set_uint]; disp_buf[set_uint+1]=clock[set_uint+1]; disp_buf[6]=0x0a;} /*********************************蜂鸣器中断***************************/ void time_inttl(void) interrupt 3 using 1 {if(time_beep==1) //整点报时状态 {if (speak_cont!=0) //发声次数也不为0 {if(pulse_cont!=0) //发声脉冲个数也不为0 {beep=~beep; //蜂鸣器取返 if(speak_cont>1) // 还有剩余的发声次数 {TH1=0xfc;TL1=0xe0;} //正常的声音 else {TH1=0xfe;TL1=0x70;} //最后一次的尖鸣 pulse_cont--; //归零,关闭 if(pulse_cont==0)beep_delay=30;} else {TH1=0X3C;TL1=0xB0;TR1=1; beep_delay--; if(beep_delay==0) {speak_cont--; if(speak_cont==1)pulse_cont=2000; 11 else pulse_cont=1000;}}} else {ET1=0;TR1=0;time_beep=0;}} else if(clock_beep==1) //闹铃状态 {if(clock_on==1&&speak_cont!=0) {if(pulse_cont!=0) {beep=~beep; TH1=(65536-100)/256; TL1=(65536-100)%256; pulse_cont--; if(pulse_cont==0)beep_delay=10;} else {TH1=0x3C;TL1=0xB0; beep_delay--; if(beep_delay==0) {pulse_cont=300;speak_cont--;}}} else {ET1=0;TR1=0;clock_beep=0;disp_clock=0;}}} /******************************主程序**************************/ main() {init(); while(1) {disp_scan(); if((P1&0x0f)!=0x0f) {disp_scan(); if((P1&0x0f)!=0x0f) {switch(P1&0x0f) {case 0x0e:set_time();break; //设定时间 case 0x0d:set_clock();break; //设定闹铃 case 0x0b:if(adj_time)add_time();if(adj_clock)add_clock();break; //+1 case 0x07:if(adj_time)sub_time();if(adj_clock)sub_clock();break;} //-1 while((P1&0x0f)!=0x0f)disp_scan();}}}} 12 五、最后仿真结果 1.整点/闹铃触发时,蜂鸣器警报 2.一次按下调时键 分位闪烁 13 3.二次按下调时键 时位闪烁 4.一次按下闹铃键,打开闹铃,分位闪烁,显示 “-0” 14 ’ 5.四次按下闹铃键,闹铃关闭,显示“-1” 6.调时+1与调时-1 15 16 因篇幅问题不能全部显示,请点此查看更多更全内容