|
一、 設(shè)計(jì)目的與要求 設(shè)計(jì)目的:通過(guò)設(shè)計(jì),培養(yǎng)運(yùn)用已學(xué)知識(shí)解決實(shí)際問(wèn)題的能力、查閱資料的能力、自學(xué)能力和獨(dú)立分析問(wèn)題、解決問(wèn)題的能力和能通過(guò)獨(dú)立思考。 設(shè)計(jì)要求:設(shè)計(jì)一個(gè)時(shí)、分可調(diào)的數(shù)字電子鐘、斷電后將數(shù)據(jù)保存,開(kāi)啟后時(shí)間將從斷電后時(shí)間繼續(xù)行走。 二、 設(shè)計(jì)內(nèi)容與方案制定具有校時(shí)功能,按鍵控制電路其中時(shí)鍵、分鍵六個(gè)鍵分別控制時(shí)、分時(shí)間的調(diào)整。按下小時(shí)數(shù)實(shí)現(xiàn)對(duì)小時(shí)數(shù)加減,按下分鐘數(shù)實(shí)現(xiàn)對(duì)分鐘數(shù)進(jìn)行加減,并設(shè)置有復(fù)位鍵,啟始鍵。 以AT89C51單片機(jī)進(jìn)行實(shí)現(xiàn)秒、分、時(shí)上的正常顯示和進(jìn)位,其中顯示功能由單片機(jī)控制共陰極數(shù)碼管來(lái)實(shí)現(xiàn),數(shù)碼管進(jìn)行動(dòng)態(tài)顯示。 通過(guò)AT24C02分別寫入時(shí)、分、秒數(shù)據(jù)在斷電后實(shí)現(xiàn)保存,在下次通電后將數(shù)據(jù)讀出保持為斷電前數(shù)據(jù)。 三、 芯片簡(jiǎn)介1、 AT89C52AT89C52是一個(gè)低電壓,高性能CMOS8位單片機(jī),片內(nèi)含8k bytes的可反復(fù)擦寫的Flash只讀程序存儲(chǔ)器和256 bytes的隨機(jī)存取數(shù)據(jù)存儲(chǔ)器(RAM),器件采用ATMEL公司的高密度、非易失性存儲(chǔ)技術(shù)生產(chǎn),兼容標(biāo)準(zhǔn)MCS-51指令系統(tǒng),片內(nèi)置通用8位中央處理器和Flash存儲(chǔ)單元,AT89C52單片機(jī)在電子行業(yè)中有著廣泛的應(yīng)用。 AT89C52有40個(gè)引腳,32個(gè)外部雙向輸入/輸出(I/O)端口,同時(shí)內(nèi)含2個(gè)外中斷口,3個(gè)16位可編程定時(shí)計(jì)數(shù)器,2個(gè)全雙工串行通信口,2 個(gè)讀寫口線,AT89C52可以按照常規(guī)方法進(jìn)行編程,也可以在線編程。其將通用的微處理器和Flash存儲(chǔ)器結(jié)合在一起,特別是可反復(fù)擦寫的 Flash存儲(chǔ)器可有效地降低開(kāi)發(fā)成本。 AT89C52為8 位通用微處理器,采用工業(yè)標(biāo)準(zhǔn)的C51內(nèi)核,在內(nèi)部功能及管腳排布上與通用的8xc52 相同,其主要用于會(huì)聚調(diào)整時(shí)的功能控制。功能包括對(duì)會(huì)聚主IC 內(nèi)部寄存器、數(shù)據(jù)RAM及外部接口等功能部件的初始化,會(huì)聚調(diào)整控制,會(huì)聚測(cè)試圖控制,紅外遙控信號(hào)IR的接收解碼及與主板CPU通信等。主要管腳有:XTAL1(19 腳)和XTAL2(18 腳)為振蕩器輸入輸出端口,外接12MHz 晶振。RST/Vpd(9 腳)為復(fù)位輸入端口,外接電阻電容組成的復(fù)位電路。VCC(40 腳)和VSS(20 腳)為供電端口,分別接+5V電源的正負(fù)端。P0~P3 為可編程通用I/O 腳,其功能用途由軟件定義,在本設(shè)計(jì)中,P0 端口(32~39 腳)被定義為N1功能控制端口,分別與N1的相應(yīng)功能管腳相連接,13 腳定義為IR輸入端,10 腳和11腳定義為I2C總線控制端口,分別連接N1的SDAS(18腳)和SCLS(19腳)端口,12 腳、27 腳及28 腳定義為握手信號(hào)功能端口,連接主板CPU的相應(yīng)功能端,用于當(dāng)前制式的檢測(cè)及會(huì)聚調(diào)整狀態(tài)進(jìn)入的控制功能。 2、 AT24C02AT24C02支持I2C,總線數(shù)據(jù)傳送協(xié)議I2C,總線協(xié)議規(guī)定任何將數(shù)據(jù)傳送到總線的器件作為發(fā)送器。任何從總線接收數(shù)據(jù)的器件為接收器。數(shù)據(jù)傳送是由產(chǎn)生串行時(shí)鐘和所有起始停止信號(hào)的主器件控制的。主器件和從器件都可以作為發(fā)送器或接收器,但由主器件控制傳送數(shù)據(jù)(發(fā)送或接收)的模式,由于A0、A1和A2可以組成000~111八種情況,即通過(guò)器件地址輸入端A0、A1和A2可以實(shí)現(xiàn)將最多8個(gè)AT24C02器件連接到總線上,通過(guò)進(jìn)行不同的配置進(jìn)行選擇器件。 AT24C02的存儲(chǔ)容量為2K bit,內(nèi)容分成32頁(yè),每頁(yè)8Byte,共256Byte,操作時(shí)有兩種尋址方式:芯片尋址和片內(nèi)子地址尋址。 (1)芯片尋址:AT24C02的芯片地址為1010,其地址控制字格式為1010A2A1A0R/W。其中A2,A1,A0可編程地址選擇位。A2,A1,A0引腳接高、低電平后得到確定的三位編碼,與1010形成7位編碼,即為該器件的地址碼。R/W為芯片讀寫控制位,該位為0,表示芯片進(jìn)行寫操作。 (2)片內(nèi)子地址尋址:芯片尋址可對(duì)內(nèi)部256B中的任一個(gè)進(jìn)行讀/寫操作,其尋址范圍為00~FF,共256個(gè)尋址單位。
四、 設(shè)計(jì)步驟
1.2.各單元電路及工作原理(1)按鍵控制電路 鍵盤可實(shí)現(xiàn)對(duì)時(shí)間的校對(duì),用四個(gè)按鍵來(lái)實(shí)現(xiàn)。按下小時(shí)數(shù)加實(shí)現(xiàn)對(duì)小時(shí)數(shù)進(jìn)行加一,按下小時(shí)數(shù)減實(shí)現(xiàn)對(duì)小時(shí)數(shù)減一,按下分鐘數(shù)加一實(shí)現(xiàn)對(duì)分鐘數(shù)加一,按下分鐘數(shù)減一實(shí)現(xiàn)對(duì)分鐘數(shù)減一。當(dāng)按下復(fù)位鍵時(shí)時(shí)間回到初始時(shí)間,按下啟停鍵時(shí)時(shí)鐘開(kāi)始工作在次按下停止工作。 其電路連接圖如下:
LED顯示器是現(xiàn)在最常用的顯示器之一發(fā)光二極管(LED)分段式顯示器由7條線段圍成8字型,每一段包含一個(gè)發(fā)光二極管。外加正向電壓時(shí)二極管導(dǎo)通,發(fā)出清晰的光。只要按規(guī)律控制各發(fā)光段亮、滅,就可以顯示各種字形或符號(hào)。顯示電路顯示模塊需要實(shí)時(shí)顯示當(dāng)前的時(shí)間,即時(shí)、分、秒,因此需要6個(gè)數(shù)碼管,采用動(dòng)態(tài)顯示方式顯示時(shí)間,其硬件連接方式如下圖所示。
(3)AT24C02連接電路
AT24C02支持I2C,總線數(shù)據(jù)傳送協(xié)議I2C,總線協(xié)議規(guī)定任何將數(shù)據(jù)傳送到總線的器件作為發(fā)送器。任何從總線接收數(shù)據(jù)的器件為接收器。數(shù)據(jù)傳送是由產(chǎn)生串行時(shí)鐘和所有起始停止信號(hào)的主器件控制的。通過(guò)AT24C02分別寫入時(shí)、分、秒數(shù)據(jù)在斷電后實(shí)現(xiàn)保存,在下次通電后將數(shù)據(jù)讀出保持為斷電前數(shù)據(jù)。 1.3.繪制原理圖 其計(jì)時(shí)周期為24小時(shí),顯示滿刻度為23時(shí)59分59秒。整個(gè)設(shè)計(jì)圖由復(fù)位電路、AT89C51單片機(jī)、鍵盤控制電路組成。 顯示電路將“時(shí)”、“分”、“秒”通過(guò)七段顯示器顯示出來(lái),6個(gè)數(shù)碼管的段選接到單片機(jī)的P0口,位選接到單片機(jī)的P2口。數(shù)碼管按照數(shù)碼管動(dòng)態(tài)顯示的工作原理工作。 把定時(shí)器定時(shí)時(shí)間設(shè)為50ms,則計(jì)數(shù)溢出20次即得時(shí)鐘計(jì)時(shí)最小單位秒,而20次計(jì)數(shù)可用軟件方法實(shí)現(xiàn),每累計(jì)60秒進(jìn)1分,每累計(jì)60分鐘,進(jìn)1小時(shí)。時(shí)采用24進(jìn)制計(jì)時(shí)器,可實(shí)現(xiàn)對(duì)一天24小時(shí)的累計(jì)。 校時(shí)電路時(shí)用來(lái)對(duì)“時(shí)”、“分”顯示數(shù)字進(jìn)行校對(duì)調(diào)整,時(shí)分秒三個(gè)控制鍵分別接單片機(jī)的p3.2、p3.3、P3.4、P3.5進(jìn)行控制。按一下分鍵秒單元就加1 ,按一下時(shí)鍵分就加1。將AT24C02接入P3.1和P3.2對(duì)斷電后數(shù)據(jù)保存,通電后數(shù)據(jù)從斷電前恢復(fù)運(yùn)行。
1.4.元件清單列表
2、程序設(shè)計(jì)2.1程序流程 數(shù)字電子鐘采用內(nèi)部硬件定時(shí)器來(lái)進(jìn)行定時(shí)。sec等于60,應(yīng)將sec清零,同時(shí)min加1。如果min等于60,應(yīng)將min清零,同時(shí)h加1。如果h大于23時(shí),應(yīng)將h清零,當(dāng)h小于10時(shí)十位不顯示。通過(guò)分析可知,程序中可分別由 {
num2=0;
sec++; if(sec==60) { sec=0; min++; if(min==60) { min=0; h++; if(h==24) h=0; } } } 這段程序負(fù)責(zé)秒、分、時(shí)的計(jì)時(shí)。 按鈕K1、K2和K3、K4為調(diào)時(shí)、調(diào)分控制按鍵。這兩個(gè)按鈕信號(hào)的輸入采用外部中斷方式來(lái)實(shí)現(xiàn)。若產(chǎn)生外部中斷時(shí),通過(guò)調(diào)用H或_min來(lái)實(shí)現(xiàn)調(diào)時(shí)或調(diào)分操作。通過(guò)displays()顯示時(shí)分秒中間用“-”隔開(kāi)每隔一秒實(shí)現(xiàn)閃爍。 斷電后數(shù)據(jù)保存,通過(guò)AT24C02芯片采用IIC串口通信解決掉電保護(hù),具體將時(shí)、分、秒,數(shù)據(jù)每隔一秒時(shí)間將數(shù)據(jù)寫入AT24C02中,在斷電后數(shù)據(jù)停留在斷電前,通電后數(shù)據(jù)恢復(fù)。 2.2主程序: void main() { init(); sec=read_add(0); if(sec>60) sec=0; min=read_add(1); if(min>60) min=0; h=read_add(2); if(h>24) h=0; if(write==1) { write=0; write_add(0,sec); write_add(1,min); write_add(2,h); } }
} 在主程序中先將讀出保存數(shù)據(jù)分別賦給h、min、sec然后判斷計(jì)時(shí)器是否到了一秒,如果到了就在24C02的地址0中寫入sec在地址1中寫入min在地址2中寫入h。最終實(shí)現(xiàn)數(shù)據(jù)斷電的保存。
2.2.源程序:#include<reg52.h> #define uchar unsigned char #define uint unsigned int Ucharcode tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; bit write=0; sbit key1=P3^2; sbit key2=P3^3; sbit key3=P3^4; sbit key4=P3^5; sbit key5=P3^6; sbit key6=P3^7; sbit sda=P3^1; sbit scl=P3^0; void delayms(uint); void display(); sbit key=P3^2; ucharnum2,secshi,secge,minshi,minge,hshi,hge; uchar mun=0,sec=0,min=20,h=5; void displays(); void keyscan(); void delay() {;;} void start() { sda=1; delay(); scl=1; delay(); sda=0; delay(); }
void stop() { sda=0; delay(); scl=1; delay(); sda=1; delay(); }
void respons() { uchari; scl=1; delay(); while((sda==1)&&(i<250)) i++; scl=0; delay(); } void init() { sda=1; delay(); scl=1; delay(); }
void write_byte(uchar date) { uchari,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; scl=0; delay(); sda=CY; delay(); scl=1; delay(); } scl=0; delay(); sda=1; delay(); }
uchar read_byte() { uchari,k; scl=0; delay(); sda=1; delay(); for(i=0;i<8;i++) { scl=1; delay(); k=(k<<1)|sda; scl=0; delay(); } returnk; }
void write_add(ucharaddress,uchar date) { start(); write_byte(0xa0); respons(); write_byte(address); respons(); write_byte(date); respons(); stop();
start(); write_byte(0xa1); respons(); write_byte(address); respons(); write_byte(date); respons(); stop();
start(); write_byte(0xa2); respons(); write_byte(address); respons(); write_byte(date); respons(); stop(); }
uchar read_add(uchar address) { uchardate; start(); write_byte(0xa0); respons(); write_byte(address); respons(); start(); write_byte(0xa1); respons(); date=read_byte(); stop(); start(); write_byte(0xa2); respons(); write_byte(address); respons(); start(); write_byte(0xa3); respons(); write_byte(address); respons(); returndate; }
void main() { init(); sec=read_add(0); if(sec>60) sec=0; min=read_add(1); if(min>60) min=0; h=read_add(2); if(h>24) h=0;
TMOD=0x01; EA=1; ET0=1; TH0=(65536-45872)/256; TL0=(65536-45872)%256; TR0=1; while(1) {
displays(); display(); if(write==1) { write=0; write_add(0,sec); write_add(1,min); write_add(2,h);
}
keyscan(); }
}
void displays() { if(num2==0) { P2=0xdb; P0=0x40; delayms(2); } }
void display( ) { secshi=sec/10; secge=sec%10; minshi=min/10; minge=min%10; hshi=h/10; hge=h%10;
P2=0xbf; P0=tab[secshi]; delayms(2); P2=0x7f; P0=tab[secge]; delayms(2);
P2=0xf7; P0=tab[minshi]; delayms(2); P2=0xef; P0=tab[minge];
delayms(2); P2=0xfe; P0=tab[hshi]; delayms(2); P2=0xfd; P0=tab[hge]; delayms(2); }
void delayms(uint xms) { uintx,y; for(x=xms;x>0;x--) for(y=110;y>0;y--); }
void keyscan() { if(key1==0) { delayms(10); if(key1==0) { h++; if(h==24) { h=0; } while(!key1); } }
if(key2==0) { delayms(10); if(key2==0) { h--; if(h==0) { h=24; } while(!key2);
} } if(key3==0) { delayms(10); if(key3==0) { min++; if(min==60) min=0; while(!key3); } }
if(key4==0) { delayms(10); if(key4==0) { if(min==0) min=60; min--; while(!key4); } } if(key5==0) { delayms(10); if(key5==0) { min=20; h=5; sec=0; while(!key5); } } if(key6==0) { delayms(10); if(key6==0) { while(!key6); TR0=~TR0; } } } void T0_time()interrupt 1 { TH0=(65536-45872)/256; TL0=(65536-45872)%256; num2++; if(num2==20) { num2=0; sec++; write=1; if(sec==60) { sec=0; min++; if(min==60) { min=0; h++; if(h==24) { h=0; } } }
} }
實(shí)物圖: |