您的当前位置:首页正文

简易数字时钟设计报告

2021-03-19 来源:易榕旅网


单片机应用系统设计报告

设计题目: 简易数字时钟设计

完 成 人:

班 级:

学 号: 指导教师:

成 绩:

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/******************扫描显示程序**********************/ void disp_scan() {uchar k;

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

因篇幅问题不能全部显示,请点此查看更多更全内容