版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
單片機(jī)接口與應(yīng)用第一章單片機(jī)基本組成第二章C51程序設(shè)計(jì)第三章片內(nèi)接口1.1單片機(jī)的基本概念1.1.1單片機(jī)的定義單片機(jī)是把CPU、存儲(chǔ)器、定時(shí)器/計(jì)數(shù)器、中斷系統(tǒng)和多種I/O接口電路與總線控制電路制作在一塊芯片上的超大規(guī)模集成電路。單片機(jī)使用時(shí),通常是處于測(cè)控系統(tǒng)的核心地位并嵌入其中,所以國(guó)際上通常把單片機(jī)稱為嵌入式控制器(EmbeddedMicrocontrollerUnit,EMCU),或微控制器(MicrocontrollerUnit,MCU)。我國(guó)習(xí)慣于使用“單片機(jī)”這一名稱。1.1.251系列單片機(jī)出現(xiàn)較早也是最成熟的單片機(jī)為Intel公司的MCS-51系列,如Intel8031、Intel8051、Intel8751等型號(hào),該系列單片機(jī)字長(zhǎng)為8位,具有完善的結(jié)構(gòu)和優(yōu)越的性能、較高的性價(jià)比和要求較低的開(kāi)發(fā)環(huán)境。STC系列單片機(jī)為宏晶科技公司生產(chǎn)的增強(qiáng)型51單片機(jī),具有多種型號(hào)。本書(shū)在介紹經(jīng)典MCS-51單片機(jī)的同時(shí),也介紹了STC增強(qiáng)型單片機(jī)。1.1.3單片機(jī)應(yīng)用1.智能儀器儀表2.機(jī)電一體化產(chǎn)品3.實(shí)時(shí)控制4.分布式控制系統(tǒng)5.家居生活1.2單片機(jī)基本組成圖1-1單片機(jī)內(nèi)部組成框圖1.2.1內(nèi)部總線總線(BUS)是傳輸信息的公共導(dǎo)線。在單片機(jī)內(nèi)部使用的總線稱為內(nèi)部總線。地址總線(AddressBus,AB)用于傳輸?shù)刂沸畔?。?shù)據(jù)總線(DataBus,DB)是用于CPU與存儲(chǔ)器之間或CPU與I/O接口之間進(jìn)行數(shù)據(jù)傳送的一組信號(hào)線??刂瓶偩€(ControlBus,CB)是一組控制命令信號(hào)線,是CPU決定對(duì)外部器件作什么操作的命令線。1.2.2中央處理器中央處理器是單片機(jī)的核心,簡(jiǎn)稱CPU,其作用是讀入和分析每條指令,根據(jù)每條指令的功能要求,完成運(yùn)算和控制操作。單片機(jī)應(yīng)用程序經(jīng)編譯器編譯,將生成可執(zhí)行代碼。把PC和單片機(jī)系統(tǒng)連接好后,運(yùn)行程序下載軟件,例如STC單片機(jī)的STC_ISP軟件,就能夠把程序代碼下載到單片機(jī)片內(nèi)ROM中。單片機(jī)在復(fù)位后,CPU自動(dòng)從ROM中逐條取出程序代碼并執(zhí)行。1.2.3~1.2.4程序存儲(chǔ)器存儲(chǔ)器(Memory)用來(lái)存放程序和數(shù)據(jù)。分為只讀存儲(chǔ)器(ROM)和隨機(jī)存儲(chǔ)器(RAM)兩大類。ROM對(duì)數(shù)據(jù)只能讀出不能寫入,斷電后其中的數(shù)據(jù)不會(huì)丟失。因此一般用來(lái)存放程序代碼和常數(shù)。RAM對(duì)數(shù)據(jù)既能讀出也能寫入,斷電后其中的內(nèi)容全部丟失。單片機(jī)中的RAM常用于存放變量和中間計(jì)算結(jié)果。1.2.5I/O接口I/O接口是連接CPU與外設(shè)的中間電路。I/O接口與外部設(shè)備間交換的信號(hào),通常有以下4種類型:
數(shù)字量:二進(jìn)制表示的數(shù)據(jù),如:字節(jié)數(shù)據(jù)、ASCII碼。
模擬量:隨時(shí)間連續(xù)變化的物理量,如:電壓、電流、濕度、壓力、流量。
開(kāi)關(guān)量:二進(jìn)制“0”和“1”描述的狀態(tài),如:開(kāi)/關(guān)、啟/停、通/斷。
脈沖量:上下沿跳變的信號(hào)。MCS-51片內(nèi)集成有P0~P3共4個(gè)并行接I/O口1.2.6~1.2.9串行通信接口,簡(jiǎn)稱串口,其特征是用單根導(dǎo)線傳輸數(shù)據(jù)。MCS-51片內(nèi)集成有一個(gè)全雙工的串行異步通信接口(UART)。定時(shí)器/計(jì)數(shù)器,具有完成硬件定時(shí)、對(duì)外部脈沖信號(hào)進(jìn)行捕捉與計(jì)數(shù)、產(chǎn)生周期脈沖信號(hào)輸出等功能。MCS-51片內(nèi)集成有2個(gè)16位定時(shí)器/計(jì)數(shù)器T0、T1。中斷控制系統(tǒng),實(shí)現(xiàn)單片機(jī)對(duì)異步事件的處理機(jī)制。MCS-51有5個(gè)中斷源。時(shí)鐘發(fā)生器,用來(lái)產(chǎn)生單片機(jī)工作所需要的時(shí)鐘信號(hào)。1.3.1數(shù)制十進(jìn)制數(shù):十進(jìn)制數(shù)的每一位有0~9十種數(shù)碼,基數(shù)為10,高位權(quán)是低位權(quán)的10倍,加減運(yùn)算的法則為“逢十進(jìn)一,借一當(dāng)十”,后綴為D,可省略。二進(jìn)制數(shù):二進(jìn)制數(shù)的每一位有0和1兩種數(shù)碼,基數(shù)為2,高位權(quán)是低位權(quán)的2倍,加減運(yùn)算的法則為“逢二進(jìn)一,借一當(dāng)二”,后綴為B。十六進(jìn)制數(shù):十六進(jìn)制數(shù)的每一位有0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F十六種數(shù)碼,其中A、B、C、D、E、F所代表的數(shù)分別相當(dāng)于十進(jìn)制的10、11、12、13、14、15?;鶖?shù)為16,高位權(quán)是低位權(quán)的16倍,加減運(yùn)算的法則為“逢十六進(jìn)一,借一當(dāng)十六”,后綴為H。1.3.2數(shù)制轉(zhuǎn)換二進(jìn)制數(shù)轉(zhuǎn)換為十六進(jìn)制數(shù)
二進(jìn)制數(shù)轉(zhuǎn)換為十六進(jìn)制數(shù)采用“合四為一法”,即從右向左,每四位二進(jìn)制數(shù)轉(zhuǎn)換為一位十六進(jìn)制數(shù),最高位不足四位用0補(bǔ)齊,就可得到十六進(jìn)制數(shù)。例如,把二進(jìn)制數(shù)1011010110010011111B轉(zhuǎn)換為十六進(jìn)制數(shù): 01011010110010011111B=5AC9FH十六進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)
十六進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)采用“一分為四法”,即從左向右,每一位十六進(jìn)制數(shù)轉(zhuǎn)換為四位二進(jìn)制數(shù)。例如,把十六進(jìn)制數(shù)6C7BH轉(zhuǎn)換為二進(jìn)制數(shù): 6C7BH=0110110001111011B1.3.3無(wú)符號(hào)數(shù)和有符號(hào)數(shù)無(wú)符號(hào)數(shù):如果一個(gè)數(shù)的所有數(shù)位都是數(shù)值位,沒(méi)有符號(hào)位,則該數(shù)就是無(wú)符號(hào)數(shù)。例如,8位無(wú)符號(hào)數(shù)的8個(gè)位都是數(shù)值位,表示的數(shù)的范圍為00000000B~11111111B,即0~255。同樣,16位無(wú)符號(hào)數(shù)的16個(gè)位都是數(shù)值位,所以它可表示的數(shù)的范圍為0000H~FFFFH,即0~65535。有符號(hào)數(shù):有符號(hào)數(shù)就是有符號(hào)位的數(shù)。有符號(hào)數(shù)以其二進(jìn)制數(shù)的最高位作為符號(hào)位,且0表示“﹢”,1表示“﹣”。例如,對(duì)于8位二進(jìn)制數(shù),00000001B表示+1,11111111B表示-1。對(duì)于16位二進(jìn)制數(shù),0001H表示+1,F(xiàn)FFFH表示-1。1.4MCS-51的CPU圖1-2MCS-51CPU的組成1.4.1控制器1.程序計(jì)數(shù)器PC:PC用來(lái)存放下一條指令的地址,具有自動(dòng)加1的功能。應(yīng)用程序通過(guò)編譯軟件編譯后,生成單片機(jī)指令碼,并預(yù)先寫入程序存儲(chǔ)器ROM中。單片機(jī)運(yùn)行后,CPU逐條從ROM中取出指令碼并執(zhí)行。2.指令寄存器IR:CPU從ROM取出指令后,就將指令碼暫存于IR中,等待譯碼。3.指令譯碼器ID:ID是對(duì)指令寄存器IR中的指令進(jìn)行譯碼,將指令碼變?yōu)閳?zhí)行此指令所需要的電信號(hào)。4.?dāng)?shù)據(jù)指針DPTR:指針是存放地址的寄存器。數(shù)據(jù)指針DPTR,用于存放數(shù)據(jù)的地址。5.堆棧指針SP:SP用于指示出堆棧頂部在內(nèi)部RAM塊中的位置。1.4.2運(yùn)算器1.算術(shù)邏輯單元ALU:由加法器和其它邏輯電路等組成,完成數(shù)據(jù)的算術(shù)邏輯運(yùn)算、循環(huán)移位、位操作等,參加運(yùn)算的兩個(gè)操作數(shù),一個(gè)由ACC通過(guò)暫存器2提供,另外一個(gè)由暫存器1提供,運(yùn)算結(jié)果送回ACC,狀態(tài)送PSW。2.累加器ACC:是一個(gè)8位寄存器,簡(jiǎn)記為A,它通過(guò)暫存器與ALU傳送信息,用來(lái)存放一個(gè)操作數(shù)或中間結(jié)果。3.程序狀態(tài)字PSW:也是一個(gè)8位寄存器,用于存儲(chǔ)程序運(yùn)行過(guò)程中的各種狀態(tài)信息。4.其他部件:暫存器用來(lái)存放中間結(jié)果,B寄存器用于乘法和除法時(shí),提供一個(gè)操作數(shù),對(duì)于其他指令,只用作暫存器。5.位處理器
在MCS-51的ALU中,與字節(jié)處理器相對(duì)應(yīng),還特別設(shè)置了一個(gè)結(jié)構(gòu)完整、功能極強(qiáng)的位處理器。MCS-51指令系統(tǒng)中的位處理指令集(17條位操作指令)、存儲(chǔ)器中的位地址空間,以及借用程序狀態(tài)寄存器PSW中的進(jìn)位標(biāo)志位CY作為位操作的累加器,構(gòu)成了MCS-51的為處理器。位處理器可對(duì)直接尋址的位變量進(jìn)行位處理,如置位、清零、取反、測(cè)試轉(zhuǎn)移以及邏輯與、邏輯或等位操作,使用戶在編程時(shí)可以利用指令完成原來(lái)要用硬件電路來(lái)完成的功能,并可方便地設(shè)置標(biāo)志位等,給面向控制的實(shí)際應(yīng)用帶來(lái)了方便。1.5MCS-51存儲(chǔ)器1.MCS-51的RAM分區(qū)1.低128字節(jié)RAM區(qū)低128字節(jié)RAM也稱通用RAM區(qū)。通用RAM區(qū)又可分為工作寄存器組區(qū),位尋址區(qū)和用戶RAM區(qū)。工作寄存器組區(qū):該區(qū)地址為00H~1FH,共32字節(jié),分為4組,每組稱為一個(gè)工作組。每個(gè)工作組都包含8個(gè)8位工作寄存器,編號(hào)都是R0~R7。工作組0是最常用的寄存器組。通過(guò)切換工作組,可以提高程序運(yùn)行效率。C51編程時(shí),一般不需要指定工作組,編譯器會(huì)自動(dòng)為程序和函數(shù)分配它們。位尋址區(qū):該區(qū)地址為20H~2FH,共16個(gè)字節(jié)。這個(gè)區(qū)域的存儲(chǔ)單元既可以按字節(jié)存取,也可以按位存取。用戶RAM區(qū):該區(qū)地址為30H~FFH,用于暫存各種變量和臨時(shí)數(shù)據(jù),也能用作函數(shù)調(diào)用時(shí)所使用的堆棧區(qū)。2.高128字節(jié)RAM區(qū)MCS-52擴(kuò)展有高128字節(jié)RAM,地址范圍是80H~FFH。高128字節(jié)RAM只能間接尋址。C51編程時(shí),存儲(chǔ)于該區(qū)的變量需要使用idata存儲(chǔ)器類型進(jìn)行變量聲明。3.特殊功能寄存器區(qū)特殊功能寄存器SFR是用來(lái)對(duì)片內(nèi)各功能模塊進(jìn)行管理、控制、監(jiān)視的控制寄存器和狀態(tài)寄存器。MCS-52的SFR區(qū)與內(nèi)部高128字節(jié)RAM區(qū)的地址范圍重合,但二者在物理上是獨(dú)立的。2.STC90C516RD+片內(nèi)集成的ROM和RAM地址空間1.6MCS-51單片機(jī)外部引腳在at89x52.h頭文件中,把P0、P1、P2、P3的位寄存器分別定義為P0_0~P0_7、P1_0~P1_7、P2_0~P2_7、P3_0~P3_7,見(jiàn)表1-6。1.7MCS-51最小系統(tǒng)最小系統(tǒng)是單片機(jī)可以運(yùn)行程序的基本電路,包括單片機(jī)、電源、振蕩電路、復(fù)位電路四部分。MCS-51的最小系統(tǒng)如圖1-8所示MCS-51單片機(jī)的時(shí)序MCS-51的時(shí)序單位共有4個(gè),從小到大依次是:節(jié)拍、狀態(tài)、機(jī)器周期和指令周期。晶體振蕩信號(hào)的一個(gè)周期稱為節(jié)拍,用P表示。該周期是單片機(jī)時(shí)鐘脈沖頻率的倒數(shù),是最基本、最小的定時(shí)信號(hào),又稱為振蕩周期或單片機(jī)的時(shí)鐘周期。狀態(tài)周期由振蕩脈沖二分頻后得到,用S表示。這樣,一個(gè)狀態(tài)包含兩個(gè)節(jié)拍,前半周期對(duì)應(yīng)的節(jié)拍叫節(jié)拍1,記作P1;后半周期對(duì)應(yīng)的節(jié)拍叫節(jié)拍2,記作P2,如圖1-12所示。CPU以時(shí)鐘P1、P2為基本節(jié)拍,指揮單片機(jī)的各個(gè)部分協(xié)調(diào)工作。CPU完成一個(gè)基本操作所需要的時(shí)間稱為機(jī)器周期。CPU的基本操作指的是讀取指令、存儲(chǔ)器讀/寫、對(duì)數(shù)據(jù)進(jìn)行處理等操作。MCS-51采用定時(shí)控制方式,具有固定的機(jī)器周期。一個(gè)機(jī)器周期的寬度為6個(gè)狀態(tài),依次記作S1~S6。由于一個(gè)狀態(tài)又包括兩個(gè)節(jié)拍,因此,一個(gè)機(jī)器周期總共有12個(gè)節(jié)拍,分別記作S1P1、S1P2、…、S6P1、S6P2,見(jiàn)圖1-12。由于一個(gè)機(jī)器周期共有12個(gè)振蕩脈沖周期,因此機(jī)器周期就是振蕩脈沖的12分頻。單片機(jī)執(zhí)行一條指令所需要的時(shí)間稱為指令周期。MCS-51大多數(shù)指令的指令周期由一個(gè)機(jī)器周期或兩個(gè)機(jī)器周期組成,只有乘法、除法指令需要4機(jī)器周期。以兩個(gè)機(jī)器周期的指令周期為例,各時(shí)序單位之間的關(guān)系見(jiàn)圖1-12。MCS-51單片機(jī)復(fù)位電路51單片機(jī)的復(fù)位電路如圖1-13、1-14所示第二章C51程序設(shè)計(jì)C51是面向51系列單片機(jī)的C語(yǔ)言。與匯編語(yǔ)言相比,C51有如下優(yōu)點(diǎn):對(duì)單片機(jī)指令系統(tǒng)不要求了解,就可以直接編程操作單片機(jī);寄存器分配、存儲(chǔ)器的尋址以及數(shù)據(jù)類型等細(xì)節(jié)完全由編譯器自動(dòng)管理;有多種結(jié)構(gòu)化控制語(yǔ)句,滿足結(jié)構(gòu)化設(shè)計(jì)要求;庫(kù)中提供許多標(biāo)準(zhǔn)子程序,具有較強(qiáng)的數(shù)據(jù)處理能力,使用方便;具有方便的模塊化編程技術(shù),使已編好的程序很容易移植。2.1C51的基本數(shù)據(jù)類型2.1.1位類型(bit,sbit)位類型是C51擴(kuò)充的數(shù)據(jù)類型,用于訪問(wèn)51單片機(jī)中的可尋址的位單元。C51支持兩種位類型:bit型和sbit型。bit用于在可位尋址的RAM區(qū)定義位變量,位地址范圍是00H~7FH,共128個(gè)可尋址位。例如: bitaflag;
定義了一個(gè)名為aflag的位變量,編譯時(shí)編譯器會(huì)把a(bǔ)flag定位于20H~2FH的RAM區(qū)sbit用于在SFR區(qū)定義位變量,位地址范圍是80H~F7H。SFR區(qū)的字節(jié)地址范圍是80H~FFH,但只有若干個(gè)字節(jié)單元可以位尋址,見(jiàn)圖2-2。例如:字節(jié)地址為80H的SFR單元的位地址為80H~87H。例如: sbitP0_0=0x80;
定義了一個(gè)名為P0_0的sbit型位變量,P0_0的位地址為80H,即sfr中P0寄存器的第0位。使用sbit型位變量能夠方便地對(duì)單片機(jī)并口的某一單個(gè)位進(jìn)行操作。在“at89x52.h”文件中,已經(jīng)包含了對(duì)P0~P3口所有單個(gè)位的定義。C51編程時(shí),若在程序開(kāi)頭使用“#include<atmel\at89x52.h>”語(yǔ)句,就可以直接引用P0_0、P0_1、……、P3_7這些位變量,而不必再進(jìn)行定義。例如,要向P1.1引腳輸出0,可編程如下:#include<atmel\at89x52.h> //#include為C51編譯器的包含命令//其它語(yǔ)句P1_1=0;
2.1.2特殊功能寄存器型(sfr,sfr16)sfr用于定義位于SFR區(qū)的字節(jié)單元,利用它可以訪問(wèn)SFR區(qū)所有的單字節(jié)特殊功能寄存器。sfr16用于定義SFR區(qū)的雙字節(jié)單元,利用它可以訪問(wèn)SFR區(qū)所有兩個(gè)字節(jié)的特殊功能寄存器。由于在“at89x52.h”、“reg52.h”這樣的頭文件中,已經(jīng)包含了51、52子系列單片機(jī)所有sfr型變量的定義,所以,應(yīng)用程序在包含了這樣的頭文件后,就可以直接引用所有sfr型變量的名稱,如P0、T0、SBUF,等等,而不需再去定義它們。例如,要向P0端口輸出75H,可編程如下:#include<atmel\at89x52.h> //#include為C51編譯器的包含命令//其它語(yǔ)句P0=0x75; //向P0端口寫入數(shù)據(jù)75H并輸出到P0.0~P0.72.1.3~2.1.7字符型……指針型字符型數(shù)據(jù)的長(zhǎng)度為一個(gè)字節(jié),用于存放一個(gè)單字節(jié)數(shù)據(jù)。整型數(shù)據(jù)的長(zhǎng)度為兩個(gè)字節(jié),用于存放一個(gè)雙字節(jié)數(shù)據(jù)。長(zhǎng)整型數(shù)據(jù)的長(zhǎng)度為四個(gè)字節(jié),用于存放一個(gè)四字節(jié)數(shù)據(jù)。浮點(diǎn)型數(shù)據(jù)(float)是長(zhǎng)度為四字節(jié)的實(shí)數(shù)指針型(*),與之對(duì)應(yīng)的是指針變量。指針變量中存放的是數(shù)據(jù)的地址。2.2.1數(shù)組與字符串相同類型的數(shù)據(jù)排列形成的有限集合就是數(shù)組。在信息處理時(shí)常常用到以ASCII字符或擴(kuò)展ASCII字符組成的字符串。C語(yǔ)言規(guī)定字符串以'\0'作為結(jié)束符,'\0'的ASCII碼值為00H。數(shù)值、字符串定義舉例inta[10];//定義整型數(shù)組a,所有10個(gè)元素的初值都為0intb[10]={1,2,3,4};//定義整型數(shù)組b,前4個(gè)元素的值為1,2,3,4,余下的為0charc[]={1,2,3,4}; //定義字符型數(shù)組c,賦值了全部元素,數(shù)組長(zhǎng)度可以省略chard[2][5]; //定義2行5列字符型數(shù)組d,所有10個(gè)元素的初值都為0chars[]={'a','b','c','d'}; //定義字符型數(shù)組s,元素為'a','b','c','d'charstr="abcd";//定義字符串str,元素為'a','b','c','d','\0'2.3常量、變量常量:是在程序運(yùn)行時(shí)其值不能改變的量變量:是在程序運(yùn)行時(shí)其值可以改變的量存儲(chǔ)種類:是指變量在程序中的作用域數(shù)據(jù)類型說(shuō)明符用于聲明變量的數(shù)據(jù)類型存儲(chǔ)器類型用于聲明變量的存儲(chǔ)單元應(yīng)定位于單片機(jī)的哪一個(gè)存儲(chǔ)區(qū),如圖2-42.4C51的運(yùn)算符C51支持的算術(shù)運(yùn)算符有+、-、*、/、%、++、--,見(jiàn)圖2-5。C51支持的關(guān)系運(yùn)算符與邏輯運(yùn)算符有>、<、>=、<=、==、!=、||、&&、!。這些運(yùn)算符及示例語(yǔ)句見(jiàn)圖2-6。位操作運(yùn)算符對(duì)操作對(duì)象按位進(jìn)行運(yùn)算,包括位與(&)、位或(|)、位非(~)、位異或(^)、左移(<<)、右移(>>)六種,如圖2-7所示。特殊運(yùn)算符包括各種賦值運(yùn)算符,問(wèn)號(hào)運(yùn)算符,逗號(hào)運(yùn)算符,地址及指針運(yùn)算符等,其類型及示例如圖2-8所示。2.5C51的表達(dá)式和語(yǔ)句1.if語(yǔ)句C51的if語(yǔ)句有if、if-else、if-else-if三種形式。見(jiàn)圖2-92.switch語(yǔ)句switch語(yǔ)句的一般形式和執(zhí)行流程如下圖所示3.while語(yǔ)句一般形式為: while(表達(dá)式){語(yǔ)句體;}do-while語(yǔ)句的形式為: do{
語(yǔ)句體; }while(表達(dá)式);兩種while語(yǔ)句的執(zhí)行流程如下圖4.for語(yǔ)句一般形式為: for(exp1;exp2;exp3) {
語(yǔ)句體; }for語(yǔ)句執(zhí)行流程如下圖5.轉(zhuǎn)移語(yǔ)句包括:(1)goto語(yǔ)句:使程序無(wú)條件轉(zhuǎn)移到標(biāo)號(hào)語(yǔ)句處(2)break語(yǔ)句:作用是跳出switch語(yǔ)句或跳出本層循環(huán),轉(zhuǎn)去執(zhí)行后續(xù)的程序(3)continue語(yǔ)句:作用是結(jié)束本次循環(huán),轉(zhuǎn)入下一次循環(huán)條件的判斷與執(zhí)行(4)return語(yǔ)句:return語(yǔ)句只能出現(xiàn)在被調(diào)函數(shù)中,用于返回主調(diào)函數(shù),其格式是: return(表達(dá)式);
其中,表達(dá)式為函數(shù)的返回值2.6函數(shù)C51函數(shù)定義的形式如下:類型說(shuō)明符函數(shù)名(形式參數(shù)表){
類型說(shuō)明;
語(yǔ)句;}函數(shù)調(diào)用的一般形式為:函數(shù)名(實(shí)際參數(shù)表);函數(shù)的編寫與調(diào)試示例1.編寫程序在KeiluV4中輸入以下程序,保存為類型名為c的文件,如123.c#include<atmel\at89x52.h>intn; //定義int型全程變量n/*延時(shí)函數(shù)*/voiddelay(intn){ inti; for(i=0;i<n;i++);}/*主函數(shù)*/main(){ n=20000; while(1){ //主循環(huán)
P1_1=1; //向P1.1引腳輸出高電平
delay(n); //延時(shí)
P1_1=0; //向P1.1引腳輸出低電平
delay(n); //延時(shí)
delay(n); //延時(shí)
}}2.編譯程序(1)創(chuàng)建項(xiàng)目。在KeiluV4中創(chuàng)建一個(gè)項(xiàng)目,確定項(xiàng)目名稱,如abc(2)為項(xiàng)目選擇單片機(jī)型號(hào)。這里選擇Atmel公司的AT89S52(3)為項(xiàng)目添加C51文件,即把123.c添加到項(xiàng)目abc中(4)設(shè)置編譯后輸出HEX文件(5)按F7編譯程序3.調(diào)試程序在KeiluV4的Debug菜單中,包含了多個(gè)用于調(diào)試源程序的選項(xiàng)。如:Ctrl+F5用于啟動(dòng)和終止調(diào)試,F(xiàn)5用于運(yùn)行程序,F(xiàn)10為單步運(yùn)行程序,Ctrl+F10為運(yùn)行到光標(biāo)所在行,F(xiàn)9為設(shè)置/清除斷點(diǎn)。KeiluV4還具有查看單片機(jī)片內(nèi)各種寄存器、I/O端口狀態(tài)、程序中的各變量值,其邏輯分析器能夠顯示來(lái)自I/O引腳的信號(hào)波形。4.下載到單片機(jī)(1)首先在PC上安裝STC單片機(jī)自動(dòng)編程器的USB驅(qū)動(dòng)程序,如CH340驅(qū)動(dòng)程序。(2)將編程器與PC通過(guò)USB線連接,連接后PC將為該設(shè)備分配一個(gè)虛擬串口。(3)把編程器的GND、RXD、TXD、5V0分別與單片機(jī)芯片的GND、P3.1、P3.0、VCC連接,運(yùn)行STC-ISP程序,選擇單片機(jī)芯片型號(hào)。(4)打開(kāi)程序文件,如abc.HEX。(5)選擇串口,下載。(6)下載成功后,程序即自動(dòng)運(yùn)行。若用杜邦線把P1.1引腳與一只LED連接,可以觀察到LED閃爍第三章單片機(jī)片內(nèi)接口3.1并行接口MCS-51單片機(jī)有P0、P1、P2、P3共4組并行I/O端口,每組端口都是8位準(zhǔn)雙向口,共32根引腳。并口要點(diǎn):并行接口可以同時(shí)輸入/輸出8位數(shù)據(jù)。準(zhǔn)雙向口:CPU在讀取準(zhǔn)雙向口輸入的數(shù)據(jù)前,應(yīng)向該接口輸出高電平。但由于單片機(jī)復(fù)位時(shí)已經(jīng)置P0、P1、P2、P3為高電平,所以把它們作為輸入接口時(shí),CPU就不需要再進(jìn)行輸出高電平的操作了。3.1.1P0口P0口要點(diǎn):P0口主要用作普通I/O接口,在一些應(yīng)用中,需要對(duì)P0口的引腳外接上拉電阻。CPU訪問(wèn)P0的C51例句:bitb;charc;c=P0; //字節(jié)訪問(wèn):CPU讀P0口引腳(P0.7~P0.0)狀態(tài)并存入字符型變量cP0=~P0; //字節(jié)訪問(wèn):CPU讀P0口各引腳鎖存器,取反后輸出到P0.7~P0.0引腳b=P0_0; //位訪問(wèn):CPU讀P0.0引腳狀態(tài)并存入位變量bP0_0=~P0_0; //位訪問(wèn):CPU讀P0.0鎖存器狀態(tài),取反后,輸出到P0.0引腳3.1.2P1口P1口要點(diǎn)P1是一個(gè)8位準(zhǔn)雙向口,它只作通用的I/O口使用,其訪問(wèn)方式與P0口相同訪問(wèn)P1口的例句:charc1,c2;bitb1,b2;c1=P1;//字節(jié)訪問(wèn):讀P1口引腳(P1.7~P1.0)狀態(tài)并送入變量c1c2=~P1;//字節(jié)訪問(wèn):讀P1口引腳(P1.7~P1.0)狀態(tài),位取反后送入變量c2P1=~P1;//字節(jié)訪問(wèn):讀P1口各鎖存器,各位取反后輸出到P1各引腳P1&=0x01;//字節(jié)訪問(wèn):讀P1口各鎖存器,同0x01按位與后輸出到P1各引腳P1_1=~P1_1; //位訪問(wèn):讀P1.1鎖存器,取反后,輸出到P1.1引腳b1=P1_5; //位訪問(wèn):讀P1.5引腳狀態(tài)并送入變量b1b2=~P1_7; //位訪問(wèn):讀P1.7引腳狀態(tài),取反后送入變量b23.1.3P2口P2口要點(diǎn):P2主要作為準(zhǔn)雙向通用I/O口使用3.1.4P3口P3口要點(diǎn):P3的第二功能很重要,但對(duì)于不使用第二功能的引腳,仍可作為準(zhǔn)雙向通用I/O口使用3.1.5并口應(yīng)用舉例【例3-1】用P0.6、P0.7引腳分別控制2只發(fā)光二極管LED1、LED2。控制方式為:LED1點(diǎn)亮、LED2熄滅;延時(shí);LED1熄滅、LED2點(diǎn)亮;如此循環(huán)。【例3-2】
用P1.0、P1.1引腳連接按鈕S1、S2輸入,用P2.7控制一只晶體管的導(dǎo)通與截止,該晶體管驅(qū)動(dòng)一只小型直流繼電器K1。控制要求是:按下S1后,K1通電;按下S2后,K1斷電。C51程序如下。#include<atmel\at89x52.h>main(){ while(1){ bitrun; //定義位變量,指示K1狀態(tài)
if(P1_0==0)run=1; //按下S1,run=1 if(P1_1==0)run=0; //按下S2,run=0 if(run==1)P2_7=0; //run=1,P2.7輸出低電平,K1通電
elseP2_7=1; //run=0,P2.7輸出高電平,K1斷電
}}【例3-3】
用P2口通過(guò)ULN2003驅(qū)動(dòng)芯片控制一只小型步進(jìn)電機(jī)運(yùn)行,且通過(guò)軟件延時(shí)實(shí)現(xiàn)電機(jī)通電相序的變換。試?yán)L出控制電路并編寫C51程序。C51程序如下。#include<atmel\at89x52.h>main(){ while(1){ inti; //定義變量i,用于延時(shí)
for(P2=0x80,P0=~0x80,i=0;i<1000;i++); //A通電,LED顯示,延時(shí)
for(P2=0x40,P0=~0x40,i=0;i<1000;i++); //B通電,LED顯示,延時(shí)
for(P2=0x20,P0=~0x20,i=0;i<1000;i++); //C通電,LED顯示,延時(shí)
for(P2=0x10,P0=~0x10,i=0;i<1000;i++); //D通電,LED顯示,延時(shí)}}3.2中斷3.2.1中斷源2.中斷信號(hào)的產(chǎn)生下面是MCS-52各中斷信號(hào)的產(chǎn)生方式。(1)INT0中斷:若預(yù)置IT0=0,當(dāng)P3.2/引腳出現(xiàn)低電平時(shí)向CPU請(qǐng)求INT0中斷;若預(yù)置IT0=1,當(dāng)P3.2/引腳出現(xiàn)下降沿時(shí)向CPU請(qǐng)求INT0中斷。(2)INT1中斷:若預(yù)置IT1=0,當(dāng)P3.3/引腳出現(xiàn)低電平時(shí)向CPU請(qǐng)求INT1中斷;若預(yù)置IT1=1,當(dāng)P3.3/引腳出現(xiàn)下降沿時(shí)向CPU請(qǐng)求INT1中斷。(3)T0中斷:當(dāng)T0溢出標(biāo)志TF0=1時(shí),向CPU請(qǐng)求T0中斷。(4)T1中斷:當(dāng)T1溢出標(biāo)志TF1=1時(shí),向CPU請(qǐng)求T1中斷。(5)串口中斷:當(dāng)串口發(fā)送中斷標(biāo)志TI=1、或串口接收中斷標(biāo)志RI=1時(shí),向CPU請(qǐng)求串口中斷。(6)T2中斷:當(dāng)T2溢出標(biāo)志TF2=1、或T2外部標(biāo)志EXF2=1時(shí),向CPU請(qǐng)求T2中斷。3.中斷允許的設(shè)置下面是C51設(shè)置開(kāi)中斷和關(guān)中斷的語(yǔ)句。EX0=1;/*開(kāi)INT0中斷 */ EX0=0; /*關(guān)INT0中斷 */EX1=1;/*開(kāi)INT1中斷 */ EX1=0; /*關(guān)INT1中斷 */ET0=1;/*開(kāi)T0中斷 */ ET0=0; /*關(guān)T0中斷 */ET1=1;/*開(kāi)T1中斷 */ ET1=0; /*關(guān)T1中斷 */ES=1;/*開(kāi)串口中斷 */ ES=0; /*關(guān)串口中斷 */ET2=1; /*開(kāi)T2中斷 */ ET0=0; /*關(guān)T2中斷 */EA=1; /*開(kāi)CPU中斷 */ EA=0; /*關(guān)CPU中斷 */3.2.2中斷優(yōu)先級(jí)MCS-52所有的中斷都具有2個(gè)中斷優(yōu)先級(jí):0為低優(yōu)先級(jí),1為高優(yōu)先級(jí)。每個(gè)中斷的優(yōu)先級(jí)均可用軟件設(shè)置。例如:PX0=1;/*設(shè)INT0中斷為高優(yōu)先級(jí)*/PX0=0; /*設(shè)INT0中斷為低優(yōu)先級(jí) */PX1=1;/*設(shè)INT1中斷為高優(yōu)先級(jí)*/ PX1=0; /*設(shè)INT1中斷為低優(yōu)先級(jí) */PT0=1;/*設(shè)T0中斷為高優(yōu)先級(jí)*/PT0=0; /*設(shè)T0中斷為低優(yōu)先級(jí) */PT1=1;/*設(shè)T1中斷為高優(yōu)先級(jí)*/ PT1=0; /*設(shè)T1中斷為低優(yōu)先級(jí) */PT2=1;/*設(shè)T2中斷為高優(yōu)先級(jí)*/PT2=0; /*設(shè)T2中斷為低優(yōu)先級(jí) */PS=1;/*設(shè)串口中斷為高優(yōu)先級(jí)*/ PS=0; /*設(shè)串口中斷為低優(yōu)先級(jí) */中斷查詢次序由高到低排列:INT0,T0,INT1,T1,UART,T23.2.3中斷服務(wù)函數(shù)在C51中,中斷服務(wù)程序是用中斷服務(wù)函數(shù)來(lái)實(shí)現(xiàn)的,它的常用形式如下:void函數(shù)名(void)interrupt中斷號(hào){
語(yǔ)句;}3.2.4中斷應(yīng)用舉例【例3-4】
用單片機(jī)自測(cè)INT0、INT1中斷優(yōu)先順序。方法是把P3.2/與P1.0連接,把P3.3/與P1.1連接,P0與一只七段數(shù)碼管7-Seg連接,主程序使7-Seg顯示字型P,INT0中斷服務(wù)程序使7-Seg顯示字型0,INT1中斷服務(wù)程序使7-Seg顯示字型1。試?yán)L出電路圖、編寫C51程序并進(jìn)行測(cè)試。#include<atmel\at89x52.h>#include<intrins.h>volatileunsignedinti1,i2;//編譯器不對(duì)volatile型變量進(jìn)行優(yōu)化main(){ IT0=IT1=1;//置INT0、INT1下降沿觸發(fā)中斷
EX0=1; //開(kāi)INT0中斷,刪除此句禁止INT0中斷請(qǐng)求
EX1=1; //開(kāi)INT1中斷,刪除此句禁止INT1中斷請(qǐng)求
EA=1; //開(kāi)CPU中斷,刪除此句禁止CPU響應(yīng)中斷
while(1){ //主循環(huán)
unsignedinti; //用于延時(shí)
P0=0x8c; //7-Seg顯示P for(i=0;i<65535;i++);//延時(shí)
P1=0xFC;//同時(shí)拉低P1.0、P1.1,輸出到P3.2、P3.3,以觸發(fā)中斷
_nop_();_nop_();_nop_();_nop_();//維持低電平4個(gè)機(jī)器周期
P1=0xFF; //同時(shí)拉高P1.0,P1.1,輸出到P3.2、P3.3 }}/*INT0中斷服務(wù)程序*/voidINT0_isr()interrupt0 /*INT0中斷號(hào)為0*/{ P0=0xc0; //7-SEG顯示0 for(i2=0;i2<50000;i2++); //延時(shí)}/*INT1中斷服務(wù)程序*/voidINT1_isr()interrupt2 /*INT0中斷號(hào)為2*/{ P0=0xf9; //7-SEG顯示1 for(i1=0;i1<50000;i1++); //延時(shí)}3.3定時(shí)器/計(jì)數(shù)器3.3.1定時(shí)器/計(jì)數(shù)器的結(jié)構(gòu)1.TCON寄存器TCON是定時(shí)器控制寄存器,它的高4位用于控制T0、T1。TCON的格式為:TF1:T1溢出標(biāo)志位。T1被允許計(jì)數(shù)以后,從初值開(kāi)始加1計(jì)數(shù)。當(dāng)最高位產(chǎn)生溢出時(shí)由硬件置位TF1,向CPU請(qǐng)求中斷;TF1一直保持到CPU響應(yīng)中斷時(shí),才由硬件清零(TF1也可由程序查詢清零)。TR1:T1運(yùn)行控制位。該位由軟件置位和清零。當(dāng)TR1=1時(shí),啟動(dòng)T1開(kāi)始計(jì)數(shù);當(dāng)TR1=0時(shí),停止T1計(jì)數(shù)。TF0:T0溢出標(biāo)志位,功能和TF1類似。TR0:T0運(yùn)行控制位,功能和TR1類似。2.TMOD寄存器GATE:門控位。GATE=0時(shí),T0、T1只分別由TR0、TR1來(lái)控制運(yùn)行與停止;GATE=1時(shí),用程序設(shè)置TR0或TR1為1,并且外部中斷引腳(P3.2/INT0引腳與T0配合,P3.3/INT1引腳與T1配合)也為高電平時(shí),才能啟動(dòng)T0或T1計(jì)數(shù)。C/T:定時(shí)/計(jì)數(shù)模式選擇位。C/T=0為定時(shí)模式,即定時(shí)器對(duì)CPU內(nèi)部的機(jī)器周期脈沖信號(hào)計(jì)數(shù);C/=1為計(jì)數(shù)模式,即定時(shí)器對(duì)外部引腳(P3.4/T0、P3.5/T1)脈沖信號(hào)計(jì)數(shù)。M1、M0:工作方式設(shè)置位。M1M0=00:方式0,13位定時(shí)器/計(jì)數(shù)器;M1M0=01:方式1,16位定時(shí)器/計(jì)數(shù)器;M1M0=10:方式2,8位自動(dòng)重裝定時(shí)器/計(jì)數(shù)器;M1M0=11:方式3,T0分成兩個(gè)8位的定時(shí)器/計(jì)數(shù)器。3.3.2定時(shí)器/計(jì)數(shù)器的工作方式1.方式1方式1為16位計(jì)數(shù)方式。T0的16位計(jì)數(shù)器由TL0和TH0組成。TL0溢出時(shí),向TH0進(jìn)位,TH0溢出時(shí),置位TF0標(biāo)志,向CPU發(fā)出中斷請(qǐng)求。圖3-16是T0工作在方式1的邏輯結(jié)構(gòu)圖,T1與之類似2.方式2方式2為8位自動(dòng)重裝計(jì)數(shù)方式,各控制信號(hào)的作用與方式1相同。方式2下,TL0作8位計(jì)數(shù)器使用,TH0作為8位常數(shù)緩沖器,保存計(jì)數(shù)初值。當(dāng)TL0計(jì)數(shù)產(chǎn)生溢出時(shí),在把TF0置1的同時(shí),將保存在TH0中的計(jì)數(shù)初值自動(dòng)裝入TL0,使TL0再次從該初值加1計(jì)數(shù),如此循環(huán)。由于是8位的計(jì)數(shù)器,所以計(jì)數(shù)值達(dá)到28=256就產(chǎn)生溢出。圖3-17是T0工作在方式2的邏輯結(jié)構(gòu)圖,T1與之類似。3.方式3方式3只適用于T0。此時(shí),T0被分為兩個(gè)獨(dú)立的8位計(jì)數(shù)器TL0和TH0。其中,TL0占用T0的控制位、引腳和中斷源。除計(jì)數(shù)位數(shù)不同于方式1外,其功能和操作與方式1完全相同,可定時(shí)也可計(jì)數(shù)。TH0占用T1的控制位TF1和TR1,同時(shí)還占用了T1的中斷源,其啟/停僅受TR1控制。TH0只能用作8位定時(shí)器,不能對(duì)外部脈沖計(jì)數(shù)。在這種情況下,T1一般用作串口波特率發(fā)生器。3.3.3T0、T1應(yīng)用舉例【例3-5】
設(shè)單片機(jī)晶振頻率為12MHz,編寫C51程序,用T0定時(shí)中斷使P1.0引腳輸出1kHz的脈沖方波,再用T1定時(shí)中斷使P1.1引腳輸出10kHz的脈沖方波。1.定時(shí)器計(jì)數(shù)初值計(jì)算T0、T1用作定時(shí)器時(shí),計(jì)數(shù)脈沖頻率為fosc/12。設(shè)定時(shí)器的溢出頻率為f,則定時(shí)器的計(jì)數(shù)次數(shù)n=fosc/12/f。定時(shí)器的計(jì)數(shù)初值就等于256(對(duì)于8位計(jì)數(shù)器)或65536(對(duì)于16位計(jì)數(shù))減去分頻數(shù),即:2.程序框圖3.程序#include<atmel\at89x52.h>#defineFOSC12000000L //晶體振蕩頻率#defineN_T20KHZ(256-FOSC/12/20000) //T1初值#defineN_TH2KHZ(65536-FOSC/12/2000)/256 //TH0初值#defineN_TL2KHZ(65536-FOSC/12/2000)%256 //TL0初值main(){ TMOD=0x01; //T0方式1:□□□□□□□■
TMOD|=0x20; //T1方式2:□□■□□□□□
TH1=N_T20KHZ; //裝T1計(jì)數(shù)初值
EA=ET0=ET1=1; //開(kāi)CPU、T0、T1中斷TR0=TR1=1; //啟動(dòng)定時(shí)器T0、T1 while(1){ }}voidt0_isr()interrupt1{ TH0=N_TH2KHZ; //裝計(jì)數(shù)初值高8位 TL0=N_TL2KHZ; //裝計(jì)數(shù)初值低8位 P1_0=~P1_0; //P1.0取反后輸出}voidt1_isr()interrupt3{ P1_1=~P1_1; //P1.1取反后輸出}【例3-6】
設(shè)單片機(jī)晶振頻率為12MHz,用T0定時(shí)產(chǎn)生1秒鐘的定時(shí)間隔,并通過(guò)P0控制一只共陽(yáng)極七段數(shù)碼管,顯示秒鐘的個(gè)位數(shù)。試?yán)L出硬件電路并編寫C51程序。1.硬件電路2.程序設(shè)計(jì)#include<atmel\at89x52.h>#defineFOSC12000000L //晶體振蕩頻率#defineN_TH50ms(65536-FOSC/12*50/1000)/256 //50ms(20Hz)TH0初值#defineN_TL50ms(65536-FOSC/12*50/1000)%256 //50ms(20Hz)TL0初值#defineN_1sec1000/50 //1secT0中斷次數(shù)main(){ TMOD=0x01; //T0方式1:□□□□□□□■ TR0=1; //啟動(dòng)定時(shí)器
EA=ET0=1; //開(kāi)CPU、T0中斷
while(1){}}codeunsignedcharSegDat[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9voidt0_isr()interrupt1{ staticintn_t0,n_sec; TH0=N_TH50ms; //裝計(jì)數(shù)初值高8位
TL0=N_TL50ms; //裝計(jì)數(shù)初值低8位
if(++n_t0==N_1sec){ n_t0=0; P0=SegDat[n_sec]; //P0輸出,顯示
if(++n_sec==10)n_sec=0; }}【例3-7】用單片機(jī)的P3.4/T0引腳對(duì)一只NPN型光電開(kāi)關(guān)的輸出脈沖進(jìn)行計(jì)數(shù),并通過(guò)P0控制一只七段數(shù)碼管,顯示脈沖數(shù)的個(gè)位數(shù)。試?yán)L出硬件電路并編寫C51程序。1.光電開(kāi)關(guān)工作原理2.硬件電路3.程序設(shè)計(jì)#include<atmel\at89x52.h>codeunsignedcharSegDat[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9main(){ TMOD=0x05; //T0方式1,對(duì)外部脈沖計(jì)數(shù):□□□□□■□■ TR0=1; //啟動(dòng)T0 while(1){unsignedinti;i=TH0*256+TL0;//讀取TH0、TL0并合成為無(wú)符號(hào)16位整數(shù)
i%=10; //i對(duì)10取余數(shù),得到i的個(gè)位數(shù)
P0=SegDat[i]; //P0輸出,顯示i的字型
for(i=0;i<30000;i++);//為顯示延時(shí)一段時(shí)間
/*如果沒(méi)有光電開(kāi)關(guān),可以把P1.0與P3.4連接,并加入以下語(yǔ)句
P1_0=0; for(i=0;i<10;i++); P1_0=1; */ }}【例3-8】
用單片機(jī)的P2.7引腳通過(guò)ULN2003的一個(gè)通道控制一只直流電機(jī)的運(yùn)行,并用T0定時(shí)器使P2.7引腳輸出周期為2ms的PWM波形,設(shè)每個(gè)波形的前1.5ms為高電平,后0.5ms為低電平。試設(shè)計(jì)硬件電路并編寫C51程序。1.直流電機(jī)的驅(qū)動(dòng)2.控制電路3.程序設(shè)計(jì)#include<atmel\at89x52.h>#defineFOSC12000000L //晶體振蕩頻率#defineN_T0d1ms(256-FOSC/12/10000) //0.1ms(10000Hz)TH0初值main(){ TMOD=0x02; //T0方式2:□□□□□□■□ TH0=N_T0d1ms; //裝T0計(jì)數(shù)初值預(yù)存于TH0 TR0=1; //啟動(dòng)T0 EA=ET0=1; //開(kāi)CPU、T0中斷
while(1){ }}voidt0_isr()interrupt1 //T0中斷號(hào)=1{ staticcharn_t0; //T0中斷次數(shù)
P2_7=(n_t0<15)?1:0; //向P2.7輸出PWM波形
if(++n_t0==20)n_t0=0; //PWM周期=20次×0.1ms=2ms}3.4串行接口3.4.1串行通信基本概念1.并行通信與串行通信2.異步通信方式3.異步通信幀格式異步通信的字符幀由起始位、數(shù)據(jù)位、校驗(yàn)位和停止位組成,見(jiàn)圖3-29。起始位:位于字符幀開(kāi)頭,只占一位,為邏輯0低電平,用于向接收設(shè)備表示發(fā)送端開(kāi)始發(fā)送一幀信息。數(shù)據(jù)位:緊跟起始位之后,根據(jù)通信約定可取5~8位,低位在前、高位在后。奇偶校驗(yàn)位:位于數(shù)據(jù)位之后,用于數(shù)據(jù)位的奇偶校驗(yàn)。奇偶校驗(yàn)有奇校驗(yàn)、偶校驗(yàn)和無(wú)校驗(yàn)三種方式,若選擇無(wú)校驗(yàn)方式,則通信時(shí)不發(fā)送該位。停止位:位于字符幀的最后,為邏輯1的高電平,根據(jù)通信約定可取1位、1.5位或2位。用于向接收端表示一幀字符信息已經(jīng)發(fā)送完,也為發(fā)送下一幀做準(zhǔn)備。從起始位開(kāi)始到停止位結(jié)束的全部?jī)?nèi)容稱之為一幀。兩相鄰幀之間可以沒(méi)有空閑位,也可以有若干空閑位3.4.251單片機(jī)串口結(jié)構(gòu)及串口寄存器1.SBUF寄存器SBUF是串口寄存器,包括發(fā)送寄存器和接收寄存器。它們有相同名字和地址,但不會(huì)出現(xiàn)沖突,因?yàn)樗鼈儺?dāng)中一個(gè)只能被CPU讀出數(shù)據(jù),另一個(gè)只能被CPU寫入數(shù)據(jù)。當(dāng)CPU向SBUF寫入時(shí),數(shù)據(jù)進(jìn)入發(fā)送SBUF,同時(shí)啟動(dòng)串行發(fā)送;當(dāng)CPU讀SBUF時(shí),實(shí)際上是讀接收SBUF中的數(shù)據(jù)2.SCON寄存器串口控制寄存器SCON的格式為:SM2:多機(jī)通信控制位。在方式0時(shí),SM2應(yīng)為0。在方式1中,如果SM2位為1,則只有接收到有效停止位時(shí),RI才置1。在方式2或方式3時(shí),當(dāng)SM2=1且接收到的第9位數(shù)據(jù)RB8=1時(shí),置位RI;否則不置位RIREN:接收允許控制位。由軟件置位以允許串口接收,又由軟件清0來(lái)禁止串口接收。TB8:是要發(fā)送數(shù)據(jù)的第9位。在方式2或方式3中,TB8為要發(fā)送的第9位數(shù)據(jù),根據(jù)需要由軟件置1或清0。例如,可以約定TB8作為奇偶校驗(yàn)位,或者在多機(jī)通信中用它作為區(qū)別地址幀或數(shù)據(jù)幀的標(biāo)志位。RB8:接收到的數(shù)據(jù)的第9位。在方式0中不使用RB8。在方式1中,若SM2=0,RB8為接收到的停止位。在方式2或方式3中,RB8為接收到的第9位數(shù)據(jù)。TI:發(fā)送中斷標(biāo)志。在方式0中,當(dāng)?shù)?位發(fā)送結(jié)束時(shí),由硬件置位。在其它方式的發(fā)送停止位前,由硬件置位。TI置位既表示一幀信息發(fā)送結(jié)束,同時(shí)也請(qǐng)求串口中斷,可根據(jù)需要,用程序查詢的方式獲得數(shù)據(jù)已經(jīng)發(fā)送完畢的信息,或者用中斷的方式來(lái)發(fā)送下一個(gè)數(shù)據(jù)。TI必須用軟件清0。RI:接收中斷標(biāo)志位。在方式0,當(dāng)接收完第8位數(shù)據(jù)后,由硬件置位。在其它方式中,在接收到停止位的中間時(shí)刻由硬件置位(例外情況見(jiàn)于SM2的說(shuō)明)。RI置位表示一幀數(shù)據(jù)接收完畢,可以用程序查詢的方式獲知或者用中斷的辦法獲知。RI必須用軟件清0。3.PCON寄存器中的SMOD位SMOD是電源控制寄存器PCON中的最高位,用于設(shè)置串口方式1、方式2、方式3的波特率是否加倍:SMOD=1,波特率加倍;SMOD=0,波特率不加倍。3.4.3串口工作方式方式0當(dāng)SM0=SM1=0時(shí),串口工作于方式0,為移位寄存器輸入/輸出方式。這種方式常用于外接移位寄存器擴(kuò)展并行I/O接口。方式1當(dāng)SM0=0、SM1=1時(shí),串口工作于方式1,為波特率可變的10位異步串行通信方式。一幀信息包括1個(gè)起始位,8個(gè)數(shù)據(jù)位和1個(gè)停止位。通常單片機(jī)與單片機(jī)串口通信,單片機(jī)與計(jì)算機(jī)串口通信,都選擇方式1。方式2當(dāng)SM0=1、SM1=0時(shí),串口工作于方式2,為固定波特率的11位UART方式。它比方式1增加了一位可程控為1或0的第9位數(shù)據(jù)。方式3當(dāng)SM0=SM1=1時(shí),串口工作于方式3,為波特率可變的11位UART方式。除波特率外,其余與方式2相同。3.4.4串口接收/發(fā)送編程舉例【例3-9】
在直流電機(jī)的PWM控制中,用單片機(jī)的串口接收PWM波形中高電平的時(shí)間值,以改變PWM脈沖的占空比。已知單片機(jī)晶振頻率為11.0592MHz,串口通信參數(shù)為:波特率=9600,數(shù)據(jù)位=8,無(wú)奇偶校驗(yàn),停止位=1。試編寫C51程序。1.PWM調(diào)速的實(shí)現(xiàn)例3-8的程序設(shè)計(jì)實(shí)現(xiàn)了用T0定時(shí)中斷輸出PWM波形,但要實(shí)現(xiàn)電機(jī)的速度調(diào)節(jié),還需要適時(shí)地改變PWM波形中高電平或低電平所占的時(shí)間值。本例中單片機(jī)通過(guò)串口接收的方法獲得PWM波形中高電平所占的時(shí)間值,并把它存儲(chǔ)于全程變量PWM_ON中,以供T0中斷服務(wù)函數(shù)使用。2.程序設(shè)計(jì)#include<atmel\at89x52.h>#defineFOSC11059200L //晶體振蕩頻率#defineN_T0d1ms(256-FOSC/12/10000)//0.1ms(10000Hz)TH0初值charPWN_ON=10; //全程變量,PWM高電平時(shí)間值main(){ /*設(shè)置T0方式2,0.1ms定時(shí)*/ TMOD=0x02; //T0方式2:□□□□□□■□ TH0=N_T0d1ms; //裝T0計(jì)數(shù)初值預(yù)存于TH0 TR0=1; //啟動(dòng)T0 EA=ET0=1; //開(kāi)CPU、T0中斷/*設(shè)置串口:波特率=9600,數(shù)據(jù)位=8,無(wú)奇偶校驗(yàn),停止位=1*/ TMOD|=0x20; //T1方式2,8位自動(dòng)重裝□□■□□□□□ TH1=0xFD; //9600bps,T1定時(shí)初值 SM0=0,SM1=1; //設(shè)定串口方式1:□■ REN=1; //允許串口接收 TR1=1; //啟動(dòng)定時(shí)器1 while(1){ charc; /*串口接收一個(gè)字符*/ while(RI==0); //等待串口接收完成 RI=0; //RI清零 c=SBUF; //從串口讀取一個(gè)字符 if(c>0&&c<20)PWN_ON=c;//PWN_ON裝入新值 SBUF=PWN_ON; //串口發(fā)送PWN_ON的值 }}voidt0_isr()interrupt1 //T0中斷號(hào)=1{ staticcharn_t0; //T0中斷次數(shù) P2_7=(n_t0<PWN_ON)?1:0; //向P2.7輸出PWM波形 if(++n_t0==20)n_t0=0; //PWM周期=20次×0.1ms=2ms}【例3-10】在對(duì)光電開(kāi)關(guān)輸出脈沖計(jì)數(shù)的應(yīng)用中,利用單片機(jī)串口發(fā)送脈沖計(jì)數(shù)值。試用串口接收查詢和串口接收中斷兩種方式實(shí)現(xiàn):當(dāng)單片機(jī)串口接收到字符‘P’時(shí),就通過(guò)串口發(fā)送T0的16位計(jì)數(shù)值。已知單片機(jī)晶振頻率為11.0592MHz,串口通信參數(shù)為:波特率=9600,數(shù)據(jù)位=8,無(wú)奇偶校驗(yàn),停止位=1。1.串口接收查詢編程所謂串口接收查詢就是在程序中不斷查詢串口的RI標(biāo)志,當(dāng)串口接收了一個(gè)字符后,RI被硬件置位,此后CPU從串口讀取字符并將RI清零。在通過(guò)串口發(fā)送一個(gè)字符后,也需要不斷查詢TI標(biāo)志,待字符發(fā)送完成、TI被硬件置位后,將TI清零。程序設(shè)計(jì)#include<atmel\at89x52.h>main(){ TMOD=0x05; //T0方式1,對(duì)外部脈沖計(jì)數(shù):□□□□□■□■ TR0=1; //啟動(dòng)T0 /*設(shè)置串口:波特率=9600,數(shù)據(jù)位=8,無(wú)奇偶校驗(yàn),停止位=1*/ TMOD|=0x20; //T1方式2,8位自動(dòng)重裝:□□■□□□□□ TH1=0xFD; //9600bps,T1定時(shí)初值 TR1=1; //啟動(dòng)定時(shí)器1 SM0=0,SM1=1; //設(shè)定串口方式1:□■ REN=1; //允許串口接收 while(1){ //主循環(huán) charc; /*串口接收一個(gè)字符*/ while(RI==0); //等待串口接收完成 RI=0; //RI清零 c=SBUF; //從串口讀取一個(gè)字符 if(c!='P')continue;//接收的不是字符P,跳到 //循環(huán)開(kāi)頭 /*接收到字符P,串口發(fā)送TH0、TL0*/ SBUF=TH0; //通過(guò)串口發(fā)送TH0 while(TI==0); //等待串口發(fā)送完成 TI=0; //TI清零 SBUF=TL0; //通過(guò)串口發(fā)送TL0 while(TI==0); //等待串口發(fā)送完成 TI=0; //TI清零 }}2.串口接收中斷編程在設(shè)置允許串口中斷后,單片機(jī)串口在接收到一個(gè)字符或發(fā)送完一個(gè)字符后都會(huì)請(qǐng)求串口中斷。所以在串口中斷服務(wù)函數(shù)中要進(jìn)行判斷:如果RI等于1,則是串口接收中斷;如果TI等于1,則是串口發(fā)送中斷。在串口接收中斷中,如果檢測(cè)到串口接收了字符'P',就通過(guò)串口發(fā)送TH0、TL0的存儲(chǔ)值。程序設(shè)計(jì)#include<atmel\at89x52.h>main(){TMOD=0x05; //T0方式1,對(duì)外部脈沖計(jì)數(shù):□□□□□■□■ TR0=1; //啟動(dòng)T0 /*設(shè)置串口:波特率=9600,數(shù)據(jù)位=8,無(wú)奇偶校驗(yàn),停止位=1*/ TMOD|=0x20; //T1方式2,8位自動(dòng)重裝□□■□□□□□ TH1=0xFD; //9600bps,T1定時(shí)初值 TR1=1; //啟動(dòng)定時(shí)器1 SM0=0,SM1=1; //設(shè)定串口方式1:□■ REN=1; //允許串口接收 EA=ES=1; //開(kāi)CPU、串口中斷 while(1){ //主循環(huán) }}voiduart_isr()interrupt4/*串口中斷序號(hào)為4*/{ if(RI){ /*如果是接收中斷*/ RI=0;/*RI清零*/ if(SBUF=='P'){/*接收到字符P,串口發(fā)送TH0、 TL0*/ SBUF=TH0; //通過(guò)串口發(fā)送TH0 while(TI==0); //等待串口發(fā)送完成 TI=0; //TI清零 SBUF=TL0; //通過(guò)串口發(fā)送TL0 while(TI==0); //等待串口發(fā)送完成 TI=0; //TI清零 } } if(TI)TI=0;/*如果是發(fā)送中斷,TI清零*/}單片機(jī)接口與應(yīng)用第四章
數(shù)字量控制應(yīng)用第五章
擴(kuò)展接口第六章片內(nèi)增強(qiáng)功能4.1單相電機(jī)正反轉(zhuǎn)控制4.1.1單相電機(jī)簡(jiǎn)介單相電機(jī)一般是指用單相交流電源(AC220V)供電的小功率單相異步電動(dòng)機(jī)。單相異步電動(dòng)機(jī)通常在定子上有兩相繞組,轉(zhuǎn)子是普通鼠籠型的。兩相繞組在定子上的分布以及供電情況的不同,可以產(chǎn)生不同的起動(dòng)特性和運(yùn)行特性。圖4-1是帶正反轉(zhuǎn)倒順開(kāi)關(guān)的接線圖。圖中電機(jī)的A繞組與B繞組是線徑與線圈數(shù)完全一致。手動(dòng)開(kāi)關(guān)S的上通和下通就能實(shí)現(xiàn)電機(jī)的正轉(zhuǎn)和反轉(zhuǎn)。4.1.2硬件電路在控制單相電機(jī)正反轉(zhuǎn)時(shí),需要自動(dòng)地控制圖4-1中開(kāi)關(guān)S的倒順。單片機(jī)控制單相電機(jī)的硬件電路如圖4-2所示。S1、S2、S3分別為正轉(zhuǎn)按鈕、反轉(zhuǎn)和停止按鈕;P0.6~P0.7控制2只LED,用來(lái)指示電機(jī)的正轉(zhuǎn)和反轉(zhuǎn)。P2口經(jīng)ULN2003控制2只繼電器K1、K2,用于實(shí)現(xiàn)單相電機(jī)正反轉(zhuǎn)。當(dāng)K1通電、K2斷電時(shí),電機(jī)M的右側(cè)接線端子接交流電源;當(dāng)K1斷電、K2通電時(shí),電機(jī)M的左側(cè)接線端子接交流電源;當(dāng)K1、K2都斷電時(shí),電機(jī)M停止。4.1.3程序設(shè)計(jì)#include<Atmel\AT89X52.h>charMotorState;main(){P2_7=P2_6=0;//電機(jī)停止MotorState=0; //電機(jī)停止標(biāo)志while(1){//主循環(huán)
if(P1_0==0)MotorState=1;//按下S1, //正轉(zhuǎn)
if(P1_1==0)MotorState=-1;//按下S2, //反轉(zhuǎn)
if(P1_2==0)MotorState=0;//按下S3, //停止
/*根據(jù)標(biāo)志控制輸出*/ switch(MotorState){ case1:P2_7=1;P2_1=6; //電機(jī)正轉(zhuǎn)
P0_6=0;P0_7=1; //LED顯示輸出
break; case-1:P2_7=0;P2_6=1; //電機(jī)反轉(zhuǎn)
P0_6=1;P0_7=0; //LED顯示輸出
break; case0:P2_7=0;P2_6=0; //電機(jī)停止
P0_6=1;P0_7=1; //LED顯示輸出
break; default: break; } }}4.2電磁閥的單片機(jī)控制4.2.1電磁閥簡(jiǎn)介電磁閥通過(guò)線圈通電產(chǎn)生的磁力吸引閥芯移動(dòng)來(lái)開(kāi)啟/關(guān)閉管路,從而控制流體的流通與斷開(kāi)。直動(dòng)式電磁閥的工作原理如圖4-4所示4.2.2液體攪拌機(jī)控制要求攪拌機(jī)的控制要求為:電磁閥YV1開(kāi)啟,將未攪拌的液體注入容器;當(dāng)液體注滿后,液位傳感器SQ1動(dòng)作,這時(shí)YV1關(guān)閉,攪拌機(jī)開(kāi)始攪拌;攪拌的方法是:使單相電機(jī)每10秒交替正轉(zhuǎn)和反轉(zhuǎn);10分鐘后,攪拌完成,YV2開(kāi)啟,排放液體;當(dāng)液位下降到液位傳感器SQ2動(dòng)作時(shí),YV2關(guān)閉,一個(gè)攪拌過(guò)程結(jié)束4.2.3硬件電路圖中,S1、S2分別為啟動(dòng)按鈕和停止按鈕;SQ1、SQ2為兩個(gè)液位傳感器的觸點(diǎn)。P0.4~P0.7控制4只LED,以指示機(jī)器工作狀態(tài)。P2口經(jīng)ULN2003控制4只繼電器,其中K1、K2用于實(shí)現(xiàn)單相電機(jī)正反轉(zhuǎn),K3、K4用于控制電磁閥YV1、YV2的開(kāi)啟和關(guān)閉4.2.4程序設(shè)計(jì)#include<Atmel\AT89X52.h>volatilecharRunState=0; //運(yùn)行狀態(tài)=停機(jī)main(){ TMOD|=0x01;//T0方式1 EA=ET0=TR0=1; //開(kāi)放CPU中斷?開(kāi)放T0中斷?啟動(dòng)T0 while(1){//主循環(huán)
switch(RunState){ case1://注入
P2_2=1;P0=0xEF;/*YV1開(kāi)啟,LED顯示
輸出*/
if(!P1_2){ //如果SQ1動(dòng)作
P2_2=0; //YV1關(guān)閉
RunState=2; //進(jìn)行狀態(tài)轉(zhuǎn)換
} break; case2://攪拌
P0=0xDF;/*LED顯示輸出,攪拌控制由T0定
時(shí)中斷執(zhí)行*/
break; case3://排放
P2_1=1;P0=0xBF;//YV2開(kāi)啟,LED顯示輸出
if(!P1_3){ //如果SQ2動(dòng)作
P2_1=0; //YV2關(guān)閉
RunState=0; //進(jìn)行狀態(tài)轉(zhuǎn)換
} break; case0://停機(jī)
P2=0;P0=0x7F;/*電機(jī)停止,閥門關(guān)閉;LED顯
示輸出*/ if(P1_2&&P1_3&&!P1_0)RunState=1;/*SQ1、 SQ2常態(tài)?按下S1*/ break; default:break; } if(!P1_1)RunState=0; /*按下S2,置停機(jī)狀態(tài)*/ }}voidT0isr()interrupt1{ staticunsignedintn50ms=0; TH0=(65536-46080)/256;//分頻數(shù)=Fosc/12*50/1000=46080 TL0=(65536-46080)%256; if(RunState==2){ //攪拌
if(((n50ms/200)&0x0001)==0){/*10秒的偶數(shù)倍*/ P2_7=1;P2_6=0; //電機(jī)正轉(zhuǎn)
} else{/*10秒的奇數(shù)倍*/ P2_7=0;P2_6=1; //電機(jī)反轉(zhuǎn)
} if(++n50ms>=12000){ //10分鐘到
P2_7=0;P2_6=0; //停止攪拌
n50ms=0; RunState=3;//置運(yùn)行狀態(tài)=排放
} }}4.3步進(jìn)電機(jī)轉(zhuǎn)速控制4.3.1硬件電路圖4-8為單片機(jī)控制微型步進(jìn)電機(jī)的硬件電路圖。按鈕S1、S2、S3分別為電機(jī)正轉(zhuǎn)、反轉(zhuǎn)、停止按鈕,S4為電機(jī)運(yùn)行頻率設(shè)定按鈕,每按一次S4,會(huì)改變一次電機(jī)的運(yùn)行頻率。P0.7~P0.4控制4只LED,用于顯示步進(jìn)電機(jī)各繞組的通電狀態(tài)。這里把具有中間抽頭的兩相電機(jī)按四相電機(jī)處理。4.3.2程序設(shè)計(jì)#include<intrins.h>#defineFOSC11059200LcharMotorState;codeunsignedintfreqs[]={100,200,300,500,800,1000,1500,2000};//T2計(jì)數(shù)數(shù)組voidmain(void){ C_T2=0;//T2asTimer T2MOD=0x00;//T2OE=0,CDEN=0 EA=ET2=TR2=1; while(1){//主循環(huán)
unsignedchari; unsignedintn; if(!P1_0)MotorState=1; //按下S1,正轉(zhuǎn)
if(!P1_1)MotorState=-1; //按下S2,反轉(zhuǎn)
if(!P1_2)MotorState=0; //按下S3,停止
if(!P1_3){ //按下S4 for(n=0;n<5000;n++); //延時(shí),避開(kāi)按鍵抖動(dòng)
if(!P1_3){ while(!P1_3);//等待S4彈起
/*電機(jī)頻率調(diào)整*/ if(i>7)i=0; TR2=0; //停止T2 n=FOSC/12/freqs[i++]; //計(jì)算分頻數(shù)
RCAP2H=TH2=(65536-n)/256;//T2定時(shí)初值,自動(dòng)重裝
RCAP2L=TL2=(65536-n)%256; TR2=1; //啟動(dòng)t2 } } }}voidt2_isr()interrupt5{ staticunsignedcharc=0xcc; //0xcc為P2輸出初值
TF2=0; //TF2清零
if(MotorState==1)c=_cror_(c,1); //循環(huán)右移1位
elseif(MotorState==-1)c=_crol_(c,1); //循環(huán)左移1位
P2=c&0xF0; //輸出相序:P2.7~P2.4=A~D,1=ON P0=~(c&0xF0); //LED輸出,0=ON}4.4直流電機(jī)控制4.4.1直流電機(jī)PWM調(diào)速在一個(gè)PWM周期(TP)中,用一部分時(shí)間(TH)把電源電壓全部加在電樞兩端,另一部分時(shí)間(TL)把電源電壓關(guān)斷。4.4.2硬件電路電路說(shuō)明:按鈕S1、S2、S3分別為電機(jī)正轉(zhuǎn)、反轉(zhuǎn)、停止按鈕,S4為PWM設(shè)定按鈕,每按一次S4,會(huì)改變一次PWM_ON的數(shù)值,
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 突發(fā)性耳聾診治現(xiàn)狀與建議
- 個(gè)人借款合同協(xié)議模板
- 普洱茶銷售合同模板
- 工程合作項(xiàng)目協(xié)議范例
- 分期付款合同2024年
- 專利申請(qǐng)委托協(xié)議
- 新版簡(jiǎn)易房屋租賃合同
- 快遞承運(yùn)合作協(xié)議范本
- 技術(shù)合同-資源授權(quán)協(xié)議
- 簡(jiǎn)單版房屋出租合同范本
- 婦科護(hù)理進(jìn)修匯報(bào)
- 新團(tuán)員團(tuán)課培訓(xùn)課件
- 學(xué)?;@球教練外聘協(xié)議書(shū)
- 工作流程改進(jìn)匯報(bào)
- 浙教版六年級(jí)勞動(dòng)項(xiàng)目三-任務(wù)二《創(chuàng)意班規(guī)巧設(shè)計(jì)》課件
- 高思學(xué)校競(jìng)賽數(shù)學(xué)課本五年級(jí)
- 油田開(kāi)發(fā)方案及調(diào)整方案經(jīng)濟(jì)評(píng)價(jià)技術(shù)要求
- 康復(fù)科常見(jiàn)疾病護(hù)理常規(guī)2023版
- 英漢互譯單詞練習(xí)打印紙
- 2021年國(guó)家公務(wù)員考試《申論》真題(副省級(jí))及參考答案(兩套答案)
- GA/T 2012-2023竊照專用器材鑒定技術(shù)規(guī)范
評(píng)論
0/150
提交評(píng)論