單片機(jī)電子時鐘的設(shè)計(畢業(yè)設(shè)計)_第1頁
單片機(jī)電子時鐘的設(shè)計(畢業(yè)設(shè)計)_第2頁
單片機(jī)電子時鐘的設(shè)計(畢業(yè)設(shè)計)_第3頁
單片機(jī)電子時鐘的設(shè)計(畢業(yè)設(shè)計)_第4頁
單片機(jī)電子時鐘的設(shè)計(畢業(yè)設(shè)計)_第5頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、摘 要單片機(jī),是集cpu ,ram ,rom ,計數(shù)和多種接口于一體的微控制器。自20世紀(jì)70年代問世以來,以其極高的性能價格比,受到人們的重視和關(guān)注。它體積小、重量輕、抗干擾能力強(qiáng)、環(huán)境要求不高、價格低廉、可靠性高、靈活性好、開發(fā)較為容易,廣泛應(yīng)用于智能生產(chǎn)和工業(yè)自動化上。本課題通過mcs-51單片機(jī)來設(shè)計,采用匯編語言進(jìn)行編程,可以實現(xiàn)以下一些功能:小時,分,秒和年,月,的顯示、定時報警功能。本次設(shè)計的電子時鐘系統(tǒng)由時鐘電路,lcd顯示電路,定時報警電路,按鍵調(diào)整電路四部分組成。51單片機(jī)通過軟件編程,在lcd1602液晶屏上實現(xiàn)小時,分,秒和年,月,的顯示;利用時鐘芯片ds1302來實現(xiàn)

2、計時,定時功能;通過兩個按鍵開關(guān),一個用于時鐘的調(diào)節(jié),一個用于鬧鐘的調(diào)節(jié),來實現(xiàn)參數(shù)設(shè)置和調(diào)節(jié)功能;到達(dá)設(shè)置的鬧鐘時間時,由蜂鳴器發(fā)聲,起報警作用。本次設(shè)計的電子時鐘,經(jīng)過對比測試,發(fā)現(xiàn)實際計時的走時精度較高,可滿足多種場合的應(yīng)用需求。本文詳細(xì)介紹了at89c51單片機(jī)的基本原理,分析了at89c51各個管腳的功能及它在設(shè)計電路中的作用。本文論述了lcd1602液晶屏和時鐘芯片ds1302的工作原理及其軟件設(shè)計過程。關(guān)鍵詞:單片機(jī);電子時鐘;時鐘芯片;lcd16021 引 言單片機(jī),亦稱單片微電腦或單片微型計算機(jī)。它是把中央處理器(cpu)、隨機(jī)存取存儲器(ram)、只讀存儲器(rom)、輸入

3、/輸出端口 (i/0)等主要計算機(jī)功能部件都集成在一塊集成電路芯片上的微型計算機(jī)。單片機(jī)是把主要計算機(jī)功能部件都集成在一塊芯片上的微型計算機(jī)。它是一種集計數(shù)和多中接口于一體的微控制器,被廣泛應(yīng)用在智能產(chǎn)品和工業(yè)自動化上,而52單片機(jī)是個單片機(jī)中最為典型和最有代表性的一種。 現(xiàn)在高精度的計時工具大多數(shù)都使用了石英晶體振蕩器,由于電子鐘、石英鐘、石英表都采用了石英技術(shù),因此走時精度高,穩(wěn)定性好,使用方便,不需要經(jīng)常調(diào)試,數(shù)字式電子鐘用集成電路計時時,譯碼代替機(jī)械式傳動,用led顯示器代替指針顯示進(jìn)而顯示時間,減小了計時誤差,這種表具有時、分、秒顯示時間的功能,還可以進(jìn)行時和分的校對,片選的靈活性好

4、。2 系統(tǒng)結(jié)構(gòu)整個電子時鐘系統(tǒng)電路可分為五大部分:中央處理單元(cpu)、顯示部分、鍵盤輸入部分、溫度采集部分。2 1 中央處理單元cpu選用at89c52對整個系統(tǒng)進(jìn)行控制:1)它將定時數(shù)據(jù)輸出到led,實現(xiàn)時間的顯示;2)根據(jù)鍵盤輸入調(diào)用相應(yīng)鍵處理子程序,實現(xiàn)時間的調(diào)整設(shè)定;3)接收溫度傳感器輸入的溫度數(shù)據(jù),進(jìn)行一定轉(zhuǎn)換,輸出到lcd顯示器顯示。22 顯示部分顯示部分是整個電子時鐘最為重要的部分,它分為時間的顯示和溫度的顯示兩部分,采用動態(tài)顯示方式,動態(tài)顯示方式是時間數(shù)字在led上逐個顯示,通過位選端控制在哪個led上顯示數(shù)字,由于led數(shù)字顯示之間的時間非常的短,人眼看來是一起顯示時間數(shù)

5、字的,并且動態(tài)顯示方式所用的接口少,節(jié)省了cpu的管腳。由于端口的問題以及動態(tài)顯示方式的優(yōu)越性,在此設(shè)計的連接方式上采用共陰級接法。23 鍵盤部分它是整個系統(tǒng)中最簡單的部分,根據(jù)功能要求,本系統(tǒng)共需四個按鍵:功能移位鍵、功能加鍵、功能減鍵、立刻跳出調(diào)整模式鍵采用獨立式按鍵。24 溫度采集部分 此部分選用ds18b20傳感器,主要由四部分組成:64位rom、溫度傳感器、非揮發(fā)的溫度報警觸發(fā)器th和tl、配置寄存器。有三個管腳:dq為數(shù)字信號輸入/輸出端;gnd為電源地;vdd為外接供電電源輸入端。它是支持“一線總線”接口的溫度傳感器,測量溫度范圍為-55c+125c,在-10+85c范圍內(nèi),可編

6、程為9位12位a/d轉(zhuǎn)換精度,工作電壓在3v5v之間?,F(xiàn)場溫度直接以“一線總線”的數(shù)字方式傳輸,大大提高了系統(tǒng)的抗干擾性。2電路制作根據(jù)電路圖(如圖示1)將元器件布置在電路板上:如圖(1)系統(tǒng)程序設(shè)計#include #include /#include lcd1602.h/#include ds1302.h#define uint unsigned int#define uchar unsigned charsbit ds1302_clk = p17; /實時時鐘時鐘線引腳 sbit ds1302_io = p16; /實時時鐘數(shù)據(jù)線引腳 sbit ds1302_rst = p15; /實時

7、時鐘復(fù)位線引腳sbit wireless_1 = p30;sbit wireless_2 = p31;sbit wireless_3 = p32;sbit wireless_4 = p33;sbit acc0 = acc0;sbit acc7 = acc7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; /秒,分,時到日,月,年位閃的計數(shù)sbit set = p20; /模式切換鍵sbit up = p21; /加法按鈕sbit down = p22; /減法按鈕sbit out = p23;

8、/立刻跳出調(diào)整模式按鈕sbit dq = p10; /溫度傳送數(shù)據(jù)io口char done,count,temp,flag,up_flag,down_flag;uchar temp_value; /溫度值uchar tempbuffer5,week_value2;void show_time(); /液晶顯示程序/*1602液晶顯示部分子程序*/port definitions*sbit lcdrs= p25;sbit lcdrw= p26;sbit lcden = p27;sfr dbport = 0x80;/p0=0x80,p1=0x90,p2=0xa0,p3=0xb0.數(shù)據(jù)端口/內(nèi)部等待

9、函數(shù)*unsigned char lcd_wait(void)lcdrs=0;lcdrw=1;_nop_();lcden=1;_nop_();lcden=0;return dbport;/lcd寫入命令或數(shù)據(jù)*#define lcd_command0 / command#define lcd_data1 / data#define lcd_clear_screen0x01 / 清屏#define lcd_homing 0x02 / 光標(biāo)返回原點void lcd_write(bit style, unsigned char input)lcden=0;lcdrs=style;lcdrw=0;_n

10、op_();dbport=input;_nop_();/注意順序lcden=1;_nop_();/注意順序lcden=0;_nop_();lcd_wait();/設(shè)置顯示模*#define lcd_show0x04 /顯示開#define lcd_hide0x00 /顯示關(guān) #define lcd_cursor0x02 /顯示光標(biāo)#define lcd_no_cursor0x00 /無光標(biāo) #define lcd_flash0x01 /光標(biāo)閃動#define lcd_no_flash0x00 /光標(biāo)不閃動void lcd_setdisplay(unsigned char displaymode

11、)lcd_write(lcd_command, 0x08|displaymode);/設(shè)置輸入模*#define lcd_ac_up0x02#define lcd_ac_down0x00 / default#define lcd_move0x01 / 畫面可平移#define lcd_no_move0x00 /defaultvoid lcd_setinput(unsigned char inputmode)lcd_write(lcd_command, 0x04|inputmode);/初始化lcd*void lcd_initial()lcden=0;lcd_write(lcd_command,

12、0x38); /8位數(shù)據(jù)端口,2行顯示,5*7點陣lcd_write(lcd_command,0x38);lcd_setdisplay(lcd_show|lcd_no_cursor); /開啟顯示, 無光標(biāo)lcd_write(lcd_command,lcd_clear_screen); /清屏lcd_setinput(lcd_ac_up|lcd_no_move); /ac遞增, 畫面不動/液晶字符輸入的位置*void gotoxy(unsigned char x, unsigned char y)if(y=0)lcd_write(lcd_command,0x80|x);if(y=1)lcd_w

13、rite(lcd_command,0x80|(x-0x40);void print(unsigned char *str)while(*str!=0)lcd_write(lcd_data,*str);str+;/*ds1302時鐘部分子程序*/typedef struct _systemtime_unsigned char second;unsigned char minute;unsigned char hour;unsigned char week;unsigned char day;unsigned char month;unsigned char year;unsigned char

14、datestring11;unsigned char timestring9;systemtime;/定義的時間類型systemtime currenttime;#define am(x)x#define pm(x)(x+12) / 轉(zhuǎn)成24小時制#define ds1302_second0x80 /時鐘芯片的寄存器位置,存放時間#define ds1302_minute0x82#define ds1302_hour0x84 #define ds1302_week0x8a#define ds1302_day0x86#define ds1302_month0x88#define ds1302_y

15、ear0x8c void ds1302inputbyte(unsigned char d) /實時時鐘寫入一字節(jié)(內(nèi)部函數(shù)) unsigned char i; acc = d; for(i=8; i0; i-) ds1302_io = acc0; /相當(dāng)于匯編中的 rrc ds1302_clk = 1; ds1302_clk = 0; acc = acc 1; unsigned char ds1302outputbyte(void) /實時時鐘讀取一字節(jié)(內(nèi)部函數(shù)) unsigned char i; for(i=8; i0; i-) acc = acc 1; /相當(dāng)于匯編中的 rrc acc7

16、 = ds1302_io; ds1302_clk = 1; ds1302_clk = 0; return(acc); void write1302(unsigned char ucaddr, unsigned char ucda) ds1302_rst = 0; ds1302_clk = 0; ds1302_rst = 1; ds1302inputbyte(ucaddr); / 地址,命令 ds1302inputbyte(ucda); / 寫1byte數(shù)據(jù) ds1302_clk = 1; ds1302_rst = 0; unsigned char read1302(unsigned char

17、ucaddr)/讀取ds1302某地址的數(shù)據(jù) unsigned char ucdata; ds1302_rst = 0; ds1302_clk = 0; ds1302_rst = 1; ds1302inputbyte(ucaddr|0x01); / 地址,命令 ucdata = ds1302outputbyte(); / 讀1byte數(shù)據(jù) ds1302_clk = 1; ds1302_rst = 0; return(ucdata);void ds1302_gettime(systemtime *time) /獲取時鐘芯片的時鐘數(shù)據(jù)unsigned char readvalue;readvalu

18、e = read1302(ds1302_second);time-second = (readvalue&0x70)4)*10 + (readvalue&0x0f);readvalue = read1302(ds1302_minute);time-minute = (readvalue&0x70)4)*10 + (readvalue&0x0f);readvalue = read1302(ds1302_hour);time-hour = (readvalue&0x70)4)*10 + (readvalue&0x0f);readvalue = read1302(ds1302_day);time-d

19、ay = (readvalue&0x70)4)*10 + (readvalue&0x0f);readvalue = read1302(ds1302_week);time-week = (readvalue&0x70)4)*10 + (readvalue&0x0f);readvalue = read1302(ds1302_month);time-month = (readvalue&0x70)4)*10 + (readvalue&0x0f);readvalue = read1302(ds1302_year);time-year = (readvalue&0x70)4)*10 + (readval

20、ue&0x0f);void datetostr(systemtime *time) /將時間年,月,日,星期數(shù)據(jù)轉(zhuǎn)換成液晶顯示字符串,放到數(shù)組里datestring if(hide_year2) /這里的if,else語句都是判斷位閃爍,2就不顯示,輸出字符串為 2007/07/22 time-datestring0 = 2; time-datestring1 = 0; time-datestring2 = time-year/10 + 0; time-datestring3 = time-year%10 + 0; else time-datestring0 = ; time-datestri

21、ng1 = ; time-datestring2 = ; time-datestring3 = ;time-datestring4 = /;if(hide_monthdatestring5 = time-month/10 + 0; time-datestring6 = time-month%10 + 0; else time-datestring5 = ; time-datestring6 = ; time-datestring7 = /;if(hide_daydatestring8 = time-day/10 + 0; time-datestring9 = time-day%10 + 0;

22、else time-datestring8 = ; time-datestring9 = ; if(hide_weekweek%10 + 0; /星期的數(shù)據(jù)另外放到 week_value數(shù)組里,跟年,月,日的分開存放,因為等一下要在最后顯示 else week_value0 = ; week_value1 = 0;time-datestring10 = 0; /字符串末尾加 0 ,判斷結(jié)束字符void timetostr(systemtime *time) /將時,分,秒數(shù)據(jù)轉(zhuǎn)換成液晶顯示字符 if(hide_hourtimestring0 = time-hour/10 + 0; time-t

23、imestring1 = time-hour%10 + 0; else time-timestring0 = ; time-timestring1 = ;time-timestring2 = :; if(hide_mintimestring3 = time-minute/10 + 0; time-timestring4 = time-minute%10 + 0; else time-timestring3 = ; time-timestring4 = ; time-timestring5 = :; if(hide_sectimestring6 = time-second/10 + 0; tim

24、e-timestring7 = time-second%10 + 0; else time-timestring6 = ; time-timestring7 = ; time-datestring8 = 0;void initial_ds1302(void) /時鐘芯片初始化 unsigned char second=read1302(ds1302_second);if(second&0x80) /判斷時鐘芯片是否關(guān)閉 write1302(0x8e,0x00); /寫入允許write1302(0x8c,0x07);/寫入初始化值07/07/25.星期:3.時間: 23:59:55write13

25、02(0x88,0x07);write1302(0x86,0x25);write1302(0x8a,0x07);write1302(0x84,0x23);write1302(0x82,0x59);write1302(0x80,0x55);write1302(0x8e,0x80); /禁止寫入/*ds18b20子程序*/*ds18b20延遲子函數(shù)(晶振12mhz )*/ void delay_18b20(unsigned int i)while(i-);/*ds18b20初始化函數(shù)*/void init_ds18b20(void) unsigned char x=0; dq = 1; /dq復(fù)位

26、 delay_18b20(8); /稍做延時 dq = 0; /單片機(jī)將dq拉低 delay_18b20(80); /精確延時 大于 480us dq = 1; /拉高總線 delay_18b20(14); x=dq; /稍做延時后 如果x=0則初始化成功 x=1則初始化失敗 delay_18b20(20);/*ds18b20讀一個字節(jié)*/ unsigned char readonechar(void)uchar i=0;uchar dat = 0;for (i=8;i0;i-) dq = 0; / 給脈沖信號 dat=1; dq = 1; / 給脈沖信號 if(dq) dat|=0x80;

27、delay_18b20(4); return(dat);/*ds18b20寫一個字節(jié)*/ void writeonechar(uchar dat) unsigned char i=0; for (i=8; i0; i-) dq = 0; dq = dat&0x01; delay_18b20(5); dq = 1; dat=1; /*讀取ds18b20當(dāng)前溫度*/void readtemp(void)unsigned char a=0;unsigned char b=0;unsigned char t=0;init_ds18b20();writeonechar(0xcc); / 跳過讀序號列號的

28、操作writeonechar(0x44); / 啟動溫度轉(zhuǎn)換delay_18b20(100); / this message is wery importantinit_ds18b20();writeonechar(0xcc); /跳過讀序號列號的操作writeonechar(0xbe); /讀取溫度寄存器兩個就是溫度delay_18b20(100);a=readonechar(); /讀取溫度值低位b=readonechar(); /讀取溫度值高位temp_value=b4; void temp_to_str() /溫度數(shù)據(jù)轉(zhuǎn)換成液晶字符顯示 tempbuffer0=temp_value/1

29、0+0; /十位 tempbuffer1=temp_value%10+0; /個位 tempbuffer2=0xdf; /溫度符號 tempbuffer3=c; tempbuffer4=0;void delay1ms(unsigned int count)unsigned int i,j;for(i=0;icount;i+)for(j=0;j0;delay-) for(i=0;i0x59) /超過59秒,清零 temp=0; break; case 2: temp=read1302(ds1302_minute);/讀取分?jǐn)?shù) temp=temp+1; /分?jǐn)?shù)加1 up_flag=1; if(te

30、mp0x59) /超過59分,清零 temp=0; break; case 3: temp=read1302(ds1302_hour);/讀取小時數(shù) temp=temp+1; /小時數(shù)加1 up_flag=1; if(temp0x23) /超過23小時,清零 temp=0; break; case 4: temp=read1302(ds1302_week);/讀取星期數(shù) temp=temp+1; /星期數(shù)加1 up_flag=1; if(temp0x7) temp=1; break; case 5: temp=read1302(ds1302_day); /讀取日數(shù) temp=temp+1; /

31、日數(shù)加1 up_flag=1; if(temp0x31) temp=1; break; case 6: temp=read1302(ds1302_month);/讀取月數(shù) temp=temp+1; /月數(shù)加1 up_flag=1; if(temp0x12) temp=1; break; case 7: temp=read1302(ds1302_year); /讀取年數(shù) temp=temp+1; /年數(shù)加1 up_flag=1; if(temp0x85) temp=0; break; default:break; while(up=0); while(wireless_2=1); void do

32、wnkey()/降序按鍵 down=1; if(down=0|wireless_3=1) mdelay(8); switch(count) case 1: temp=read1302(ds1302_second);/讀取秒數(shù) temp=temp-1;/秒數(shù)減1 down_flag=1; /數(shù)據(jù)調(diào)整后更新標(biāo)志 if(temp=0x7f) /小于0秒,返回59秒 temp=0x59; break; case 2: temp=read1302(ds1302_minute);/讀取分?jǐn)?shù) temp=temp-1; /分?jǐn)?shù)減1 down_flag=1; if(temp=-1) temp=0x59; /小于

33、0秒,返回59秒 break; case 3: temp=read1302(ds1302_hour);/讀取小時數(shù) temp=temp-1; /小時數(shù)減1 down_flag=1; if(temp=-1) temp=0x23; break; case 4: temp=read1302(ds1302_week);/讀取星期數(shù) temp=temp-1; /星期數(shù)減1 down_flag=1; if(temp=0) temp=0x7; break; case 5: temp=read1302(ds1302_day); /讀取日數(shù) temp=temp-1; /日數(shù)減1 down_flag=1; if(

34、temp=0) temp=31; break; case 6: temp=read1302(ds1302_month); /讀取月數(shù) temp=temp-1; /月數(shù)減1 down_flag=1; if(temp=0) temp=12; break; case 7: temp=read1302(ds1302_year); /讀取年數(shù) temp=temp-1; /年數(shù)減1 down_flag=1; if(temp=-1) temp=0x85; break; default:break; while(down=0); while(wireless_3=1); void setkey()/模式選擇按

35、鍵set=1;if(set=0|wireless_4=1) mdelay(8); count=count+1; /setkey按一次,count就加1 done=1; /進(jìn)入調(diào)整模式 while(set=0); while(wireless_4=1); void keydone()/按鍵功能執(zhí)行 uchar second; if(flag=0) /關(guān)閉時鐘,停止計時 write1302(0x8e,0x00); /寫入允許 temp=read1302(0x80); write1302(0x80,temp|0x80); write1302(0x8e,0x80); /禁止寫入 flag=1; set

36、key(); /掃描模式切換按鍵 switch(count) case 1:do /count=1,調(diào)整秒 outkey(); /掃描跳出按鈕 upkey(); /掃描加按鈕 downkey(); /掃描減按鈕 if(up_flag=1|down_flag=1) /重新寫入新的數(shù)據(jù) write1302(0x8e,0x00); /寫入允許 write1302(0x80,temp|0x80); /寫入新的秒數(shù) write1302(0x8e,0x80); /禁止寫入 up_flag=0; down_flag=0; hide_sec+; /位閃計數(shù) if(hide_sec3) hide_sec=0;

37、show_time(); /液晶顯示數(shù)據(jù) while(count=2);break; case 2:do /count=2,調(diào)整分 hide_sec=0; outkey(); upkey(); downkey(); if(temp0x60) temp=0; if(up_flag=1|down_flag=1) write1302(0x8e,0x00); /寫入允許 write1302(0x82,temp); /寫入新的分?jǐn)?shù) write1302(0x8e,0x80); /禁止寫入 up_flag=0; down_flag=0; hide_min+; if(hide_min3) hide_min=0; show_time(); while(count=3);break; case 3:do /cou

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論