第12章 應(yīng)用案例設(shè)計(jì)_第1頁(yè)
第12章 應(yīng)用案例設(shè)計(jì)_第2頁(yè)
第12章 應(yīng)用案例設(shè)計(jì)_第3頁(yè)
第12章 應(yīng)用案例設(shè)計(jì)_第4頁(yè)
第12章 應(yīng)用案例設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩123頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1第12章單片機(jī)的各種控制與檢測(cè)應(yīng)用設(shè)計(jì)

介紹各種常用的單片機(jī)測(cè)控應(yīng)用設(shè)計(jì)案例,通過(guò)案例使讀者了解單片機(jī)系統(tǒng)的的各種常見的應(yīng)用設(shè)計(jì)。12.1單片機(jī)控制步進(jìn)電機(jī)的設(shè)計(jì)

步進(jìn)電機(jī)是將脈沖信號(hào)轉(zhuǎn)變?yōu)榻俏灰苹蚓€位移的開環(huán)控制元件。

非超載的情況下,電機(jī)轉(zhuǎn)速、停止位置只取決于脈沖信號(hào)的頻率和脈沖數(shù),而不受負(fù)載變化的影響,給電機(jī)加一脈沖信號(hào),電機(jī)則轉(zhuǎn)過(guò)一個(gè)步距角。因而步進(jìn)電機(jī)只有周期性誤差而無(wú)累積誤差,在速度、位置等控制領(lǐng)域有較為廣泛的應(yīng)用。2312.1.1控制步進(jìn)電機(jī)的工作原理

驅(qū)動(dòng)步進(jìn)電機(jī)由單片機(jī)通過(guò)對(duì)每組線圈中的電流的順序切換來(lái)使電機(jī)作步進(jìn)式旋轉(zhuǎn),切換是單片機(jī)輸出脈沖信號(hào)來(lái)實(shí)現(xiàn)。

調(diào)節(jié)脈沖信號(hào)頻率就可改變步進(jìn)電機(jī)轉(zhuǎn)速;改變各相脈沖先后順序,就可改變電機(jī)旋轉(zhuǎn)方向。

步進(jìn)電機(jī)驅(qū)動(dòng)可采用雙四拍(AB→BC→CD→DA→AB)方式,也可采用單四拍(A→B→C→D→A)方式。為使步進(jìn)電機(jī)旋轉(zhuǎn)平穩(wěn),還可采用單、雙八拍方式(A→AB→B→BC→C→CD→D→DA→A)。各種工作方式時(shí)序見圖12-1。

4

圖12-1

各種工作方式時(shí)序圖5

圖12-1脈沖信號(hào)是高電平有效,但實(shí)際控制時(shí)公共端是接在VCC上,所以實(shí)際控制脈沖是低電平有效。12.1.2電路設(shè)計(jì)與編程

【例12-1】單片機(jī)對(duì)步進(jìn)電機(jī)控制的原理電路見圖12-1。編寫程序,用四路I/O口輸出實(shí)現(xiàn)環(huán)形脈沖分配,控制步進(jìn)電機(jī)按固定方向連續(xù)轉(zhuǎn)動(dòng)。同時(shí),通過(guò)“正轉(zhuǎn)”和“反轉(zhuǎn)”兩個(gè)按鍵來(lái)控制電機(jī)的正轉(zhuǎn)與反轉(zhuǎn)。按下“正轉(zhuǎn)”按鍵,步進(jìn)電機(jī)正轉(zhuǎn);按下“反轉(zhuǎn)”按鍵,步進(jìn)電機(jī)反轉(zhuǎn);松開按鍵,電機(jī)停止轉(zhuǎn)動(dòng)。ULN2003是高耐壓、大電流達(dá)林頓陣列系列產(chǎn)品,7個(gè)NPN達(dá)林頓管組成。多用于單片機(jī)、智能儀表、PLC等控制電路6圖12-2

單片機(jī)控制步進(jìn)電機(jī)接口電路7中。在5V電壓下能與TTL和CMOS電路直接相連,可直接驅(qū)動(dòng)繼電器等負(fù)載。具有電流增益高、工作電壓高、溫度范圍寬、帶負(fù)載能力強(qiáng)等特點(diǎn)。輸入5V的TTL電平,輸出可達(dá)500mA/50V。適于各類高速大功率驅(qū)動(dòng)的系統(tǒng)。參考程序:#include"reg51.h"#defineucharunsignedchar#defineuintunsignedint#defineoutP2sbitpos=P0^0; //定義檢測(cè)正轉(zhuǎn)控制位P0.0sbitneg=P0^1; //定義檢測(cè)反轉(zhuǎn)控制位P0.1voiddelayms(uint);

8ucharcodeturn[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03};//步進(jìn)脈沖數(shù)組voidmain(void){ uchari; out=0x03; while(1) { if(!pos)//如果正轉(zhuǎn)按鍵按下 { i=i<8?i+1:0;//如果i<8,則i=i+1;否則i=0 out=turn[i]; delayms(50); }9elseif(!neg) { i=i>0?i-1:7; out=turn[i]; delayms(50); } }}voiddelayms(uintj) //函數(shù)功能:延時(shí){ uchari; for(;j>0;j--) { i=250; while(--i); i=249; while(--i); }}1012.2單片機(jī)控制直流電機(jī)

直流電機(jī)多用在無(wú)交流電源、方便移動(dòng)場(chǎng)合,具有低速大力矩等特點(diǎn)。如何用單片機(jī)控制直流電機(jī)。12.2.1控制直流電機(jī)的工作原理

對(duì)直流電機(jī)可精確控制其旋轉(zhuǎn)速度或轉(zhuǎn)矩,通過(guò)兩個(gè)磁場(chǎng)相互作用產(chǎn)生旋轉(zhuǎn)。結(jié)構(gòu)見圖12-3(a),定子裝設(shè)一對(duì)直流勵(lì)磁的靜止主磁極N和S,在轉(zhuǎn)子上裝設(shè)電樞鐵心。定子與轉(zhuǎn)子間有一氣隙。在電樞鐵心上放置了由兩根導(dǎo)體連成的電樞線圈,線圈首端和末端分別連到兩個(gè)圓弧形銅片上,此銅片稱為換向片。由換向片構(gòu)成的整體稱為換向器。11

換向器固定在轉(zhuǎn)軸上,換向片與轉(zhuǎn)軸間互相絕緣。在換向片上放置一對(duì)固定不動(dòng)的電刷B1和B2,當(dāng)電樞旋轉(zhuǎn)時(shí),電樞線圈通過(guò)換向片和電刷與外電路接通。

定子通過(guò)永磁體或受激勵(lì)電磁鐵產(chǎn)生一固定磁場(chǎng),由于轉(zhuǎn)子由一系列電磁體構(gòu)成,當(dāng)電流通過(guò)其中一個(gè)繞組時(shí)會(huì)產(chǎn)生一個(gè)磁場(chǎng)。

對(duì)有刷直流電機(jī),轉(zhuǎn)子上換向器和定子電刷在電機(jī)旋轉(zhuǎn)時(shí)為每個(gè)繞組供給電能。通電轉(zhuǎn)子繞組與定子磁體有相反極性,因而相互吸引,使轉(zhuǎn)子轉(zhuǎn)動(dòng)至與定子磁場(chǎng)對(duì)準(zhǔn)的位置。當(dāng)轉(zhuǎn)子到達(dá)對(duì)準(zhǔn)位置時(shí),電刷通過(guò)換向器為下一組繞組供電,從而使轉(zhuǎn)子維持旋轉(zhuǎn)運(yùn)動(dòng),見圖12-3(b)。12(a)有刷直流電機(jī)結(jié)構(gòu)示意圖(i)導(dǎo)體ad處于N極下(ii)導(dǎo)體ad處于S極下(b)有刷直流電機(jī)工作示意圖圖12-3

直流電機(jī)工作示意圖13

直流電機(jī)轉(zhuǎn)速與施加電壓成正比,轉(zhuǎn)矩與電流成正比。由于必須在工作期間改變直流電機(jī)的速度,直流電機(jī)控制是一較困難問(wèn)題。直流電機(jī)高效運(yùn)行的常見方法是施加一個(gè)PWM(脈寬調(diào)制)脈沖波,其占空比對(duì)應(yīng)于所需速度。電機(jī)起到了一個(gè)低通濾波器作用,PWM信號(hào)相對(duì)容易產(chǎn)生,這種驅(qū)動(dòng)方式使用更為廣泛。12.2.2電路設(shè)計(jì)與編程

【例12-2】原理電路見圖12-4。使用單片機(jī)兩個(gè)I/O腳控制直流電機(jī)轉(zhuǎn)速和旋轉(zhuǎn)方向。其中P3.7腳輸出PWM信號(hào)控制直流電機(jī)轉(zhuǎn)速;P3.6腳控制直流電機(jī)旋轉(zhuǎn)方向。14圖12-4

單片機(jī)控制直流電機(jī)的接口電路

當(dāng)P3.6=1時(shí),P3.7發(fā)送PWM波,直流電機(jī)正轉(zhuǎn)。且可通過(guò)“INC”和“DEC”兩個(gè)按鍵來(lái)增大和減少直流電機(jī)轉(zhuǎn)速。反之,P3.6=0時(shí),P3.7發(fā)送PWM信號(hào),直流電機(jī)反轉(zhuǎn)。

因此,增大和減小電機(jī)轉(zhuǎn)速,實(shí)際上是通過(guò)按下“INC”或“DEC”按鍵來(lái)改變輸出PWM信號(hào)占空比,控制直流電機(jī)轉(zhuǎn)速。圖12-4中驅(qū)動(dòng)電路使用了NPN低頻、低噪聲小功率達(dá)林頓管

2SC2547。參考程序如下:1516#include"reg51.h"#include"intrins.h"#defineucharunsignedchar#defineuintunsignedint sbitINC=P3^4;sbitDEC=P3^5;sbitDIR=P3^6; sbitPWM=P3^7;voiddelay(uint);intPWM=900;voidmain(void){ DIR=1; while(1) { if(!INC) PWM=PWM>0?PWM-1:0;//如果PWM>0,則PWM=PWM-1;否則PWM=01712.3電機(jī)轉(zhuǎn)速測(cè)量12.3.1電機(jī)轉(zhuǎn)速測(cè)量的工作原理

用光電管、單片機(jī)及LED數(shù)碼管可測(cè)量直流電機(jī)轉(zhuǎn)速并顯示。

光電對(duì)管,也稱光電開關(guān),內(nèi)部結(jié)構(gòu)就是一發(fā)光二極管和一個(gè)光敏三極管,分為反射式和直射式,工作原理都是光電轉(zhuǎn)化,即通過(guò)集聚光線來(lái)控制光敏三極管的導(dǎo)通與截止。

因此,測(cè)量電機(jī)轉(zhuǎn)速實(shí)質(zhì)是利用光電對(duì)管對(duì)直流電機(jī)葉片底部的白色小帶進(jìn)行檢測(cè),當(dāng)檢測(cè)到白色小帶時(shí)將產(chǎn)生一個(gè)脈沖信號(hào)。電機(jī)轉(zhuǎn)一圈對(duì)應(yīng)一個(gè)脈沖,然后對(duì)脈沖信號(hào)放大并進(jìn)行計(jì)數(shù),計(jì)算單位時(shí)間內(nèi)測(cè)得的脈沖數(shù),也就測(cè)出電機(jī)轉(zhuǎn)速,并送LED數(shù)碼管顯示。1812.3.2電路設(shè)計(jì)與編程

【例12-3】測(cè)量電機(jī)轉(zhuǎn)速電路見圖12-5。Z-OPTOCOULER-NPN為光電管,電機(jī)旋轉(zhuǎn)時(shí),使光電管輸出脈沖信號(hào),然后脈沖信號(hào)經(jīng)過(guò)放大,并對(duì)其計(jì)數(shù),經(jīng)計(jì)算,把轉(zhuǎn)速數(shù)據(jù)送到LED數(shù)碼管顯示。

模擬直流電機(jī)轉(zhuǎn)速脈沖由數(shù)字時(shí)鐘發(fā)生器產(chǎn)生,在電路中添加數(shù)字時(shí)鐘發(fā)生器方法是,點(diǎn)擊圖4-2中左側(cè)工具箱中的圖標(biāo)

,出現(xiàn)選擇菜單,選擇“DCLOCK”項(xiàng),然后把其放入原理圖編輯窗口中進(jìn)行連線。鼠標(biāo)右鍵單擊“DCLOCK”圖標(biāo),出現(xiàn)屬性設(shè)置窗口,選擇“數(shù)字類型”欄中的“時(shí)鐘”項(xiàng),在右面的“時(shí)間”欄中,手動(dòng)修改輸出的數(shù)字時(shí)鐘脈沖的頻率,這相當(dāng)于改變電機(jī)轉(zhuǎn)速。19 if(!DEC) PWM=PWM<1000?PWM+1:1000;//如PWM<1000,則PWM=PWM+1;//否則PWM=1000 PWM=1; //產(chǎn)生PWM的信號(hào)高電平 delay(PWM); //延時(shí) PWM=0; //產(chǎn)生PWM的信號(hào)低電平 delay(1000-PWM); //延時(shí) }}voiddelay(uintj){ for(;j>0;j--) { _nop_(); }}20圖12-5測(cè)量電機(jī)轉(zhuǎn)速的原理電路與仿真21

仿真運(yùn)行后,電機(jī)轉(zhuǎn)速(即每秒計(jì)得的脈沖數(shù))顯示在LED數(shù)碼管上。在手動(dòng)設(shè)置數(shù)字時(shí)鐘頻率時(shí),選擇“600”,經(jīng)過(guò)單片機(jī)測(cè)得的轉(zhuǎn)數(shù)值(轉(zhuǎn)數(shù)/秒)在數(shù)碼管上顯示,與設(shè)置的數(shù)字脈沖頻率相一致。參考程序如下。#include"reg51.h"#include"intrins.h"#defineucharunsignedchar#defineuintunsignedint#defineoutP0ucharcodeseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x01};22inti=0; voidmain(void){ intj; TMOD=0x15; //T0方式1計(jì)數(shù),T1方式1定時(shí) TH0=0; //T0計(jì)數(shù)器清零

TH1=0x3C; //12MHz晶振,T1定時(shí)50ms TL1=0xB0; TR0=1; //啟動(dòng)T0計(jì)數(shù)器

TR1=1; //啟動(dòng)T1 IE=0x88; //允許T1中斷和總中斷允許

while(1) { P2=0x00; //輸出百位顯示值 out=seg[i/100]; P2=0x02; for(j=0;j<100;j++);

P2=0x00; out=seg[i%100/10]; //輸出十位顯示值23 P2=0x04; for(j=0;j<100;j++); P2=0x00; out=seg[i%10]; //輸出個(gè)位顯示值 P2=0x08; for(j=0;j<100;j++); } }voidTimer1_ISR()interrupt3//T1中斷程序,產(chǎn)生50ms定時(shí){ staticcharj=0; TH1=0x3C; //重設(shè)定時(shí)器值,50ms定時(shí),12MHz晶振 TL1=0xB0; if(++j==20) //是否中斷20次,即50msx20次=1s { j=0; i=(TH0<<8)|TH00;//1s內(nèi)的計(jì)數(shù)值即為電機(jī)轉(zhuǎn)動(dòng)速度,單位:轉(zhuǎn)/秒 TH0=0; //T0清零 TL0=0; }}2412.4頻率計(jì)的制作12.4.1工作原理

利用單片機(jī)定時(shí)器/計(jì)數(shù)器可實(shí)現(xiàn)信號(hào)頻率測(cè)量。頻率測(cè)量有測(cè)頻法和測(cè)周法兩種。測(cè)頻法利用外部電平變化引發(fā)的外部中斷,測(cè)算1s內(nèi)出現(xiàn)的次數(shù),從而實(shí)現(xiàn)對(duì)頻率測(cè)量;測(cè)周法是通過(guò)測(cè)算某兩次電平變化引發(fā)的中斷間的時(shí)間,再求倒數(shù),從而實(shí)現(xiàn)對(duì)頻率測(cè)定??傊?,測(cè)頻法是直接根據(jù)定義來(lái)測(cè)定頻率,測(cè)周法是通過(guò)測(cè)定周期間接測(cè)定頻率。理論上,測(cè)頻法適于較高頻率測(cè)量,測(cè)周法適于較低頻率測(cè)量。本例采用測(cè)頻法。

12.4.2電路設(shè)計(jì)與軟件編程【例12-4】設(shè)計(jì)以單片機(jī)為核心的頻率測(cè)量裝置,測(cè)量加在P3.4腳上數(shù)字時(shí)鐘信號(hào)頻率,并在外部擴(kuò)展的6位LED數(shù)碼管上顯示測(cè)量頻率值。原理電路與仿真見圖12-6。

本頻率計(jì)測(cè)量的信號(hào)由數(shù)字時(shí)鐘源“DCLOCK”產(chǎn)生,在電路中添加數(shù)字時(shí)鐘源的具體操作與設(shè)置見【例12-3】。手動(dòng)改變被測(cè)時(shí)鐘信號(hào)源頻率,觀察是否與LED數(shù)碼管上顯示的測(cè)量結(jié)果相同。26圖12-6

頻率計(jì)原理電路與仿真27參考程序如下。#include<reg51.h>sfr16DPTR=0x82; //定義寄存器DPTRunsignedcharcnt_t0,cnt_t1,qian,bai,shi,ge,bb,wan,shiwan;unsignedlongfreq; //定義頻率unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共陰數(shù)碼管段碼表voiddelay_1ms(unsignedintz) //函數(shù)功能:延時(shí)約1ms{ unsignedchari,j; for(i=0;i<z;i++) for(j=0;j<110;j++);}28voidinit() //函數(shù)功能:定時(shí)器/計(jì)數(shù)器及中斷系統(tǒng)初始化{ freq=0; //頻率賦初值 cnt_t1=0; cnt_t0=0; IE=0x8a; //開中斷,T0,T1中斷 TMOD=0x15; //T0為定時(shí)器方式1,T1為計(jì)數(shù)器于方式1 TH1=0x3c; //T1定時(shí)50ms TL1=0xb0; TR1=1; //開啟定時(shí)器T1 TH0=0; //T0清0 TL0=0; TR0=1; //開啟定時(shí)器T0}voiddisplay(unsignedlongfreq_num)//函數(shù)功能:驅(qū)動(dòng)數(shù)碼管顯示{shiwan=freq_num%1000000/100000;wan=freq_num%100000/10000;29

qian=freq_num%10000/1000; //顯示千位 bai=freq_num%1000/100; //顯示百位 shi=freq_num%100/10; //顯示十位 ge=freq_num%10; //顯示個(gè)位 P0=0xdf; //P0口是位選 P2=table[shiwan]; //顯示十萬(wàn)位 delay_1ms(5); P0=0xef; P2=table[wan]; //顯示萬(wàn)位 delay_1ms(3); P0=0xf7; P2=table[qian]; //顯示千位 delay_1ms(3);30P0=0xfb; P2=table[bai]; //顯示百位 delay_1ms(3); P0=0xfd; P2=table[shi]; //顯示十位 delay_1ms(3); P0=0xfe; P2=table[ge]; //顯示個(gè)位 delay_1ms(3);}voidmain() //主函數(shù){ P0=0xff; //初始化P0口 init(); //計(jì)數(shù)器初始化 while(1) { if(cnt_t1==19) //定時(shí)1s {31

cnt_t1=0; //定時(shí)完成后清0 TR1=0; //關(guān)閉T1定時(shí)器,定時(shí)1S完成 delay_1ms(141); //延時(shí)較正誤差,通過(guò)實(shí)驗(yàn)獲得 TR0=0; //關(guān)閉T0 DPL=TH00; //利用DPTR讀入其值 DPH=TH0; freq=cnt_t0*65535; freq=freq+DPTR; //計(jì)數(shù)值放入變量}display(freq); //調(diào)用顯示函數(shù) }

}voidt1_func()interrupt3 //定時(shí)器T1的中斷函數(shù){ TH1=0x3c; TL1=0xb0;

cnt_t1++;}

32voidt0_func()interrupt1 //定時(shí)器T0的中斷函數(shù){ cnt_t0++;}

在單片機(jī)應(yīng)用系統(tǒng)中,有時(shí)往往需要一個(gè)實(shí)時(shí)時(shí)鐘/日歷作為測(cè)控時(shí)間基準(zhǔn)。時(shí)鐘/日歷集成電路芯片多種,設(shè)計(jì)者只需選擇合適芯片即可。本節(jié)介紹最為常見的時(shí)鐘/日歷芯片DS1302的功能、特性以及單片機(jī)的硬件接口設(shè)計(jì)及軟件編程。12.5基于時(shí)鐘/日歷芯片DS1302的電子鐘設(shè)計(jì)

時(shí)鐘/日歷芯片DS1302是美國(guó)DALLAS公司推出的涓流充電時(shí)鐘芯片,功能特性如下。(1)能計(jì)算2100年前的年、月、日、星期、時(shí)、分、秒的信息;每月的天數(shù)和閏年天數(shù)可自動(dòng)調(diào)整;時(shí)鐘可設(shè)置為24或12小時(shí)格式。(2)與單片機(jī)間采用單線同步串行通信。12.5.1DS1302的工作原理1.基本性能34(3)31字節(jié)的8位靜態(tài)RAM。(4)功耗低,保持?jǐn)?shù)據(jù)和時(shí)鐘信息時(shí)功率小于1mW;可選的涓流充電能力。(5)讀/寫時(shí)鐘或RAM數(shù)據(jù)有單字節(jié)和多字節(jié)兩種傳送方式。DS1302引腳見圖12-7。圖12-7DS1302的引腳35各引腳功能如下:I/O:數(shù)據(jù)輸入/輸出。SCLK:同步串行時(shí)鐘輸入。RST*:芯片復(fù)位,1—芯片的讀/寫使能,0—芯片復(fù)位并被禁止讀/寫。VCC2:主電源輸入,接系統(tǒng)電源。VCC1:備份電源輸入引腳,通常接2.7~3.5V電源。當(dāng)VCC2>VCC1+0.2V時(shí),芯片由VCC2供電;當(dāng)VCC2<VCC1時(shí),芯片由VCC1供電。GND:地X1,X2:接32.768KHz晶振引腳。

單片機(jī)與DS1302間無(wú)數(shù)據(jù)傳輸時(shí),SCLK保持低電平,此時(shí)如果

從低變?yōu)楦邥r(shí),即啟動(dòng)數(shù)據(jù)傳輸,此時(shí)SCLK的上升沿將數(shù)據(jù)寫入DS1302,而在SCLK的下降沿從DS1302讀出數(shù)據(jù)。

為低時(shí),則禁止數(shù)據(jù)傳輸,讀/寫時(shí)序如圖12-8所示。數(shù)據(jù)傳輸時(shí),低位在前,高位在后。2.DS1302的命令字格式單片機(jī)對(duì)DS1302的讀/寫,都必須由單片機(jī)先向DS1302寫入一個(gè)命令字(8位)發(fā)起,命令字的格式見表12-1。37圖12-8DS1302讀/寫時(shí)序命令字各位功能:D7:必須為邏輯1,如為0,則禁止寫入DS1302。D6:1—讀/寫RAM數(shù)據(jù),0—讀/寫時(shí)鐘/日歷數(shù)據(jù)。D5~D1:為讀/寫單元的地址;D0:1—對(duì)DS1302讀操作,0—對(duì)DS1302寫操作。注意,命令字(8位)總是低位在先,命令字每1位都是在SCLK上升沿送出。383.DS1302的內(nèi)部寄存器片內(nèi)各時(shí)鐘/日歷寄存器以及其它的功能寄存器見表12-2。通過(guò)向寄存器寫入命令字實(shí)現(xiàn)對(duì)DS1302操作。例如,如要設(shè)置秒寄存器的初始值,需要先寫入命令字80H(見表12-2),然后再向秒寄存器寫入初始值;如要讀出某時(shí)刻秒值,需要先寫入命令字81H,然后再?gòu)拿爰拇嫫髯x取秒值。表12-2中各寄存器“取值范圍”1列存放的數(shù)據(jù)均為BCD碼。39表12-2

主要寄存器、命令字與取值范圍及各位內(nèi)容40CH:時(shí)鐘暫停位,1-振蕩器停止,DS1302為低功耗方式;0-時(shí)鐘開始工作。10SEC:秒的十位數(shù)字,SEC為秒的個(gè)位數(shù)字10MIN:分的十位數(shù)字,MIN為分的個(gè)位數(shù)字12/24:12或24小時(shí)方式選擇位AP:小時(shí)格式設(shè)置位,0-上午模式(AM);1-下午模式(PM)10DATE:日期的十位數(shù)字,DATE為日期的個(gè)位數(shù)字10M:月的十位數(shù)字,MONTH為日期的個(gè)位數(shù)字DAY:星期的個(gè)位數(shù)字4110YEAR:年的十位數(shù)字,YEAR為年的十位數(shù)字

表12-2中后3個(gè)寄存器的功能及特殊位符號(hào)的意義說(shuō)明如下。寫保護(hù)寄存器:該寄存器的D7位WP是寫保護(hù)位,其余7位(D0~D6)置為0。在對(duì)時(shí)鐘/日歷單元和RAM單元進(jìn)行寫操作前,WP必須為0,即允許寫入。當(dāng)WP為1時(shí),用來(lái)防止對(duì)其它寄存器進(jìn)行寫操作。涓流充電寄存器:慢充電寄存器,用于管理對(duì)備用電源的充電。TCS:當(dāng)4位TCS=1010時(shí),才允許使用涓流充電寄存器,其他任何狀態(tài)都將禁止使用涓流充電器。DS:兩DS位用于選擇連接在VCC2和VCC1間的二極管數(shù)目。01-選擇1個(gè)二極管;10-選擇2個(gè)二極管;11或00-涓流充電器被禁止。RS:兩位RS位用于選擇涓流充電器內(nèi)部在VCC2和VCC1之間的連接電阻。RS=01,選擇R1(2kΩ);RS=10時(shí),選擇R2(4kΩ);RS=11時(shí),選擇R3(8kΩ);RS=00時(shí),不選擇任何電阻。43時(shí)鐘突發(fā)寄存器:?jiǎn)纹瑱C(jī)對(duì)DS1302除單字節(jié)數(shù)據(jù)讀/寫外,還可采用突發(fā)方式,即多字節(jié)連續(xù)讀/寫。在多字節(jié)連續(xù)讀/寫中,只要對(duì)地址為3EH的時(shí)鐘突發(fā)寄存器進(jìn)行讀/寫操作,即把對(duì)時(shí)鐘/日歷或RAM單元的讀/寫設(shè)定為多字節(jié)方式。該方式,讀/寫都開始于地址0的D0位。當(dāng)多字節(jié)方式寫時(shí)鐘/日歷時(shí),必須按照數(shù)據(jù)傳送的次序?qū)懭胱钕鹊?個(gè)寄存器;但是以多字節(jié)方式寫RAM時(shí),沒(méi)有必要寫入所有的31個(gè)字節(jié),每個(gè)被寫入的字節(jié)都被傳輸?shù)絉AM,無(wú)論31個(gè)字節(jié)是否都被寫入。12.5.2電路設(shè)計(jì)與編程44(2)閏年自動(dòng)判別。(3)鍵盤采用動(dòng)態(tài)掃描方式查詢,參量應(yīng)能進(jìn)行增1修改,由“啟動(dòng)日期與時(shí)間修改”功能鍵k1與6個(gè)參量修改鍵組合來(lái)完成增1修改。即先按一下k1,然后按一下被修改參量鍵,即可使該參量增1,修改完畢,再按一下k1表示修改結(jié)束確認(rèn)。本例時(shí)鐘/日歷原理電路與仿真見圖12-9。LCD1602分兩行顯示日歷與時(shí)鐘。45

【例12-5】制作一個(gè)使用時(shí)鐘/日歷芯片DS1302并采用LCD1602顯示的日歷/時(shí)鐘,基本功能如下。(1)顯示6個(gè)參量的內(nèi)容,第一行顯示:年、月、日;第二行顯示:時(shí)、分、秒。46圖12-9LCD顯示的時(shí)鐘/日歷原理電路及仿真47圖12-9的4×3矩陣鍵盤,只用到了其中2行鍵共6個(gè),余下的按鍵,本例未使用,可用于將來(lái)鍵盤功能擴(kuò)展。參考程序如下:#include<reg51.h>#include"LCD1602.h" //液晶顯示器LCD1602頭文件#include"DS1302.h" //時(shí)鐘/日歷芯片DS1302頭文件#defineucharunsignedchar#defineuintunsignedintbitkey_flag1=0,key_flag2=0;SYSTEMTIMEadjusted; //此處為結(jié)構(gòu)體定義48ucharsec_add=0,min_add=0,hou_add=0;ucharday_add=0,mon_add=0,yea_add=0;uchardata_alarm[7]={0};intkey_scan() //函數(shù)功能:鍵盤掃描,判是否有鍵按下{ inti=0; uinttemp; P1=0xf0; temp=P1; if(temp!=0xf0) { i=1; } else { i=0; }

returni;}49ucharkey_value() //函數(shù)功能:獲取按下的按鍵值{uintm=0,n=0,temp;ucharvalue;ucharv[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'};P1=0xfe;temp=P1;if(temp!=0xfe)m=0;//采用分行、分列掃描的形式獲取按鍵鍵值

P1=0xfd;temp=P1;if(temp!=0xfd)m=1;P1=0xfb;temp=P1;if(temp!=0xfb)m=2;P1=0xf7;temp=P1;if(temp!=0xf7)m=3;P1=0xef;temp=P1;if(temp!=0xef)n=0;P1=0xdf;temp=P1;if(temp!=0xdf)n=1;P1=0xbf;temp=P1;if(temp!=0xbf)n=2;50value=v[m][n];returnvalue;}voidadjust(void) //函數(shù)功能:修改各參量{ if(key_scan()&&key_flag1) switch(key_value()) { case'0':sec_add++;break; case'1':min_add++;break; case'2':hou_add++;break; case'3':day_add++;break; case'4':mon_add++;break; case'5':yea_add++;break;51 default:break; }adjusted.Second+=sec_add;adjusted.Minute+=min_add;adjusted.Hour+=hou_add;adjusted.Day+=day_add;adjusted.Month+=mon_add;adjusted.Year+=yea_add;if(adjusted.Second>59) { adjusted.Second=adjusted.Second%60; adjusted.Minute++; } if(adjusted.Minute>59) { adjusted.Minute=adjusted.Minute%60; adjusted.Hour++; }52if(adjusted.Hour>23) { adjusted.Hour=adjusted.Hour%24; adjusted.Day++; } if(adjusted.Day>31) adjusted.Day=adjusted.Day%31; if(adjusted.Month>12) adjusted.Month=adjusted.Month%12; if(adjusted.Year>100) adjusted.Year=adjusted.Year%100;} 53voidchanging(void)interrupt0using0//中斷處理函數(shù),修改參量,或修改確認(rèn){ if(key_flag1) key_flag1=0; else key_flag1=1;}

main() //主函數(shù){

uinti; ucharp1[]="D:",p2[]="T:"; SYSTEMTIMET;

EA=1; EX0=1; IT0=1; EA=1;54

EX1=1; IT1=1; init1602(); Initial_DS1302();

while(1){ write_com(0x80); write_string(p1,2); write_com(0xc0); write_string(p2,2); DS1302_GetTime(&T); adjusted.Second=T.Second; adjusted.Minute=T.Minute; adjusted.Hour=T.Hour; adjusted.Week=T.Week;55 adjusted.Day=T.Day; adjusted.Month=T.Month; adjusted.Year=T.Year; for(i=0;i<9;i++){ adjusted.DateString[i]=T.DateString[i]; adjusted.TimeString[i]=T.TimeString[i]; } adjust(); DateToStr(&adjusted); TimeToStr(&adjusted); write_com(0x82); write_string(adjusted.DateString,8); write_com(0xc2); write_string(adjusted.TimeString,8); delay(10); } }

56程序中,使用了自行編寫的液晶顯示器LCD1602的頭文件“LCD1602.h”,由于液晶顯示器LCD1602是單片機(jī)應(yīng)用系統(tǒng)經(jīng)常用到的器件,因此將其常用到的驅(qū)動(dòng)函數(shù)等函數(shù),寫成一個(gè)頭文件,如果以后在其他項(xiàng)目中也用到LCD1602,只需將該頭文件包含進(jìn)來(lái)即可,這樣程序的編寫提供了方便。同理涉及對(duì)時(shí)鐘/日歷芯片DS1302的控制,也可自行編寫頭文件“DS1302.h”,以后在其他項(xiàng)目中將該頭文件包含進(jìn)來(lái)即可。上述兩個(gè)頭文件清單見附錄1與附錄2。12.6電話撥號(hào)的模擬12.6.1模擬電話撥號(hào)的設(shè)計(jì)要求57設(shè)計(jì)模擬電話撥號(hào)時(shí)的狀況,把模擬電話鍵盤撥出的某一電話號(hào)碼,顯示在LCD顯示屏上。電話鍵盤除了0~9的10個(gè)數(shù)字鍵外,還有“*”鍵用于實(shí)現(xiàn)刪除功能,即刪除一位最后輸入的號(hào)碼;“#”鍵用于清除顯示屏上所有的數(shù)字顯示。此外還要求每按下一個(gè)鍵,發(fā)出聲響,表示按下該鍵。還有LCD顯示器,顯示所撥的電話號(hào)碼。12.6.2電路設(shè)計(jì)與編程【例12-6】設(shè)計(jì)一模擬電話撥號(hào)時(shí)的電話鍵盤及顯示裝置,把電話鍵盤撥出的電話號(hào)碼及其他信息,顯示在LCD顯示屏上。電話鍵盤共12個(gè)鍵,除了0~9的10個(gè)數(shù)字鍵外,還有58“*”鍵用于刪除最后輸入的1位號(hào)碼的功能;“#”鍵用于清除顯示屏上所有的數(shù)字顯示。此外還要求每按下一個(gè)鍵,蜂鳴器要發(fā)出聲響,以表示按下該鍵。顯示信息共2行,第1行為設(shè)計(jì)者信息,第2行顯示所撥的電話號(hào)碼。本例的電話撥號(hào)鍵盤采用4×3矩陣鍵盤,共12個(gè)鍵。撥號(hào)號(hào)碼顯示采用LCD1602液晶顯示模塊。因此涉及了單片機(jī)與4×3矩陣式鍵盤以及與16×2的液晶顯示屏的接口設(shè)計(jì),還有各種驅(qū)動(dòng)程序的編制。液晶顯示屏采用LCD1602

(即Proteus中的LM016L)。本設(shè)計(jì)原理電路及仿真見圖12-10。59圖12-10

電話撥號(hào)的模擬60參考程序如下。#include<reg51.h>#defineuintunsignedint#defineucharunsignedcharucharkeycode,DDram_value=0xc0;sbitrs=P2^0;sbitrw=P2^1;sbite=P2^2;sbitspeaker=P2^3;ucharcodetable[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20};ucharcodetable_designer[]="HITZYGDesign";//第1行顯示設(shè)計(jì)者信息61voidlcd_delay();voiddelay(uintn);voidlcd_init(void);voidlcd_busy(void);voidlcd_wr_con(ucharc);voidlcd_wr_data(uchard);ucharcheckkey(void);ucharkeyscan(void);voidmain(){ucharnum; lcd_init(); lcd_wr_con(0x80);62for(num=0;num<=14;num++) { lcd_wr_data(table_designer[num]); } while(1) { keycode=keyscan(); if((keycode>=0)&&(keycode<=9)){ lcd_wr_con(0x06); lcd_wr_con(DDram_value); lcd_wr_data(table[keycode]); DDram_value++; }63elseif(keycode==0x0b) { uchari,j; j=0xc0; for(i=0;i<=15;i++) { lcd_wr_con(j); lcd_wr_data(table[10]); }voidlcd_delay() //函數(shù)功能:液晶顯示延時(shí){uchary;for(y=0;y<0xff;y++){ ;}}64

voidlcd_init(void) //函數(shù)功能:液晶初始化{lcd_wr_con(0x01);lcd_wr_con(0x38);

65lcd_wr_con(0x0c);lcd_wr_con(0x06);}voidlcd_busy(void) //函數(shù)功能:判液晶是否忙{ P0=0xff; rs=0; rw=1; e=1; e=0; while(P0&0x80) { e=0;66e=1; } lcd_delay();}

voidlcd_wr_con(ucharc) //函數(shù)功能:向液晶顯示器寫入命令{lcd_busy(); e=0; rs=0; rw=0; e=1;

67 P0=c; e=0; lcd_delay();}voidlcd_wr_data(uchard)//函數(shù)功能:/向液晶寫數(shù)據(jù){ lcd_busy(); e=0; rs=1; rw=0; e=1; P0=d; e=0; lcd_delay();}68voiddelay(uintn) //函數(shù)功能:延時(shí){ uchari; uintj; for(i=50;i>0;i--)for(j=n;j>0;j--);}

ucharcheckkey(void) //函數(shù)功能:檢測(cè)鍵有無(wú)按下{ uchartemp; P1=0xf0; temp=P1;69temp=temp&0xf0; if(temp==0xf0) { return(0); } else{ return(1); }}ucharkeyscan(void) //函數(shù)功能:鍵盤掃描并返回所按下的鍵盤號(hào){ucharhanghao,liehao,keyvalue,buff;if(checkkey()==0)70{ return(0xff); //無(wú)鍵按下,返回0xff}else //無(wú)鍵按下,返回0xff{ ucharsound; for(sound=50;sound>0;sound--){ speaker=0; delay(1); speaker=1; delay(1); } P1=0x0f;71 buff=P1; if(buff==0x0e) { hanghao=0; } elseif(buff==0x0d) { hanghao=3; } elseif(buff==0x0b) { hanghao=6; }

72elseif(buff==0x07) { hanghao=9; } P1=0xf0; buff=P1; if(buff==0xe0) { liehao=2; } elseif(buff==0xd0) { liehao=1; }73elseif(buff==0xb0) { liehao=0; } keyvalue=hanghao+liehao; while(P1!=0xf0); return(keyvalue);}}7412.7簡(jiǎn)易音符發(fā)生器的制作12.7.1設(shè)計(jì)要求及工作原理

設(shè)計(jì)一個(gè)音樂(lè)音符發(fā)生器。利用分別按下鍵盤的1,2,3,4,5,6,7,1(高音)8個(gè)鍵,可發(fā)出8個(gè)不同音符的聲音,即發(fā)出“哆”、“唻”、“咪”、“發(fā)”、“嗽”、“拉”、“西”、“哆”(高音)的聲音,并且要求按下按鍵松開后延遲一段時(shí)間停止,如果再按別的鍵則發(fā)出另一音符的聲音。當(dāng)掃描到鍵盤上有鍵按下,則快速檢測(cè)是哪鍵按下,然后單片機(jī)定時(shí)器啟動(dòng),發(fā)出相應(yīng)音符頻率的脈沖,該音符脈沖輸入到蜂鳴器后,就會(huì)發(fā)出相應(yīng)的音調(diào)。如在前一個(gè)按下的鍵發(fā)聲的同時(shí)有另一個(gè)鍵被按下,則啟用中斷系統(tǒng),75前面鍵的發(fā)音停止,轉(zhuǎn)到后按下鍵的發(fā)音程序,發(fā)出相應(yīng)的音符聲音。發(fā)出不同音符聲音原理,就是發(fā)出對(duì)應(yīng)不同音符頻率的方波,即給定時(shí)器T0載入不同的定時(shí)時(shí)間常數(shù),從而產(chǎn)生對(duì)應(yīng)頻率的方波,驅(qū)動(dòng)蜂鳴器發(fā)出音符聲音。12.7.2電路設(shè)計(jì)與編程音樂(lè)音符發(fā)生器的原理電路與仿真如圖12-11所示。在“ClockFrequency”欄中輸入晶振頻率為11.0592MHz。依次按下不同的音符選擇按鍵就可發(fā)出不同聲音。76

圖12-11簡(jiǎn)易音樂(lè)音符發(fā)生器原理電路與仿真77參考程序如下://本例晶振頻率為11.0592MHz,計(jì)算各音符頻率,可得哆、唻、咪、發(fā)、嗽、拉、西、哆(高音)8個(gè)音符,應(yīng)賦給定時(shí)器的初值(十進(jìn)制)為:6440964604647056475164837649146498265032,通過(guò)定時(shí)器T0輸出不同頻率的方波#include<reg51.h>sbitP3_3=P3^3;unsignedcharidatai,TL0_temp=0,TH0_temp=0,counter=0;voidT0_func()interrupt1{ //定時(shí)器T0中斷服務(wù)程序,T0產(chǎn)生方波 counter++; TH0=TH0_temp; //裝載時(shí)間常數(shù)

TL0=TL0_temp; P3_3=~P3_3; //P3.3腳求反,輸出方波}78main() //主函數(shù) { P1=0xff; //向P1口寫入全1,輸入口

TMOD=0x01; //設(shè)定時(shí)器T0為方式1定時(shí)

ET0=1; //允許T0中斷

EA=1; //總中斷允許

TH0=0; //T0清0 TL0=0; TCON=0x10; //總中斷允許 while(1){

i=P1; if((i==0xff)||(counter>=100))//無(wú)鍵按下,或發(fā)音結(jié)束,則//停止計(jì)數(shù)79

{ TR0=0; counter=0; }//對(duì)不同音階加載不同的初值。如已在發(fā)音,則打斷當(dāng)前發(fā)音,重加載if(i==0xfe),“哆”鍵按下,加載“哆”初值

{ TR0=0; counter=0; TH0_temp=0xfb; TL0_temp=0xe9; TR0=1; //T0啟動(dòng)

} if(i==0xfd) //“唻”鍵按下,加載“唻”初值80{ TR0=0; counter=0; TH0_temp=0xfc; TL0_temp=0x5c; TR0=1; //T0啟動(dòng)

} if(i==0xfb) //“咪”鍵按下,加載“咪”初值

{ TR0=0; //停止T0 counter=0; TH0_temp=0xfc; TL0_temp=0xc1; TR0=1; 81 //T0啟動(dòng)

} if(i==0xf7) //“發(fā)”鍵按下,加載“發(fā)”初值

{ TR0=0; //停止T0 counter=0; TH0_temp=0xfc; TL0_temp=0xef; TR0=1; //T0啟動(dòng)

} if(i==0xef) 82 //“嗽”鍵按下,加載“嗽”初值

{ TR0=0; //停止T0 counter=0; TH0_temp=0xfd; TL0_temp=0x45;

TR0=1; //T0啟動(dòng)

} if(i==0xdf) //“拉”鍵按下,加載“拉”初值

{ TR0=0; //停止T0 counter=0; TH0_temp=0xfd; TL0_temp=0x92; TR0=1; }83if(i==0xbf) //“西”鍵按下,加載“西”初值

{ TR0=0; counter=0; TH0_temp=0xfd; TL0_temp=0xd6; TR0=1; }if(i==0x7f)//“哆(高音)”鍵按下,加載其初值

{ TR0=0; counter=0; TH0_temp=0xfe; TL0_temp=0x08; TR0=1; } }}8412.88位競(jìng)賽搶答器設(shè)計(jì)目前,各類競(jìng)賽中大多用到競(jìng)賽搶答器,以單片機(jī)為核心配上搶答按鈕開關(guān)以及數(shù)碼管顯示器并結(jié)合編寫的軟件,很容易制作一個(gè)競(jìng)賽搶答器,且修改方便。12.8.1設(shè)計(jì)要求設(shè)計(jì)一個(gè)以單片機(jī)為核心8位競(jìng)賽搶答器,要求如下:(1)搶答器同時(shí)供8名選手或8個(gè)代表隊(duì)比賽,分別用8個(gè)按鈕S0~S7表示。(2)設(shè)置一個(gè)系統(tǒng)清除和搶答控制開關(guān)S,該開關(guān)由主持人控制。(3)搶答器具有鎖存與顯示功能。即選手按動(dòng)按鈕,鎖存相應(yīng)的編號(hào),且優(yōu)先搶答選手的編號(hào)一直保持到主持人將系統(tǒng)清除為止。(4)搶答器具有定時(shí)搶答功能,且一次搶答時(shí)間由主持人設(shè)定(如30秒)。當(dāng)主持人啟動(dòng)“開始”鍵后,定時(shí)器進(jìn)行減計(jì)時(shí),同時(shí)揚(yáng)聲器發(fā)出短暫聲響,聲響持續(xù)時(shí)間為0.5s左右。(5)參賽選手在設(shè)定的時(shí)間內(nèi)進(jìn)行搶答,搶答有效,定時(shí)器停止工作,顯示器上顯示選手的編號(hào)和搶答剩余時(shí)間,并保持到主持人將系統(tǒng)清除為止。86(6)如定時(shí)時(shí)間已到,無(wú)人搶答,本次搶答無(wú)效,系統(tǒng)報(bào)警并禁止搶答,定時(shí)顯示器上顯示00。

通過(guò)鍵盤改變可搶答時(shí)間,可把定時(shí)時(shí)間變量設(shè)為全局變量,通過(guò)鍵盤掃描程序使每按下一次按鍵,時(shí)間加1(超過(guò)30時(shí)置0)。同時(shí)單片機(jī)不斷進(jìn)行按鍵掃描,當(dāng)參賽選手的按鍵按下時(shí),用于產(chǎn)生時(shí)鐘信號(hào)的定時(shí)計(jì)數(shù)器停止計(jì)數(shù),同時(shí)將選手編號(hào)(按鍵號(hào))和搶答時(shí)間分別顯示在LED上。12.8.2電路設(shè)計(jì)與仿真8位競(jìng)賽搶答器的原理電路與仿真見圖12-12。晶振頻率為12MHz。圖中為剩余18秒時(shí),7號(hào)選手搶答成功。87圖中MAX7219是一串行接收數(shù)據(jù)的動(dòng)態(tài)掃描顯示驅(qū)動(dòng)器。MAX7219驅(qū)動(dòng)8位以下LED顯示器時(shí),它的DIN、LOAD、CLK端分別與單片機(jī)三條口線(P3.0~P3.2)相連。

MAX7219采用16位數(shù)據(jù)串行移位接收方式,即單片機(jī)將16位二進(jìn)制數(shù)逐位發(fā)送到DIN端,在CLK的每個(gè)上升沿將一位數(shù)據(jù)移入MAX7219內(nèi)移位寄存器,當(dāng)16位數(shù)據(jù)移入完后,在LOAD腳信號(hào)上升沿將16位數(shù)據(jù)裝入MAX7219內(nèi)相應(yīng)位置,能對(duì)送入的數(shù)據(jù)進(jìn)行BCD譯碼并顯示。本例對(duì)MAX7219進(jìn)行相應(yīng)的初始化設(shè)置,具體請(qǐng)查閱有關(guān)MAX7219技術(shù)資料。88圖12-128位競(jìng)賽搶答器原理電路與仿真89參考程序如下:#include<reg51.h>sbitDIN=P3^0; //與max7219接口定義sbitLOAD=P3^1;sbitCLK=P3^2;sbitkey0=P1^0; //8路搶答器按鍵sbitkey1=P1^1;sbitkey2=P1^2;sbitkey3=P1^3;sbitkey4=P1^4;sbitkey5=P1^5;sbitkey6=P1^6;sbitkey7=P1^7;sbitkey_clear=P2^0; //主持人時(shí)間設(shè)置、清除sbitbegin=P2^1; //主持人開始按鍵90sbitsounder=P3^7; //蜂鳴器unsignedcharsecond=30; //秒表計(jì)數(shù)值unsignedcharcounter=0; //counter每100,minite加1unsignedcharpeople=0; //搶答結(jié)果unsignedcharnum_add[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};//max7219讀寫地址、內(nèi)容unsignedcharnum_dat[]={0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89};unsignedcharkeyscan()//鍵盤掃描函數(shù){unsignedcharkeyvalue,temp;keyvalue=0;P1=0xff;temp=P1;91 if(~(P1&temp)) { switch(temp) { case0xfe: keyvalue=1; break; case0xfd: keyvalue=2; break; case0xfb: keyvalue=3; break; case0xf7: keyvalue=4; break;92 case0xef: keyvalue=5; break; case0xdf: keyvalue=6; break; case0xbf: keyvalue=7;

break; case0x7f: keyvalue=8; break; default: keyvalue=0; break; } } returnkeyvalue; }93voidmax7219_send(unsignedcharadd,unsignedchardat)//函數(shù)功能:向max7219寫命令{ unsignedchar ADS,i,j;

LOAD=0; i=0; while(i<16) {

if(i<8) { ADS=add; } else { ADS=dat; }94 for(j=8;j>=1;j--) { DIN=ADS&0x80; ADS=ADS<<1; CLK=1; CLK=0; } i=i+8; } LOAD=1; }

voidmax7219_init() //函數(shù)功能:max7219初始化{ max7219_send(0x0c,0x01); max7219_send(0x0b,0x07); max7219_send(0x0a,0xf5); max7219_send(0x09,0xff);}95voidtime_display(unsignedcharx) //函數(shù)功能:時(shí)間顯示{ unsignedchari,j; i=x/10; j=x%10; max7219_send(num_add[1],num_dat[j]); max7219_send(num_add[0],num_dat[i]);}

voidscare_display(unsignedcharx)//函數(shù)功能:搶答結(jié)果顯示{ unsignedchari,j; i=x/10; j=x%10;96 max7219_send(num_add[3],num_dat[j]); max7219_send(num_add[2],num_dat[i]);}voidholderscan() //函數(shù)功能:搶答時(shí)間設(shè)置,0-60s{ time_display(second); scare_display(people); if(~key_clear) //如果有鍵按下,改變搶答時(shí)間

{ while(~key_clear); if(people) //如果搶答結(jié)果沒(méi)有清空,搶答器重置

{ second=30;97 people=0; } if(second<60) { second++; } else { second=0; } }}voidtimer_init() //定時(shí)器T0初始化{ EA=1; ET0=1; TMOD=0x01; //定時(shí)器T0方式0定時(shí)98TH0=0xd8; //裝入定時(shí)器定時(shí)常數(shù),設(shè)定10ms中斷一次TL0=0xef;}

voidmain(){while(1){do{holderscan();}while(begin); //開始前進(jìn)行設(shè)置,若未按下開始鍵

while(~begin); //防抖max7219_init(); //芯片初始化

timer_init(); //中斷初始化

TR0=1; //開始中斷

do99{time_display(second);scare_display(people);people=keyscan();}while((!people)&&(second)); //運(yùn)行直到搶答結(jié)束或時(shí)間結(jié)束

TR0=0;}}voidtimer0()interrupt1 //定時(shí)器T0中斷函數(shù){ if(counter<100) { counter++; if(counter==50) { sounder=0; }100}else{ sounder=1; counter=0; second=second-1;} TH0=0xd8; //重新裝載

TL0=0xef; TR0=1;}101

12.9電梯運(yùn)行控制的樓層顯示12.9.1工作原理與設(shè)計(jì)要求設(shè)計(jì)采用單片機(jī)控制8×8LED點(diǎn)陣屏來(lái)模仿電梯運(yùn)行的樓層顯示裝置。單片機(jī)的P1口的8只引腳接有8只按鍵開關(guān)K1~K8,這8只按鍵開關(guān)K1~K8分別代表1樓~8樓。如果某一樓層的按鍵按下,單片機(jī)控制的點(diǎn)陣屏將從當(dāng)前位置向上或向下平滑滾動(dòng)顯示到指定樓層的位置。電梯樓層顯示器初始顯示0。單片機(jī)的P1口的8只引腳接有8只按鍵開關(guān)K1~K8,這8只按鍵開關(guān)K1~K8分別代表1樓~8樓。如果按下代表某一樓層的按鍵,單片機(jī)控制的點(diǎn)陣屏將從當(dāng)前位置向上或向下平滑滾動(dòng)顯示到指定樓層的位置。12.9電梯運(yùn)行控制的樓層顯示

12.9.1工作原理與設(shè)計(jì)要求設(shè)計(jì)采用單片機(jī)控制8×8LED點(diǎn)陣屏來(lái)模仿電梯運(yùn)行的樓層顯示裝置。單片機(jī)的P1口的8只引腳接有8只按鍵開關(guān)K1~K8,這8只按鍵開關(guān)K1~K8分別代表1樓~8樓。如果某一樓層的按鍵按下,單片機(jī)控制的點(diǎn)陣屏將從當(dāng)前位置向上或向下平滑滾動(dòng)顯示到指定樓層的位置。

電梯樓層顯示器初始顯示0。單片機(jī)的P1口的8只引腳接有8只按鍵開關(guān)K1~K8,這8只按鍵開關(guān)K1~K8分別代表1樓~8樓。如果按下代表某一樓層的按鍵,單片機(jī)控制的點(diǎn)陣屏將從當(dāng)前位置向上或向下平滑滾動(dòng)顯示到指定樓層的位置。在上述功能基礎(chǔ)上,還設(shè)有LED指示燈和蜂鳴器,在到達(dá)指定樓層后蜂鳴器發(fā)出短暫聲音且LED閃爍片刻。系統(tǒng)還應(yīng)同時(shí)識(shí)別依次按下的多個(gè)按鍵,例如,當(dāng)前位置在1層時(shí),用戶依次按下1046、5時(shí),則數(shù)字分別向上滾動(dòng)到5、6時(shí)暫停且LED閃爍片刻,同時(shí)蜂鳴器發(fā)出提示音。如在待去樓層的數(shù)字中,有的在當(dāng)前運(yùn)行的反方向,則數(shù)字先在當(dāng)前方向運(yùn)行完畢后,再依次按順序前往反方向的樓層位置。12.9.2電路設(shè)計(jì)與仿真本例原理電路與仿真見圖12-13。電路中采用P2口做8×8點(diǎn)陣的行選通控制,P1口完成對(duì)樓層按鍵的讀取及確認(rèn)。105圖12-138×8LED點(diǎn)陣屏模仿電梯數(shù)字滾動(dòng)顯示電路原理圖與仿真106參考程序如下:#include"reg51.h"#include"intrins.h"#defineucharunsignedchar#defineuintunsignedintsbitp36=P3^6;sbitp37=P3^7;voiddelay(uintt);//定義全局變量uintterminal;uintoutset=0;uintflag=0;uintflag1=0;uintflag2=0;ucharcodescan[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //掃描代碼//以下為顯示“0,1,2,3,4,5,6,7,8”的8×8點(diǎn)陣代碼ucharcodezm[]={1070x00,0x18,0x24,0x24,0x24,0x24,0x18,0x00,0x00,0x10,0x1c,0x10,0x10,0x10,0x3c,0x00,0x00,0x38,0x44,0x40,0x20,0x10,0x7c,0x00,0x00,0x38,0x44,0x30,0x40,0x44,0x38,0x00,0x00,0x20,0x30,0x28,0x24,0x7e,0x20,0x00,0x00,0x7c,0x04,0x3c,0x40,0x40,0x3c,0x00,0x00,0x38,0x44,0x3c,0x44,0x44,0x38,0x00,0x00,0x7e,0x40,0x40,0x20,0x10,0x10,0x00,0x00,0x38,0x44,0x38,0x44,0x44,0x38,0x00};voidsoundandled(uintj)//函數(shù):提示樓層到,蜂鳴器發(fā)聲及LED閃亮{ uinti,k; P0=0xff;P2=0xff; for(i=0;i<20;i++) {108 p36=0; delay(10); p36=1; for(k=0;k<8;k++) { P0=scan[k]; P2=~zm[j*8+k]; p37=1; delay(5); p37=0; } } }unsignedintkeyscan(void) //函數(shù):鍵盤掃描{ if(P1!=0xff) {109switch(P1){ case0x7f:{return(8);break;} case0xbf:{return(7);break;} case0xdf:{return(6);break;} case0xef:{return(5);break;} case0xf7:{return(4);break;} case0xfb:{return(3);break;} case0xfd:{return(2);break;} case0xfe:{return(1);break;} default:return(0); }}}voiddownmove(uintm,uintn) //函數(shù):電梯下行{ uintk,j,i; for(k=m*8;k>n*8;k--)110{ for(j=0;j<30;j++){ for(i=7;i>=0&&i<8;i--){ if(P1!=0xff){ outset=keyscan(); if((outset>n)&&(outset<m)) {111 flag1=outset; outset=n; n=flag1; terminal=n; }while(P1!=0xff);}//在最里面循環(huán)中加判別,可增加按鍵靈敏度如果不加則只能是運(yùn)行//完所有循環(huán)后才進(jìn)入下一步P0=scan[i];P2=~zm[(i+k)%72];delay(1); }}}}112voidupmove(unsignedintm,unsignedintn)//函數(shù):電梯上行{ uintk,j,i; for(k=m*8;k<n*8;k++) { for(j=0;j<30;j++) { for(i=0;i<8;i++) { if(P1!=0xff) { outset=keyscan(); if((outset>m)&&(outset<n)) { flag1=outset; outset=n; n=flag1;113terminal=n; }while(P1!=0xff);}//在最里面循環(huán)中加入判別可增加按鍵靈敏度如不加則只能運(yùn)行完所//有循環(huán)才進(jìn)入下一步

P0=scan[i]; P2=~zm[(i+k)%72]; delay(1); } }}}114voidshow(unsignedinti) //函數(shù):電梯靜止,并等待鍵盤{ uintk; while(P1!=0xff); while(P1==0xff) { for(k=0;k<8;k++) { P0=scan[k]; P2=~zm[i*8+k]; delay(1); } }}115voidmain() //主程序{ p37

溫馨提示

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

評(píng)論

0/150

提交評(píng)論