第一篇:電氣工程及其自動(dòng)化單片機(jī)課程設(shè)計(jì)
河北建筑工程學(xué)院
單片機(jī)課程設(shè)計(jì)任務(wù)書(shū)
課程名稱(chēng):
單片機(jī)原理及應(yīng)用 系 :
電氣工程系 專(zhuān) 業(yè):
電氣工程及其自動(dòng)化 班 級(jí): 學(xué) 號(hào): 2008308112 學(xué)生姓名:
指導(dǎo)教師: 職 稱(chēng):
講師
2012 年 1 月 1 日
一·摘要
近年來(lái)隨著計(jì)算機(jī)在社會(huì)領(lǐng)域的滲透和大規(guī)模集成電路的發(fā)展,單片機(jī)的應(yīng)用正在不斷地走向深入,由于它具有功能強(qiáng),體積小,功耗低,價(jià)格便宜,工作可靠,使用方便等特點(diǎn),因此越來(lái)越廣泛地應(yīng)用各個(gè)領(lǐng)域.本文的電子鐘系統(tǒng)是以單片機(jī)(AT89C51)為核心,時(shí)鐘芯片DS1302、數(shù)碼管顯示驅(qū)動(dòng)芯片74LS164等元器件組成。具體介紹應(yīng)用protell軟件進(jìn)行單片機(jī)系統(tǒng)的電子鐘設(shè)計(jì)與仿真的實(shí)現(xiàn)方法。該方法既能準(zhǔn)確驗(yàn)證所設(shè)計(jì)的系統(tǒng)是否滿(mǎn)足技術(shù)要求,又能提高系統(tǒng)設(shè)計(jì)的效率和質(zhì)量,降低開(kāi)發(fā)成本,具有推廣價(jià)值。
關(guān)鍵詞:?jiǎn)纹瑱C(jī); 時(shí)鐘芯片 ;數(shù)碼管顯示驅(qū)動(dòng)芯片 ;電子鐘
二·系統(tǒng)總體方案設(shè)計(jì)
隨著電子技術(shù)的發(fā)展,人類(lèi)不斷研究,不斷創(chuàng)新紀(jì)錄。萬(wàn)年歷目前已經(jīng)不再局限于以書(shū)本形式出現(xiàn)。以電腦軟件或者電子產(chǎn)品形式出現(xiàn)的萬(wàn)年歷被稱(chēng)為電子萬(wàn)年歷。與傳統(tǒng)書(shū)本形式的萬(wàn)年歷相比,電子萬(wàn)年歷得到了越來(lái)越廣泛的應(yīng)用,采用電子時(shí)鐘作為時(shí)間顯示已經(jīng)成為一種時(shí)尚。目前市場(chǎng)上各式各樣的電子時(shí)鐘數(shù)不勝數(shù),但多數(shù)是只針對(duì)時(shí)間顯示,功能單一不能滿(mǎn)足人們?nèi)粘I钚枨蟆?/p>
本文提出了一種基于AT89C51單片機(jī)的萬(wàn)年歷設(shè)計(jì)方案,本方案以AT89C51單片機(jī)作為主控核心,與時(shí)鐘芯片DS1302、按鍵、LED顯示等模塊組成硬件系統(tǒng)。在硬件系統(tǒng)中設(shè)有獨(dú)立按鍵和LED顯示器,能顯示豐富的信息,根據(jù)使用者的需要可以隨時(shí)對(duì)時(shí)間進(jìn)行校準(zhǔn)、選擇時(shí)間等,綜上所述此萬(wàn)年歷具有讀取方便、顯示直觀、功能多樣、電路簡(jiǎn)潔、成本低廉等諸多優(yōu)點(diǎn),符合電子儀器儀表的發(fā)展趨勢(shì),具有廣闊的市場(chǎng)前景。
1.功能要求
本電子時(shí)鐘能顯示星期、小時(shí)、分鐘、秒
2.技術(shù)可行性
隨著國(guó)內(nèi)超大規(guī)模集成電路的出現(xiàn),微處理器及其外圍芯片有了迅速的發(fā)展。集成技術(shù)的最新發(fā)展之一是將CPU和外圍芯片,如程序存儲(chǔ)器、數(shù)據(jù)存儲(chǔ)器、并行I/O口、串行I/O口、定時(shí)/計(jì)數(shù)器、中斷控制器及其他控制部件集成在一個(gè)芯片之中,制成單片計(jì)算機(jī)(Single-Chip Microcomputer)。而近年來(lái)推出的一些高檔單片機(jī)還包括有許多特殊功能單元,如A/D、D/A轉(zhuǎn)換器、調(diào)制解調(diào)器、通信控制器、鎖相環(huán)、DMA、浮點(diǎn)運(yùn)算單元、PWM控
4.DS1302簡(jiǎn)介
(1)DS1302特性介紹
DS1302是美國(guó)DALLAS公司推出的一種高性能、低功耗的實(shí)時(shí)時(shí)鐘芯片,附加31字節(jié)靜態(tài)RAM,采用SPI三線接口與CPU進(jìn)行通信,并可采用突發(fā)方式一次傳送多個(gè)字節(jié)的時(shí)鐘信號(hào)和RAM數(shù)據(jù)。實(shí)時(shí)時(shí)鐘可提供秒、分、時(shí)、日、星期、月和年,一個(gè)月小與31天時(shí)可以自動(dòng)調(diào)整,且具有閏年補(bǔ)償功能。工作電壓寬達(dá)2.5~5.5V。采用雙電源供電(主電源和備用電源),可設(shè)置備用電源充電方式,提供了對(duì)后備電源進(jìn)行涓細(xì)電流充電的能力。
(2)DS1302引腳介紹
各引腳的功能為:、Vcc1:備用電池端;
1、Vcc2:5V電源。當(dāng)Vcc2>Vcc1+0.2V時(shí),由Vcc2向DS1302供電,當(dāng)Vcc2< Vcc1時(shí),由Vcc1向DS1302供電。
7、SCLK:串行時(shí)鐘,輸入;
6、I/O:數(shù)據(jù)輸入輸出口;
5、CE/RST:復(fù)位腳
3、X1、X2 是外接晶振腳(32.768KHZ的晶振)
4、地(GND)
(4)DS1302有關(guān)日歷、時(shí)間的寄存器
寄存器的說(shuō)明如下:
1、秒寄存器(81h、80h)的位7定義為時(shí)鐘暫停標(biāo)志(CH)。當(dāng)初始上電時(shí)該位置為1,時(shí)鐘振蕩器停止,DS1302處于低功耗狀態(tài);只有將秒寄存器的該位置改寫(xiě)為0時(shí),時(shí)鐘才能開(kāi)
6(2)時(shí)鐘電路DS1302
DS1302的性能特性: ● 實(shí)時(shí)時(shí)鐘,可對(duì)秒、分、時(shí)、日、周、月以及帶閏年補(bǔ)償?shù)哪赀M(jìn)行比較; ● 用于高速數(shù)據(jù)暫存的31*8位RAM; ● 最少引腳的串行I/O; ● 2.5~5.5V電壓工作范圍; ● 2.5V時(shí)耗小于300nA;
● 用于時(shí)鐘或RAM數(shù)據(jù)讀/寫(xiě)的單字節(jié)或多字節(jié)(脈沖方式)數(shù)據(jù)傳送方式; ● 簡(jiǎn)單的三線接口;
● 可選的慢速充電(至Vcc1)的能力。
DS1302在任何數(shù)據(jù)傳送時(shí)必須先初始化,把RST腳置為高電平,然后把8位地址和命令字裝入移位寄存器,數(shù)據(jù)在SCLK的上升沿被訪問(wèn)到。在開(kāi)始8個(gè)時(shí)鐘周期,把命令字節(jié)裝入移位寄存器后,另外的時(shí)鐘周期在讀操作時(shí)輸出數(shù)據(jù),在寫(xiě)操作時(shí)寫(xiě)入數(shù)據(jù)。時(shí)鐘脈沖的個(gè)數(shù)在單字節(jié)方式下為8+8,在多字節(jié)方式下為8+字節(jié)數(shù),最大可達(dá)248字節(jié)數(shù)。如果在傳送過(guò)程中置RST腳為低電平,則會(huì)終止本次數(shù)據(jù)傳送,并且I/O引腳變?yōu)楦咦钁B(tài)。上電運(yùn)行時(shí),在Vcc≥2.5V之前,RST腳必須保持低電平。只有在SCLK為低電平時(shí),才能將RST置為高電平。
DS1302的控制字如表所示。控制字節(jié)的最高有效位(位7)必須是邏輯1,如果它為0,則不能把數(shù)據(jù)寫(xiě)入到DS1302中。位6如果為0,則表示存取日歷時(shí)鐘數(shù)據(jù);為1則表示存取RAM數(shù)據(jù)。位5~1(A4~A0)指示操作單元的地址。最低有效位(位0)如果為0,則表示藥進(jìn)行寫(xiě)操作;為1表示進(jìn)行讀操作??刂谱止?jié)總是從最低位開(kāi)始輸入/輸出。
為了提高對(duì)32個(gè)地址尋址能力(地址/命令位1~5=邏輯1),可以把時(shí)鐘/日歷或RAM寄存器規(guī)定為多字節(jié)(burst)方式。位6規(guī)定時(shí)鐘或RAM,而位0規(guī)定讀或?qū)憽T跁r(shí)鐘/日歷寄存器中的地址9~31或RAM寄存器中的地址31不能存儲(chǔ)數(shù)據(jù)。在多字節(jié)方式下,讀或?qū)憦牡刂?的位0開(kāi)始。必須按數(shù)據(jù)傳送的次序?qū)懽钕鹊?個(gè)寄存器。但是,當(dāng)以多字節(jié)方式寫(xiě)RAM時(shí),為了傳送數(shù)據(jù)不必寫(xiě)所有的31字節(jié),不管是否謝了全部31字節(jié),所寫(xiě)的每一字節(jié)都將傳送至RAM。
DS1302共有12個(gè)寄存器,其中有7個(gè)寄存器與日歷、時(shí)鐘相關(guān),存放的數(shù)據(jù)位為BCD碼形式。其日歷、時(shí)間寄存器及其控制字如上表所示,其中奇數(shù)為讀操作,偶數(shù)為寫(xiě)操作。
時(shí)鐘暫停:秒寄存器的位7定義位時(shí)鐘暫停位。當(dāng)它為1時(shí),DS1302停止振蕩,進(jìn)入低功耗的備份方式,通常在對(duì)DS1302進(jìn)行寫(xiě)操作時(shí)(如進(jìn)入時(shí)鐘調(diào)整程序),停止振蕩。當(dāng)它為0時(shí),時(shí)鐘將開(kāi)始啟動(dòng)。
AM-PM/12-24小時(shí)方式:小時(shí)寄存器的位7定義為12或24小時(shí)方式選擇位。它為高電平時(shí),選擇12小時(shí)方式。在此方式下,位5為第二個(gè)10小時(shí)位(20~23h)。
DS1302的晶振選用32768Hz,電容推薦值為6pF。因?yàn)檎袷庮l率較低,也可以不接電容,對(duì)計(jì)時(shí)精度影響不大。
9DS1302的晶振選用32768Hz,電容推薦值為6pF。因?yàn)檎袷庮l率較低,也可以不接電容,對(duì)計(jì)時(shí)精度影響不大。
四· 系統(tǒng)軟件設(shè)計(jì)
1.程序設(shè)計(jì)
電子萬(wàn)年歷的程序主要包括3個(gè)方面的內(nèi)容:一是DS1302從單片機(jī)中讀取數(shù)據(jù)進(jìn)行計(jì)數(shù),二是利用按鍵進(jìn)行時(shí)間的調(diào)整,三是74LS164從單片機(jī)中讀取數(shù)據(jù)驅(qū)動(dòng)LED數(shù)碼管顯示時(shí)間。
AT89C51單片機(jī)主要I/O口的分配,P2.0-P2.2分別接74LS164的DIN,LOAD,CLK三個(gè)功能端,P3接查詢(xún)式按鍵,P1.0-P1.2分別接DS1302的CLK,IO,RST端。
2.時(shí)間控制流程圖
DS1302時(shí)控流程圖
附錄 電子時(shí)鐘程序
#include
//定義10ms計(jì)數(shù)器 sbit K1 = P3^2;
//定義K1鍵 sbit K2 = P3^3;
//定義K2鍵 sbit K3 = P3^4;
//定義K3鍵 sbit K4 = P3^5;
//定義K4鍵 sbit BEEP=P3^7;//定義蜂鳴器 sbit reset = P1^2;sbit sclk = P1^0;sbit io
= P1^1;sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;bit K1_FLAG=0;
//定義按鍵標(biāo)志位,當(dāng)按下K1鍵時(shí),該位置1,K1鍵未按下時(shí),該位為0。uchar code line1_data[] = {“---LCD Clcok---”};
//定義第1行顯示的字符 uchar code line2_data[] = {“****”};
//定義第2行顯示的字符 uchar disp_buf[8] ={0x00};
//定義顯示緩沖區(qū) uchar time_buf[7] ={0,0,0x12,0,0,0,0};//DS1302時(shí)間緩沖區(qū),存放秒、分、時(shí)、日、月、星期、年 uchar temp [2]={0};
//用來(lái)存放設(shè)置時(shí)的小時(shí)、分鐘的中間值 /********以下是函數(shù)聲明********/ void Delay_ms(uint xms);bit lcd_busy();
void lcd_wcmd(uchar cmd);
void lcd_wdat(uchar dat);
void lcd_clr();void lcd_init();void write_byte(uchar inbyte);
//寫(xiě)一字節(jié)數(shù)據(jù)函數(shù)聲明 uchar read_byte();
//讀一字節(jié)數(shù)據(jù)函數(shù)聲明 void write_ds1302(uchar cmd,uchar indata);//寫(xiě)DS1302函數(shù)聲明 uchar read_ds1302(uchar addr);
//讀DS1302函數(shù)聲明
void set_ds1302(uchar addr,uchar *p,uchar n);//設(shè)置DS1302初始時(shí)間函數(shù)聲明 void get_ds1302(uchar addr,uchar *p,uchar n);//讀當(dāng)前時(shí)間函數(shù)聲明 void init_ds1302();
//DS1302初始化函數(shù)聲明 /********以下是延時(shí)函數(shù)********/ void Delay_ms(uint xms)
{ uint i,j;for(i=xms;i>0;i--)
//i=xms即延時(shí)約xms毫秒
for(j=110;j>0;j--);} /********以下是LCD忙碌檢查函數(shù)********/
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}
/********以下是LCD清屏函數(shù)********/ void lcd_clr()
{
lcd_wcmd(0x01);
//清除LCD的顯示內(nèi)容
Delay_ms(5);
}
/********以下是LCD初始化函數(shù)********/ void lcd_init()
{
Delay_ms(15);
//等待LCD電源穩(wěn)定
lcd_wcmd(0x38);
//16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)
Delay_ms(5);
lcd_wcmd(0x38);
Delay_ms(5);
lcd_wcmd(0x38);
Delay_ms(5);
lcd_wcmd(0x0c);
//顯示開(kāi),關(guān)光標(biāo)
Delay_ms(5);
lcd_wcmd(0x06);
//移動(dòng)光標(biāo)
Delay_ms(5);
lcd_wcmd(0x01);
//清除LCD的顯示內(nèi)容
Delay_ms(5);
}
/********以下是寫(xiě)一字節(jié)數(shù)據(jù)函數(shù)********/ void write_byte(uchar inbyte){
uchar i;
for(i=0;i<8;i++)
{
sclk=0;
//寫(xiě)時(shí)低電平改變數(shù)據(jù)
if(inbyte&0x01)
io=1;
else
io=0;
sclk=1;
//高電平把數(shù)據(jù)寫(xiě)入DS1302
_nop_();
inbyte=inbyte>>1;
{
write_ds1302(addr,*p);
p++;
addr=addr+2;
}
write_ds1302(0x8e,0x80);
//寫(xiě)保護(hù),不允許寫(xiě) } ********讀取當(dāng)前時(shí)間函數(shù)******** void get_ds1302(uchar addr,uchar *p,uchar n){
for(;n>0;n--)
{
*p=read_ds1302(addr);
p++;
addr=addr+2;
} } ********初始化DS1302函數(shù)********/ void init_ds1302(){
reset=0;
sclk=0;
write_ds1302(0x80,0x00);//寫(xiě)秒寄存器
write_ds1302(0x90,0xab);//寫(xiě)充電器
write_ds1302(0x8e,0x80);//寫(xiě)保護(hù)控制字,禁止寫(xiě) }
/*********以下是蜂鳴器響一聲函數(shù)********/ void beep(){
BEEP=0;
//蜂鳴器響
Delay_ms(100);
BEEP=1;
//關(guān)閉蜂鳴器
Delay_ms(100);
} /********以下是轉(zhuǎn)換函數(shù),負(fù)責(zé)將走時(shí)數(shù)據(jù)轉(zhuǎn)換為適合LCD顯示的數(shù)據(jù)********/ void LCD_conv(uchar in1,in2,in3)
//形參in1、in2、in3接收實(shí)參time_buf[2]、time_buf[1]、time_buf[0]傳來(lái)的小時(shí)、分鐘、秒數(shù)據(jù) { disp_buf[0]=in1/10+0x30;
//小時(shí)十位數(shù)據(jù)
disp_buf[1]=in1%10+0x30;
//小時(shí)個(gè)位數(shù)據(jù)
disp_buf[2]=in2/10+0x30;
//分鐘十位數(shù)據(jù)
disp_buf[3]=in2%10+0x30;
//分鐘個(gè)位數(shù)據(jù)
disp_buf[4]=in3/10+0x30;
//秒十位數(shù)據(jù)
disp_buf[5]=in3%10+0x30;
//秒個(gè)位數(shù)據(jù) }
{
Delay_ms(10);//延時(shí)去抖
if(K4==0)
{
while(!K4);//等待K4鍵釋放
beep();
write_ds1302(0x80,0x00);//調(diào)整完畢后,啟動(dòng)時(shí)鐘運(yùn)行
write_ds1302(0x8e,0x80);//寫(xiě)保護(hù)控制字,禁止寫(xiě)
K1_FLAG=0;//將K1鍵按下標(biāo)志位清0
} } }
/********以下是讀取時(shí)間函數(shù),負(fù)責(zé)讀取當(dāng)前的時(shí)間,并將讀取到的時(shí)間轉(zhuǎn)換為10進(jìn)制數(shù)********/ void get_time(){ uchar sec,min,hour;
//定義秒、分和小時(shí)變量
write_ds1302(0x8e,0x00);
//控制命令,WP=0,允許寫(xiě)操作
write_ds1302(0x90,0xab);
//涓流充電控制
sec=read_ds1302(0x81);
//讀取秒
min=read_ds1302(0x83);
//讀取分
hour=read_ds1302(0x85);
//讀取時(shí)
time_buf[0]=sec/16*10+sec%16;
//將讀取到的16進(jìn)制數(shù)轉(zhuǎn)化為10進(jìn)制
time_buf[1]=min/16*10+min%16;
//將讀取到的16進(jìn)制數(shù)轉(zhuǎn)化為10進(jìn)制
time_buf[2]=hour/16*10+hour%16;
//將讀取到的16進(jìn)制數(shù)轉(zhuǎn)化為10進(jìn)制 } /********以下是主函數(shù)********/ void main(void){ uchar i;P0 = 0xff;P2 = 0xff;lcd_init();
//LCD初始化函數(shù)(在LCD驅(qū)動(dòng)程序軟件包中)
lcd_clr();
//清屏函數(shù)(在LCD驅(qū)動(dòng)程序軟件包中)
lcd_wcmd(0x00|0x80);
//設(shè)置顯示位置為第1行第0列
i = 0;
while(line1_data[i]!= '