目錄
一、 前言--------------------------------------2
二、 硬件原理分析--------------------------2
三、 程序設計--------------------------------4
四、 程序代碼--------------------------------4
五、 仿真效果-------------------------------10
六、 參考文獻-------------------------------10
七、 學習體會-------------------------------11
一、 前言
<1>利用所學知識設計一個單片機數字電子鍾
<2>數字電子鍾的功能要求:
(1)有自動計時功能;
(2)能顯示計時時間,顯示效果良好;
(3)有校時功能,能對時間進行校准
<3>設計要求:
(1)主電路由秒信號發生器、“時、分、秒”計數器、譯碼器及顯示器、校准電路等構成。
(2)秒信號發生器一般用石英晶體振盪器加分頻器實現。
(3)譯碼電路將時、分、秒計數器的輸出狀態送七段譯碼器譯碼,經過六位LED七段顯示器顯示出來。
(4)校時電路用來對時、分、秒顯示數字進行校對。
二、 硬件原理分析
1、時鍾信號部分
單片機XTAL1,XTAL2端接外部時鍾電路(時鍾電路參考課本),EA端接5V電源,使得單片機讀取片內程序。
2、按鍵開關部分
開始仿真,按下開關K1,時鍾暫停,然后按下開關K2一次,切到調時位,再按K3,K4實現時位加減;按K1兩次切到調分位,按K3,K4實現分位加減;按K1三次切到調秒位,按K3,K4實現秒位加減;按下K5,確定當前操作,然后再按K1,重新啟動時鍾。
3、數碼管顯示器部分(共陰極)
所用的是一個六位七段共陰極數碼管
4、共陰極數碼管編碼
三、 程序設計
四、 程序代碼
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit set=P1^0;
sbit save=P1^5;
sbit rselect=P1^1;
sbit lselect=P1^2;
sbit add=P1^3;
sbit reduce=P1^4;
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar disp_buf[6];
uchar disp_bit=0;
uint hour,min,sec;
uint select_num=0;
uint hour_adj,min_adj,sec_adj;
uchar count;
uchar key_num=0;
void key_scan()
{
if(!set)
{
hour_adj=hour;
min_adj=min;
sec_adj=sec;
key_num++;
}
while(!set);
if(key_num%2==1)
{
if(rselect==0)
{
select_num++;
if(select_num==4)
select_num=1;
}
while(!rselect);
if(lselect==0)
{
select_num--;
if(select_num<=0)
select_num=3;
}
while(!lselect);
}
if(!add&&(key_num%2))
{
switch(select_num)
{
case 1 :
{
hour_adj++;
if(hour_adj==24)
hour_adj=0;
break;
}
case 2 :
{
min_adj++;
if(min_adj==60)
min_adj=0;
break;
}
case 3 :
{
sec_adj++;
if(sec_adj==60)
sec_adj=0;
break;
}
default:break;
}
while(!add);
}
if(!reduce&&(key_num%2))
{
switch(select_num)
{
case 1 :
{
hour_adj--;
if(hour_adj<=0)
hour_adj=23;
break;
}
case 2 :
{
min_adj--;
if(min_adj<=0)
min_adj=59;
break;
}
case 3 :
{
sec_adj--;
if(sec_adj<=0)
sec_adj=59;
break;
}
default:break;
}
while(!reduce);
}
if(!save&&(key_num%2))
{
select_num=0;
hour=hour_adj;
min=min_adj;
sec=sec_adj;
while(!save);
}
}
void main()
{
TMOD=0x11;
TH0=0xf7;
TL0=0x00;
TH1=0x4c;
TH0=0x00;
ET0=1;
ET1=1;
EA=1;
TR0=1;
TR1=1;
PT1=1;
hour=23;
min=59;
sec=59;
count=0;
while(1)
{
key_scan();
if(key_num%2)
{
switch(select_num)
{
case 1 :
{
if(count<=10)
{
disp_buf[0]=hour_adj/10;
disp_buf[1]=hour_adj%10;
}
else
{
disp_buf[0]=0x40;
disp_buf[1]=0x40;
}
disp_buf[2]=min_adj/10;
disp_buf[3]=min_adj%10;
disp_buf[4]=sec_adj/10;
disp_buf[5]=sec_adj%10;
break;
}
case 2 :
{
if(count<=10)
{
disp_buf[2]=min_adj/10;
disp_buf[3]=min_adj%10;
}
else
{
disp_buf[2]=0x40;
disp_buf[3]=0x40;
}
disp_buf[0]=hour_adj/10;
disp_buf[1]=hour_adj%10;
disp_buf[4]=sec_adj/10;
disp_buf[5]=sec_adj%10;
break;
}
case 3 :
{
if(count<=10)
{
disp_buf[4]=sec_adj/10;
disp_buf[5]=sec_adj%10;
}
else
{
disp_buf[4]=0x40;
disp_buf[5]=0x40;
}
disp_buf[0]=hour_adj/10;
disp_buf[1]=hour_adj%10;
disp_buf[2]=min_adj/10;
disp_buf[3]=min_adj%10;
break;
}
default : break;
}
}
if(key_num%2==0)
{
disp_buf[0]=hour/10;
disp_buf[1]=hour%10;
disp_buf[2]=min/10;
disp_buf[3]=min%10;
disp_buf[4]=sec/10;
disp_buf[5]=sec%10;
}
}
}
void timer0() interrupt 1
{
TH0=0xf7;
TL0=0x00;
P2=~(0x01<<disp_bit);
P0=tab[disp_buf[disp_bit]];
disp_bit++;
if(disp_bit==6) disp_bit=0;
}
void timer1() interrupt 3
{
TH1=0x4c;
TL1=0x00;
if(++count==20)
{
count=0;
if(++sec==60)
{
sec=0;
if(++min==60)
{
min=0;
if(++hour==24)
{
hour=0;
}
}
}
}
}
五、 仿真效果圖
六、 參考文獻
1. 網上搜索
2. 單片機教材
3. 網上論壇
七、學習體會
通過本次單片機課程設計,不僅加深了我對單片機理論課程知識的認識,而且通過將理論與實踐相結合,使我真正地全面理解單片機的功能。 在剛開始編程時,沒有一點思路,通過書上所提供的例程,慢慢理清了思路、基本了解了程序大致需要那幾部分,基本確定編程思想。在課程設計的整個過程中也遇到了很多問題,但本着遇到問題解決問題的原則,通過查找資料和詢問老師、同學的辦法,基本解決了所遇到問題。整個課程設計過程學到了不少通過理論學習沒法學到的東西,真正增強了自己的能力。
課程設計的這天時間,雖然辛苦但是收獲巨大。