|
1.png (73.02 KB, 下載次數(shù): 40)
下載附件
2023-1-3 17:39 上傳
一、設(shè)計(jì)內(nèi)容
內(nèi)容:用單片機(jī)控制實(shí)現(xiàn)基本數(shù)字電子鐘的設(shè)計(jì),擴(kuò)展了4X4鍵盤和4位LED數(shù)碼顯示器,可用于顯示和按鍵控制。
功能:能夠顯示時(shí)和分;可通過按鍵設(shè)置鬧鐘功能;可進(jìn)行整點(diǎn)報(bào)時(shí);可通過按鍵設(shè)置分校時(shí)。
二、總體方案設(shè)計(jì)
2.1 功能分析
數(shù)字電子鐘系統(tǒng)可以分為主控制單元、復(fù)位電路、鍵盤電路、顯示電路等。
2.2 各模塊功能說明
晶振電路的功能:每個(gè)單片機(jī)系統(tǒng)里都有晶振,全程是叫晶體震蕩器,在單片機(jī)系統(tǒng)里晶振的作用非常大,他結(jié)合單片機(jī)內(nèi)部的電路,產(chǎn)生單片機(jī)所必須的時(shí)鐘頻率,單片機(jī)的一切指令的執(zhí)行都是建立在這個(gè)基礎(chǔ)上的,晶振的提供的時(shí)鐘頻率越高,那單片機(jī)的運(yùn)行速度也就越快。晶振用一種能把電能和機(jī)械能相互轉(zhuǎn)化的晶體在共振的狀態(tài)下工作,以提供穩(wěn)定,精確的單頻振蕩。
復(fù)位電路的功能:把電路初始化到一個(gè)確定的狀態(tài),一般來說,單片機(jī)復(fù)位電路作用是把一個(gè)例如狀態(tài)機(jī)初始化到空狀態(tài),而在單片機(jī)內(nèi)部,復(fù)位的時(shí)候單片機(jī)是把一些寄存器以及存儲(chǔ)設(shè)備裝入廠商預(yù)設(shè)的一個(gè)值。
鍵盤電路:根據(jù)4×4矩陣鍵盤,它是用四條I/O線作為行線,四條I/O線作為列線組成的鍵盤。在行線和列線的每個(gè)交叉點(diǎn)上設(shè)置一個(gè)按鍵。這樣鍵盤上按鍵的個(gè)數(shù)就為4×4個(gè)。這種行列式鍵盤結(jié)構(gòu)能有效地提高單片機(jī)系統(tǒng)中I/O口的利用率。實(shí)現(xiàn)按鍵控制鬧鐘,設(shè)置時(shí)間的功能。
顯示電路的功能:采用4位共陰極數(shù)碼管驅(qū)動(dòng)方式P2口相應(yīng)的位置0 即選擇要顯示的數(shù)碼管位,P0口相應(yīng)的位置1即可顯示相應(yīng)的數(shù)碼管段。負(fù)責(zé)顯示時(shí)鐘的時(shí)和分。
三、硬件系統(tǒng)設(shè)計(jì)
使用了Produce軟件進(jìn)行硬件原理圖的仿真設(shè)計(jì)。
部分電路如圖所示:
a. 主控電路: 80C51單片機(jī)
b. 晶振電路:89C51單片機(jī)內(nèi)部的振蕩電路是一個(gè)高增益反相放大器,引線XTAL1和XTAL2分別 為反相振蕩放大器的輸入及內(nèi)部時(shí)鐘工作電路的輸入和來自反相振蕩器的輸出,該反相放大 器可以配置為片內(nèi)振蕩器。
c. 復(fù)位電路:采用上電復(fù)位,上電后,由于電容充電,使RST持續(xù)一段時(shí)間的高電平,從而實(shí) 現(xiàn)上電復(fù)位操作。這不僅能使單片機(jī)復(fù)位,還能是單片機(jī)的外圍設(shè)備同時(shí)復(fù)位,當(dāng)程序出 現(xiàn)錯(cuò)誤時(shí),可以隨時(shí)使電路復(fù)位。
d. 鍵盤電路:當(dāng)按鍵被按下時(shí),相應(yīng)的引腳被拉低,經(jīng)掃描后,獲得鍵值,并執(zhí)行鍵功能程 序,因此通過按下同一個(gè)鍵,將執(zhí)行不同的功能程序。
e. 顯示電路:主要是數(shù)碼管顯示數(shù)字電子鐘的時(shí)和分。
四、軟件系統(tǒng)設(shè)計(jì)
4.1 程序總體流程圖
主函數(shù)的流程框圖:先進(jìn)行初始化設(shè)定初值,然后相關(guān)子程序的調(diào)用
4.2 主要模塊程序流程
1.調(diào)用中斷服務(wù)子程序,循環(huán)次數(shù)++,因?yàn)槎〞r(shí)時(shí)長(zhǎng)為50ms,所以循環(huán)次數(shù)為20時(shí),循環(huán)次數(shù)清0,秒++;秒為60時(shí)分加++,秒清0;分為60時(shí),時(shí)++,分清0;時(shí)為24時(shí),時(shí)清0,中斷返回。
2.先確認(rèn)彈簧消抖是否有鍵按下,之后判斷掃描按鍵,不同的按鍵觸發(fā)不同功能。
五、源代碼
部分代碼展示:
#include<reg51.h>
#define tl 0xba; //宏定義 tl賦初值
#define th 0x3c; //宏定義 th賦初值
sbit speaker=P3^5; //鬧鐘輸出 蜂鳴器
unsigned char code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //數(shù)碼管顯示的數(shù)字0-9的編碼
unsigned char count0,second,minit,hour; //時(shí)間時(shí)分秒
unsigned int second1,minit1,hour1;//鬧鐘時(shí)分秒
//timenum1是調(diào)節(jié)時(shí)間的按鍵按下的次數(shù)
//timenum2是調(diào)節(jié)鬧鐘的按鍵按下的次數(shù)
//f1是否在設(shè)置鬧鐘
//f2是否在設(shè)置時(shí)間
unsigned char timenum1,timenum2,f1,f2;
unsigned int dsflg;
unsigned char temp;
//延時(shí)子程序 代碼燒路軟件自動(dòng)生成的
void delay(void)
{
unsigned int i;
for(i=0;i<100;i++);
}
//50ms
//數(shù)碼管顯示
void display(void)
{
P0=led[hour/10]; //p0口送數(shù)據(jù) 拆數(shù)顯示,時(shí)的十位
P2=0xFE; //片選 P2.0
delay(); //延時(shí)
P2=0xFF; //片選關(guān)
P0=led[hour%10]; //p0口送數(shù)據(jù) 拆數(shù)顯示,時(shí)的個(gè)位
P2=0xFD; //P2.1
delay();
P2=0xFF;
P0=led[minit/10]; //p0口送數(shù)據(jù) 拆數(shù)顯示,分的十位
P2=0xFB; //P2.2
delay();
P2=0xFF;
P0=led[minit%10]; //p0口送數(shù)據(jù) 拆數(shù)顯示,分的個(gè)位
P2=0xF7; //P2.3
delay();
P2=0xFF;
}
//掃描按鍵
void keyscan()
{
unsigned char temp;
P1=0xfe; // 給P1.0賦低電平
temp=P1;
temp=temp&0xf0; //判斷P1.0那一列是否有鍵按下
if(temp!=0xf0)// 確定有鍵按下的時(shí)候
{
delay1(10); //延時(shí)子程序進(jìn)行消抖
temp=P1;
temp=temp&0xf0; //再次判斷p1.0那一列是否有鍵按下
if(temp!=0xf0) //確定有鍵按下
{
temp=P1; //將P1的值給temp
switch(temp)
{
case 0xee: //p1.4口
timenum1++; //標(biāo)記++
TR1=0; //不啟動(dòng)T1 ,關(guān)閉蜂鳴器
f2=0; //進(jìn)入調(diào)時(shí)間的狀態(tài)
if(timenum1==1||timenum2==1) //如果timenum1==1 調(diào)時(shí)
{
dsflg=0; //正在調(diào)時(shí)間
}
if(timenum1==3) 如果timenum1==4 退出
{
TR1=1; //啟動(dòng)T1
timenum1=0; //將按鍵次數(shù)歸零
dsflg=1; //退出調(diào)時(shí)間
f2=1; //退出調(diào)節(jié)時(shí)間
}
break;
case 0xde: //p1.5口
//調(diào)時(shí)間
if(timenum1==1) //如果timenum1==1 調(diào)時(shí)
{
hour++; //小時(shí)++
}
if(timenum1==2) //如果timenum1==2 調(diào)分
{
minit++;
}
//調(diào)鬧鐘
if(timenum2==1) //如果timenum2==1 調(diào)時(shí) 鬧鐘
{
hour1++; //小時(shí)++
}
if(timenum2==2) //如果timenum2==2 調(diào)分 鬧鐘
{
minit1++;
}
break;
case 0xbe: //p1.6口
speaker=1; //蜂鳴器處于不響狀態(tài)在設(shè)置時(shí)間的時(shí)候
if(timenum1==1) //如果timenum1==1 調(diào)時(shí)
{
hour--; //小時(shí)--
}
if(timenum1==2) //如果timenum1==2 調(diào)分
{
minit--; //分鐘--
}
//調(diào)鬧鐘
if(timenum2==1) //如果timenum2==1 調(diào)時(shí) 鬧鐘
{
hour1--; //小時(shí)--
}
if(timenum2==2) //如果timenum2==2 調(diào)分 鬧鐘
{
minit1--;
}
break;
case 0x7e://p1.7
timenum2++; //標(biāo)記++
f1=0; //進(jìn)入設(shè)置鬧鐘
if(timenum2==1||timenum2==2) //如果timenum2=1設(shè)定腦鐘的小時(shí)
{
dsflg=0; //正在調(diào)時(shí)間
}
if(timenum2==3) //如果timenum2=3退出
{
timenum2=0; //將按鍵次數(shù)歸零
dsflg=1; //退出調(diào)時(shí)間
f1=1; // 退出設(shè)置鬧鐘
}
break;
}
while(temp!=0xf0) //判斷按鍵是否彈起
{
temp=P1;
temp=temp&0xf0;
}
}
}
}
//按鍵控制 時(shí)間設(shè)置
void Keykonzhi()
{
if(timenum1==1) //如果timenum1==1 調(diào)時(shí)
{
if(hour>23) //限位
{
hour=0;
}
P0=led[hour/10]; //顯示小時(shí)
P2=0xFE; //小時(shí)十位 p2.0
delay();
P2=0xFF;
P0=led[hour%10]; //顯示小時(shí)
P2=0xFD; //小時(shí)個(gè)位 p2.1
delay();
P2=0xFF;
}
if(timenum1==2) 如果timenum1==2 調(diào)分 //以下也是和調(diào)時(shí)一樣的方法
{
if(minit>59)
{
minit=0;
}
P0=led[minit/10];
P2=0xFB; //分鐘十位 p2.2
delay();
P2=0xFF;
P0=led[minit%10];
P2=0xF7; //分鐘個(gè)位 p2.3
delay();
P2=0xFF;
}
}
//設(shè)置鬧鐘
void almset()
{
timenum1=0;
if(timenum2==1) //如果timenum2==1設(shè)定鬧鐘的小時(shí)
{
if(hour1>23) //限位
{
hour1=0;
}
P0=led[hour1/10];//小時(shí)顯示 十位
P2=0xFE;//p2.0
delay();
P2=0xFF;
P0=led[hour1%10];
P2=0xFD;//p2.1 小時(shí)個(gè)位 顯示
delay();
P2=0xFF;
}
if(timenum2==2) //如果timenum2==2設(shè)定鬧鐘的分鐘 和上面小時(shí)一樣
{
if(minit1>59)
{
minit1=0;
}
P0=led[minit1/10];//顯示分鐘十位
P2=0xFB; // p2.2
delay();
P2=0xFF;
P0=led[minit1%10];//顯示分鐘個(gè)位
P2=0xF7;// p2.3
delay();
P2=0xFF;
}
}
//控制鬧鐘 (鬧鐘到了設(shè)定時(shí)間就會(huì)響)
void almkozi()
{
if((hour1==hour)&&(minit1==minit)&&(second<4))
{
speaker=0; //鬧鐘時(shí)間到,蜂鳴器響
}
if(minit==0&&second<4)
{
//整點(diǎn)報(bào)時(shí),蜂鳴器響
speaker=0;
}
if(second>4) //控制蜂鳴器響的時(shí)長(zhǎng)
{
speaker=1; //關(guān)閉蜂鳴器
}
}
六、測(cè)試結(jié)果展示
1. 時(shí)鐘顯示:最開始設(shè)置時(shí)間為12:59。
2 . 鬧鐘調(diào)時(shí):手動(dòng)按鍵調(diào)整時(shí)鐘的時(shí)。
3. 鬧鐘調(diào)分:手動(dòng)按鍵調(diào)整時(shí)鐘的分。
4. 整點(diǎn)報(bào)時(shí):時(shí)鐘到整點(diǎn)蜂鳴器就會(huì)響,達(dá)到報(bào)時(shí)的效果。
在做設(shè)計(jì)的過程中,我進(jìn)一步認(rèn)識(shí)到全面專業(yè)知識(shí)以及邏輯思考方式對(duì)研究問題的重要性,同時(shí)我也更加具體的掌握了設(shè)計(jì)的基本方法。經(jīng)過不斷的努力,我終于完成了這次設(shè)計(jì),總的來說,我學(xué)到了不少的東西,知道了理論聯(lián)系實(shí)際的重要性。在設(shè)計(jì)過程中我遇到了很多的困難,但沒放棄,查閱了許多相關(guān)的書籍,自己獨(dú)立思考和借鑒了前人的許多優(yōu)秀成果,并與所學(xué)的知識(shí)緊密的結(jié)合了起來。我相信這過程對(duì)我今后的學(xué)習(xí)和工作有著積極的影響,并搭好了平臺(tái)。通過這次設(shè)計(jì),我對(duì)這門課有了更好的理解,尤其結(jié)合了這幾年學(xué)的相關(guān)的專業(yè)知識(shí),對(duì)各門課都有了一個(gè)較全面的理解。這必將對(duì)我以后的學(xué)習(xí)和工作有很大的幫助。本次設(shè)計(jì)的定時(shí)鬧鐘電路,可以滿足人們的基本要求,但因?yàn)橹R(shí)水平有限,此電路中存在一定的問題,雖可以通過增加電路解決,但過于復(fù)雜和現(xiàn)有水平有限,本次設(shè)計(jì)就未深入涉及,想要更好的改進(jìn)電路,需要進(jìn)一步的努力,如果有好的意見,希望
|
|