單片機(jī)四位時(shí)鐘電路設(shè)計(jì)方案(一)
以AT89C51單片機(jī)為核心的時(shí)鐘電路的程序設(shè)計(jì)
1.主程序設(shè)計(jì)及系統(tǒng)主流程圖
設(shè)計(jì)中采用定時(shí)器T0中斷完成,其余狀態(tài)循環(huán)調(diào)用顯示子程序。系統(tǒng)主流程圖如圖所示
2.時(shí)鐘電路的時(shí)鐘和鬧鈴程序設(shè)計(jì)及流程圖
時(shí)鐘采用11.0256MHZ的脈沖控制, 鬧鈴采用整點(diǎn)報(bào)時(shí)功能。
3 時(shí)鐘電路的顯示程序設(shè)計(jì)及流程圖
碼管顯示的數(shù)據(jù)存放在內(nèi)存單元70H-75H中,其中70H~71H存放秒數(shù)據(jù),72H~73H存放分?jǐn)?shù)據(jù),74H~75H存放時(shí)數(shù)據(jù),每一地址單元內(nèi)均為十進(jìn)制BCD碼。由于采用軟件動(dòng)態(tài)掃描實(shí)現(xiàn)數(shù)據(jù)顯示功能,顯示用十進(jìn)制BCD碼數(shù)據(jù)的對(duì)應(yīng)段碼存放在ROM表中。顯示時(shí),先取出70H~75H某一地址中的數(shù)據(jù),然后查的對(duì)應(yīng)的顯示段碼從P1口輸出。P3口將對(duì)應(yīng)的數(shù)碼管選中,就是顯示該地址單元的數(shù)據(jù)值,每個(gè)LED數(shù)碼管亮1MS時(shí)間再逐位循環(huán)。
4.時(shí)鐘電路的鍵盤程序設(shè)計(jì)及流程圖
P0口輸出段碼數(shù)據(jù),P1.0-P1.2口作掃描輸出,P0.1—P0.4口接按鈕開關(guān)S1,S2,S3,S4,S5,rest 接S6復(fù)位按鍵。P0.0控制秒的調(diào)整,每按一次加1秒;P0.1控制分的調(diào)整,每按一次加1分;P0.2控制時(shí)的調(diào)整,每按一次加1個(gè)小時(shí)。
5.仿真圖及程序
單片機(jī)四位時(shí)鐘電路設(shè)計(jì)方案(二)
通過S1、S2、S3和S4四個(gè)按鍵,對(duì)時(shí)間進(jìn)行修改和鬧鐘的設(shè)置,S0控制鬧鐘的啟動(dòng)和停止。按下S4鍵顯示鬧鐘,松開后顯示時(shí)間;按下S1鍵進(jìn)入時(shí)間修改模式,再按S1鍵時(shí)間的時(shí)加1,按S3分加1,調(diào)整結(jié)束后按下S4恢復(fù)正常顯示;按下S2鍵進(jìn)入鬧鐘修改模式,再按S3鍵鬧鐘的時(shí)加1,按S3分加1,調(diào)整結(jié)束后按下S4恢復(fù)正常顯示。在按鍵按下和放開時(shí)會(huì)出現(xiàn)抖動(dòng)現(xiàn)象。通過延時(shí)程序,可以進(jìn)行去抖動(dòng)設(shè)計(jì)。
Proteus仿真電路
單片機(jī)四位時(shí)鐘電路設(shè)計(jì)方案(三)
通過4位數(shù)碼管來顯示時(shí)間,系統(tǒng)晶振11.0592MHZ,仿真圖中用二極管代替時(shí)鐘冒號(hào)閃爍,非門代替三極管,讓仿真速度與真實(shí)速度達(dá)到一致,本設(shè)計(jì)用了6個(gè)按鈕來對(duì)時(shí)間及鬧鐘時(shí)間的調(diào)節(jié)、關(guān)閉,p3.2接時(shí)間分加1按鈕,p3.3接時(shí)間時(shí)加1按鈕,p3.4接鬧鐘時(shí)間與當(dāng)前時(shí)間切換按鈕,按住不放顯示鬧鐘的時(shí)間,鬧鐘初始化為00:00,放開按鈕則顯示當(dāng)前時(shí)間,p3.5接鬧鐘加1按鈕,p3.6接鬧鐘時(shí)加1按鈕,p3.7接關(guān)閉鬧鐘按鈕。
程序源代碼:
org 0000h
ajmp main ;調(diào)至主程序
org 000bh ;T0中斷入口地址
ljmp inti0
org 001bh ;T1中斷入口地址
ljmp inti1
org 0030h
main:mov tmod,#11h ;設(shè)T0、T1為模式1
mov ie,#8ah ;開T0、T1中斷允許
mov th0,#4ch ;賦T0 50ms初值
mov tl0,#00h
mov th1,#4ch ;賦T1 50ms初值
mov tl1,#00h
mov sp,#60h ;設(shè)置堆棧指針
mov r0,#20 ; T0 50ms計(jì)數(shù)20次
mov 31h,#00 ;時(shí)間秒初始化
mov 32h,#00 ;時(shí)間分初始化
mov 33h,#00 ;時(shí)間時(shí)初始化
mov 38h,#00 ;鬧鐘分初始化
mov 39h,#00 ;鬧鐘時(shí)初始化
setb tr0 ;啟動(dòng)T0
setb tr1 ;啟動(dòng)T1
loop:lcall display ;調(diào)用時(shí)間顯示子程序
lcall key ;調(diào)用時(shí)間調(diào)節(jié)按鍵子程序
lcall keynz ;調(diào)用鬧鐘按鍵子程序
ajmp loop
inti0:push psw ;保護(hù)現(xiàn)場(chǎng)
push acc
clr ea ;關(guān)中斷
mov th0,#4ch ;重賦50ms初值
mov tl0,#00h
djnz r0,out ;對(duì)50ms計(jì)數(shù)判斷
mov r0,#20 ;重賦50ms計(jì)數(shù)值
inc 31h ;秒加1
cpl p2.2 ;P2.2取反輸出
mov a,31h
cjne a,#60,out ;判秒是否加到60,沒有加到中斷返回
mov 31h,#00 ;秒加到60,對(duì)秒清零
inc 32h ;分加1
mov a,32h
cjne a,#60,out ;判分是否加到60,沒有加到就中斷返回
mov 32h,#00 ;分加到60,對(duì)分清零
inc 33h ;時(shí)加1
mov a,33h
cjne a,#24,out ;判時(shí)是否加到24,沒有就中斷返回
mov 33h,#00 ;時(shí)加到24,對(duì)時(shí)清零
out: setb ea ;開中斷
pop acc ;恢復(fù)現(xiàn)場(chǎng)
pop psw
reti ;中斷返回
inti1:push psw ;保護(hù)現(xiàn)場(chǎng)
push acc
clr ea ;關(guān)中斷
mov th1,#4ch ;賦50ms初值
mov tl1,#00h
inc 3ah
mov a,3ah
cjne a,#20,out1 ;判斷50ms計(jì)數(shù)是否到20,沒到就中斷返回
mov 3ah,#00 ;50ms計(jì)數(shù)到20,將計(jì)數(shù)單元清零
mov a,32h
cjne a,38h,out1 ;鬧鐘分與時(shí)間分判斷
mov a,33h
cjne a,39h,out1 ;鬧鐘時(shí)與時(shí)間時(shí)判斷
clr p1.0 ;相等就清p1.0輸出
out1: setb ea ;開中斷
pop acc ;恢復(fù)現(xiàn)場(chǎng)
pop psw
reti ;中斷返回
單片機(jī)四位時(shí)鐘電路設(shè)計(jì)方案(四)
附:源程序
/***************************************************************************
標(biāo)題: 定時(shí)器中斷 24小時(shí)時(shí)鐘程序
效果: 數(shù)碼管顯示24小時(shí)制時(shí)鐘(具有調(diào)時(shí)功能)
說明: 使用12M晶振 ,key1=P3^7; key2=P3^6; key3=P3^5; key4=P3^4; 數(shù)碼管位選P1.0~P1.3 ,段選P0,共陽(yáng)數(shù)碼管
******************************************************************************/
#include《reg52.h》
#define uchar unsigned char; #define uint unsigned int;
uchar position; uchar tt; uchar second; uchar minute; uchar hour;
uchar code table[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0--9
sbit smg_q = P1^0; //數(shù)碼管千位引腳 sbit smg_b = P1^1; sbit smg_s = P1^2; sbit smg_g = P1^3;
sbit key1=P3^7; //按鍵定義 sbit key2=P3^6; sbit key3=P3^5; sbit key4=P3^4;
void keyscan(); //函數(shù)聲明
void display(unsigned char hour,unsigned char minute); void delay(unsigned int timer); void init();
/***********************************************************
主函數(shù)
***********************************************************/
void main() {
init(); while(1) {
if(tt==20) { tt=0; second++;
if(second==60) {
second=0; minute++;
if(minute==60) {
minute=0; hour++;
if(hour==24) hour=0; } } }
keyscan();
display(hour,minute); delay(1); } }
/***********************************************************
調(diào)時(shí)
***********************************************************/ void keyscan() {
if(key1==0) //小時(shí)加1 {
TR0=0; hour++;
if(hour==24) hour=0; delay(200) ; TR0=1; }
if(key2==0) // 小時(shí)減 {
TR0=0; hour--;
if(hour《0) hour=23; delay(200) ; TR0=1; }
if(key3==0) // 分鐘加 {
TR0=0; minute++;
if(minute==60) minute=0; delay(200) ; TR0=1; }
if(key4==0) // 分鐘減 {
TR0=0;
minute--;
if(minute《0)
minute=59; delay(200) ; TR0=1; } }
/***********************************************************
初始化
***********************************************************/ void init() {
tt=0;
position=0; second=0; minute=0; hour=0; smg_q=1; smg_b=1; smg_s=1; smg_g=1; key1=1; key2=1;
TMOD=0X01;
TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; }
/***********************************************************
定時(shí)器TO中斷
***********************************************************/ void t0() interrupt 1 {
TH0=(65536-50000)/256; TL0=(65536-50000)%256; tt++; }
/***********************************************************
顯示
***********************************************************/
void display(unsigned char hour,unsigned char minute) {
P0=0XFF; switch(position) {
case 0: smg_g=1; smg_q=0;
P0=table[hour/10]; break;
case 1:
smg_q=1; smg_b=0;
P0=table[hour%10];
if(tt》=10)
P0&=0x7f; //小數(shù)點(diǎn)以半秒的時(shí)間閃爍 break;
case 2:
smg_b=1; smg_s=0; P0=table[minute/10]; break;
case 3: smg_s=1; smg_g=0;
P0=table[minute%10]; break; }
position++; if(position》3) position=0; }
/***********************************************************
延時(shí)
***********************************************************
/ void delay(unsigned int time) {
unsigned int x,y; for(x=time;x》0;x--) for(y=110;y》0;y--);
評(píng)論
查看更多