《8051單片機(jī)原理及應(yīng)用》 課件 第九章人機(jī)接口開發(fā)_第1頁
《8051單片機(jī)原理及應(yīng)用》 課件 第九章人機(jī)接口開發(fā)_第2頁
《8051單片機(jī)原理及應(yīng)用》 課件 第九章人機(jī)接口開發(fā)_第3頁
《8051單片機(jī)原理及應(yīng)用》 課件 第九章人機(jī)接口開發(fā)_第4頁
《8051單片機(jī)原理及應(yīng)用》 課件 第九章人機(jī)接口開發(fā)_第5頁
已閱讀5頁,還剩62頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

網(wǎng)絡(luò)空間安全學(xué)院網(wǎng)絡(luò)安全基礎(chǔ)技術(shù)應(yīng)用第九章人機(jī)接口開發(fā)目錄CONTENT9.1.STN-LCD液晶顯示開發(fā)9.2.狀態(tài)機(jī)設(shè)計(jì)9.3.總線擴(kuò)展復(fù)用設(shè)計(jì)9.4.人機(jī)接口綜合練習(xí)9.1.STN-LCD液晶顯示開發(fā)液晶顯示終端是單片機(jī)應(yīng)用系統(tǒng)中最常見的人機(jī)接口輸出顯示設(shè)備,單片機(jī)學(xué)習(xí)板通常都預(yù)留液晶顯示接口。圖9.1-1是連接LCD12864顯示屏的插座示例。圖9.1-1液晶LCD12864顯示連接接口9.1.STN-LCD液晶顯示開發(fā)表9.1-1是插座管腳定義。管腳號管腳名管腳功能

管腳號管腳名管腳功能1VSS電源地11DB4數(shù)據(jù)位42VDD電源正極12DB5數(shù)據(jù)位53V0液晶顯示對比度調(diào)節(jié)13DB6數(shù)據(jù)位64RS數(shù)據(jù)/命令選擇14DB7數(shù)據(jù)位75R/W讀/寫選擇15PSB串并選擇:“1”并行;“0”串行。6E使能信號16NC空腳,7DB0數(shù)據(jù)位017/RES復(fù)位信號,低電平有效8DB1數(shù)據(jù)位118VOUTLCD驅(qū)動電壓輸出端9DB2數(shù)據(jù)位219BLA背光源正極10DB3數(shù)據(jù)位320BLK背光源負(fù)極表9.1-1LCD12864管腳定義表如下:9.1.STN-LCD液晶顯示開發(fā)LCD全稱LiquidCrystalDisplay,液晶就是液態(tài)的晶體,是一種特殊的混合物質(zhì),具有固態(tài)物質(zhì)和液態(tài)物質(zhì)的雙重特性。液晶分子的排列受到電場影響會發(fā)生偏轉(zhuǎn),當(dāng)它偏轉(zhuǎn)使得光線通過,就顯示圖像,當(dāng)它偏轉(zhuǎn)阻擋了光線傳播,就沒有圖像。本節(jié)要介紹型號12864的STN-LCD液晶屏。STN-LCD液晶屏,是一種超扭曲向列屏(STN,SuperTwistedNematic),液晶分子在電場作用下,能發(fā)生180度以上的扭曲,從而改變旋光狀態(tài)形成顯示圖像。LCD12864表示像素陣列為128×64像素(列×行),基于128×64=8192個像素陣列,LCD可以顯示漢字及圖形。目前市場有帶字庫和不帶字庫兩種產(chǎn)品,不帶字庫的液晶屏由開發(fā)人員自己編寫字型碼,帶有字庫的程序中無需編寫字形碼,直接顯示字型。圖9.1-2展示了LCD12864的外觀。圖9.1-2LCD12864外觀9.1.STN-LCD液晶顯示開發(fā)液晶的顯示基礎(chǔ)是像素陣列,每個像素類似一個發(fā)光二極管(實(shí)際上是液晶分子的偏轉(zhuǎn)),當(dāng)不同位置的像素點(diǎn)亮后就構(gòu)成了字符。一個英文字母或數(shù)字通常使用8列16行個像素點(diǎn),一個漢字通常使用16列16行個像素點(diǎn)。表9.1-2列出了數(shù)字“5”、字母“A”、漢字“漢”的字模(宋體)編碼,它們的顯示情況如圖9.1-3所示,均為縱向取模。符號字模5x00,0x1F,0x11,0x11,0x11,0x10,0x10,0x00,0x00,0x98,0x04,0x04,0x04,0x88,0x70,0x00,A0x00,0x00,0x03,0x1C,0x07,0x00,0x00,0x00,0x04,0x3C,0xC4,0x40,0x40,0xE4,0x1C,0x04,漢x08,0x06,0x40,0x30,0x03,0x40,0x78,0x47,0x40,0x40,0x40,0x47,0x78,0x00,0x00,0x00,0x20,0x20,0x3E,0xC0,0x01,0x01,0x02,0x04,0xC8,0x30,0xC8,0x04,0x02,0x01,0x01,0x00,表9.1-2取模編碼9.1.STN-LCD液晶顯示開發(fā)縱向取模是從上到下取字節(jié),如圖9.1-3所示,對字母和數(shù)字,先取(X=0)的8個字節(jié),再?。╔=1)的8個字節(jié)。對于漢字,Y方向有16個比特2個字節(jié),先取(X=0)的16個字節(jié),再?。╔=1)的16個字節(jié)。(c)(b)(a)圖9.1-3字符顯示取模(編碼)原理9.1.STN-LCD液晶顯示開發(fā)LCD液晶顯示屏分為帶字庫和不帶字庫兩種類型。帶字庫的液晶支持ASCII字符集和GB2312字符集,一個漢字占用16×16個點(diǎn),所以12864液晶屏最多可顯示4行8列共32個漢字?;蛘?行16列共64個ASCII碼。不帶字庫的LCD需要開發(fā)人員自己提供圖形編碼,設(shè)計(jì)靈活,開發(fā)人員根據(jù)自己的應(yīng)用場景靈活選擇。1.LCD液晶有顯示緩存(DisplayDataRAM,DDRAM)。顯示緩存DDRAM存放要顯示字符的編碼。此外,LCD液晶模塊還有字庫存儲區(qū),分為三個存儲區(qū):中文字庫CGROM、ASCII碼半寬字庫HCGROM、自定義的字形空間CGRAM。9.1.STN-LCD液晶顯示開發(fā)LCD顯示區(qū)域與DDRAM的緩存地址一一映射,作為編程人員要記住它們的對應(yīng)關(guān)系,見表9.1-3。上表中80H是第一行的第一個漢字顯示區(qū)域,如果要顯示ASCII字符,那么地址80H可顯示兩個字符。行號第1列第2列第3列第4列第5列第6列第7列第8列第一行80H81H82H83H84H85H86H87H第二行90H91H92H93H94H95H96H97H第三行88H89H8AH8BH8CH8DH8EH8FH第四行98H99H9AH9BH9CH9DH9EH9FH表9.1-3LCD12864的顯示區(qū)域與緩存DDRAM的對應(yīng)關(guān)系任務(wù)1.在LCD12864屏幕上顯示信息任務(wù)要求:在LCD12864屏幕上顯示課程名字、開發(fā)人姓名以及班級學(xué)號。任務(wù)說明:點(diǎn)陣式圖形液晶顯示屏LCD能夠動態(tài)顯示圖形漢字以及各種符號信息,相對于數(shù)碼管而言,顯示內(nèi)容更豐富,為各種電子產(chǎn)品提供了友好的人機(jī)界面,具有工作電壓低、微功耗、體積小、可視面積大、無電磁輻射、數(shù)字接口、壽命長等特點(diǎn)。開發(fā)任務(wù)使用的液晶控制器是ST7920。任務(wù)資訊:1.液晶工作時序如下:(1)寫時序,單片機(jī)寫數(shù)據(jù)到液晶的時序(并行)如圖9.1-4所示:在RS周期時間內(nèi),R/W低電平、E高電平時,單片機(jī)在DB0--DB7輸出有效數(shù)字。圖9.1-4寫數(shù)據(jù)到液晶(并行)任務(wù)1.在LCD12864屏幕上顯示信息(2)讀時序,單片機(jī)從液晶讀數(shù)據(jù)的時序(并行)如圖9.1-5所示:在RS周期時間內(nèi),R/W高電平、E高電平,LCD將數(shù)據(jù)發(fā)送到DB0-DB7數(shù)據(jù)線上。圖9.1-5讀數(shù)據(jù)到單片機(jī)(并行)在圖9.1-4和圖9.1-5中,RS是命令和顯示數(shù)據(jù)內(nèi)容的指示信號(數(shù)據(jù)/命令選擇),當(dāng)單片機(jī)寫指令給液晶的時候,RS是低電平;當(dāng)單片機(jī)讀/寫顯示內(nèi)容時,RS是高電平。任務(wù)1.在LCD12864屏幕上顯示信息2.液晶顯示的指令控制液晶的游標(biāo)、顯示狀態(tài)等都受到指令的控制。在如圖9.1-4和圖9.1-5所示的時序中,當(dāng)RS為低電平時,單片機(jī)向液晶發(fā)送操作指令,其數(shù)據(jù)線上DB0-DB7上的數(shù)值為指令碼。液晶控制器(以ST7920為例)提供基本指令和擴(kuò)充指令兩套控制命令,常用指令見表9.1-4所示。指令RSR/W指令碼DB7DB6DB5DB4DB3DB2DB1DB0功能功能設(shè)定000x3000110RE00RE=0基本指令集清除顯示000x0100000001DDRAM的地址計(jì)數(shù)器AC設(shè)定為00H,并清除DDRAM里的顯示內(nèi)容。地址歸位000x0200000010DDRAM的地址計(jì)數(shù)器AC設(shè)定為00H,游標(biāo)也回到原點(diǎn),DDRAM內(nèi)容不發(fā)生變化。進(jìn)入點(diǎn)設(shè)定000x04+偏移地址000001I/DSI/D=0,光標(biāo)左移,DDRAM地址計(jì)數(shù)器AC減1;I/D=1,光標(biāo)右移,AC加1;S=0,畫面整體不變S=1,畫面整體移動顯示狀態(tài)開關(guān)000x08+偏移地址00001DCBD:整體顯示控制位當(dāng)D=1,整體顯示ON;當(dāng)D=0,整體顯示OFF,DDRAM里的內(nèi)容不變。C:光標(biāo)控制位,1:光標(biāo)ON;0:光標(biāo)OFF。B:光標(biāo)位置反白控制位。1:ON,光標(biāo)所在地址上的數(shù)據(jù)反白顯示;0:OFF。任務(wù)1.在LCD12864屏幕上顯示信息指令RSR/W指令碼DB7DB6DB5DB4DB3DB2DB1DB0功能游標(biāo)或顯示移位控制000x10+偏移值0001S/CR/L00設(shè)定游標(biāo)的移動與顯示的移位控制位,不改變DDRAM內(nèi)容。R/L=1:光標(biāo)向右移動;R/L=0:光標(biāo)向左移動S/C=1:光標(biāo)顯示跟著光標(biāo)移動;S/C=0:光標(biāo)顯示移位off。設(shè)定CGRAM地址000x60+偏移地址01AC5AC4AC3AC2AC1AC0設(shè)定CGRAM地址到地址計(jì)數(shù)器AC。設(shè)定DDRAM地址000x80+偏移地址1AC6AC5AC4AC3AC2AC1AC0設(shè)定DDRAM地址到地址計(jì)數(shù)器AC。讀取忙碌標(biāo)志01讀出值BFAC6AC5AC4AC3AC2AC1AC0BF:1,忙碌標(biāo)志位,1表示忙碌,同時可以讀出地址計(jì)數(shù)器AC的值。寫資料到RAM10寫入的數(shù)D7D6D5D4D3D2D1D0寫入資料到內(nèi)部的RAM。讀出RAM11讀出的值D7D6D5D4D3D2D1D0從內(nèi)部RAM讀取資料功能設(shè)定000x3400110RE00RE=1擴(kuò)充指令集設(shè)定繪圖RAM地址000x80+偏移地址1AC6AC5AC4AC3AC2AC1AC0在擴(kuò)充指令集下,設(shè)定CGRAM地址到地址計(jì)數(shù)器AC。任務(wù)1.在LCD12864屏幕上顯示信息(1)寫數(shù)據(jù)的子函數(shù)。在寫數(shù)據(jù)的時候沒有讀忙標(biāo)志,而是做了延時處理。voidLCD12864_Write_Data(unsignedchardat){LCD_E=0;LCD_RW=0;//選擇寫模式LCD_RS=1;//選擇數(shù)據(jù)模式//延時Delay100us(1);//將數(shù)據(jù)準(zhǔn)備LCD_Data=dat;Delay100us(1);LCD_E=1;//表示開始寫入數(shù)據(jù),上升沿寫入數(shù)據(jù)Delay100us(50);//延時等待數(shù)據(jù)全部發(fā)送完成}任務(wù)1.在LCD12864屏幕上顯示信息(2)向12864中寫入命令的子函數(shù)voidLCD12864_Write_Com(unsignedcharcom){//首先我們設(shè)置片選信號LCD_E=0;//片選信號一般設(shè)置為0表示片選LCD_RW=0;//選擇寫模式LCD_RS=0;//選擇命令模式//延時Delay100us(1);//數(shù)據(jù)準(zhǔn)備LCD_Data=com;Delay100us(1);LCD_E=1;//表示開始寫入數(shù)據(jù),上升沿寫入數(shù)據(jù)Delay100us(50);}任務(wù)1.在LCD12864屏幕上顯示信息(3)讀12864的狀態(tài)ucharReadStatusLCD(void){LCD_Data=0xFF;LCD_RS=0;LCD_RW=1;Delay100us(1);LCD_E=1;Delay100us(1);while(LCD_Data&Busy);//檢測忙信號LCD_E=0;return(LCD_Data);}任務(wù)1.在LCD12864屏幕上顯示信息任務(wù)具體代碼:此代碼基于圖9.1-1接口電路STC15F2K60S2單片機(jī)開發(fā),如果使用其它接口電路更改管腳定義即可。#include<STC15F2K60S2.H>#include<math.h>#include<INTRINS.H>#defineucharunsignedchar#defineuintunsignedint#definexcharunsignedcharcode#define LCD_DataP0#define DELAYMS80//MCUInterfaceDefinationsbitLCD_RS = P2^0;任務(wù)1.在LCD12864屏幕上顯示信息sbitLCD_RW = P2^1;sbitLCD_E =P1^2;sbitLCD_PSB= P2^6;sbitLCD_RST = P3^4;ucharcodelesson[]={"單片機(jī)應(yīng)用"};ucharcodename[]={"姓名:王小明"};ucharcodeclasses[]={"班級:天才班"};ucharcodeID[]={"學(xué)號:203011758"};#defineBusy0x80//用于檢測LCD狀態(tài)字中的Busy標(biāo)識voidDelay100us(unsignedchark) //@11.0592MHz{任務(wù)1.在LCD12864屏幕上顯示信息unsignedchari,j;while(k--) { _nop_(); _nop_(); i=2; j=15; do { while(--j); }while(--i); }}

任務(wù)1.在LCD12864屏幕上顯示信息//向12864中寫入數(shù)據(jù)voidLCD12864_Write_Data(unsignedchardat){LCD_E=0;LCD_RW=0;//選擇寫模式LCD_RS=1;//選擇數(shù)據(jù)模式//延時Delay100us(1);//將數(shù)據(jù)準(zhǔn)備LCD_Data=dat;Delay100us(1);LCD_E=1;//表示開始寫入數(shù)據(jù),上升沿寫入數(shù)據(jù)任務(wù)1.在LCD12864屏幕上顯示信息Delay100us(50);//延時等待數(shù)據(jù)全部發(fā)送完成}//向12864中寫入命令voidLCD12864_Write_Com(unsignedcharcom){//首先我們設(shè)置片選信號LCD_E=0;//片選信號一般設(shè)置為0表示片選LCD_RW=0;//選擇寫模式LCD_RS=0;//選擇命令模式//延時Delay100us(1);//將數(shù)據(jù)準(zhǔn)備任務(wù)1.在LCD12864屏幕上顯示信息LCD_Data=com;Delay100us(1);LCD_E=1;//表示開始寫入數(shù)據(jù),上升沿寫入數(shù)據(jù)Delay100us(50);}//讀狀態(tài)ucharReadStatusLCD(void){LCD_Data=0xFF;LCD_RS=0;LCD_RW=1;Delay100us(1);任務(wù)1.在LCD12864屏幕上顯示信息LCD_E=1;Delay100us(1);while(LCD_Data&Busy);//檢測忙信號LCD_E=0;return(LCD_Data);}//對LCD12864進(jìn)行初始化voidLCD12864_Init(){LCD_PSB=1;//并口,如果是0則為SPI串口 /*開始初始化的步驟*/LCD12864_Write_Com(0x30); //基本指令集任務(wù)1.在LCD12864屏幕上顯示信息LCD12864_Write_Com(0x08); //光標(biāo)畫面都OFFLCD12864_Write_Com(0x01); //顯示歸零LCD12864_Write_Com(0x06); //光標(biāo)右移,畫面整體不變LCD12864_Write_Com(0x0c); //畫面、光標(biāo)都開啟顯示}/*顯示中文和ascii碼。單個字符實(shí)際坐標(biāo):0x80->0x870x90->0x970x88->0x8f0x98->0x9f//這個坐標(biāo)我們自己規(guī)定的,再換算成上面的實(shí)際坐標(biāo)就可以了任務(wù)1.在LCD12864屏幕上顯示信息輸入坐標(biāo)(1,1)->(1,8)(4,1)->(4,8)再指出需要顯示的字符*/unsignedcharLCD_addr[]={0x80,0x90,0x88,0x98};voidLCD12864_Display_Char(ucharx,uchary,uchardat){LCD12864_Write_Com(0x30);LCD12864_Write_Com(0x06);//寫入地址LCD12864_Write_Com(LCD_addr[x-1]+(y-1));//上面的輸入坐標(biāo)//寫入數(shù)據(jù)LCD12864_Write_Data(dat);任務(wù)1.在LCD12864屏幕上顯示信息}//顯示漢字voidLCD12864_Display_Chars(unsignedcharx,unsignedchary,unsignedchar*dat){LCD12864_Write_Com(0x30);LCD12864_Write_Com(0x06);//寫入地址LCD12864_Write_Com(LCD_addr[x-1]+(y-1));//寫入數(shù)據(jù)while(*dat!='\0'){LCD12864_Write_Data(*dat);dat++;}}任務(wù)1.在LCD12864屏幕上顯示信息voidmain(){ Delay100us(10); LCD12864_Init(); LCD12864_Display_Chars(1,1,lesson);//顯示字庫中的中文數(shù)字LCD12864_Display_Chars(2,1,name);//顯示字庫中的中文數(shù)字LCD12864_Display_Chars(3,1,classes);//顯示字庫中的中文LCD12864_Display_Chars(4,1,ID);//顯示字庫中的中文數(shù)字 while(1) { ; } }任務(wù)1.在LCD12864屏幕上顯示信息二維碼9.1-1LCD顯示12864屏應(yīng)用程序任務(wù)25參考代碼及開發(fā)結(jié)果見二維碼9.1-1。9.2.狀態(tài)機(jī)設(shè)計(jì)狀態(tài)機(jī)是有限狀態(tài)機(jī)(Finite-statemachine,F(xiàn)SM)的簡稱,也稱有限狀態(tài)自動機(jī)。有限狀態(tài)機(jī)表示一個系統(tǒng)是有限個狀態(tài),有限狀態(tài)機(jī)中的狀態(tài)可以在事件觸發(fā)下自動轉(zhuǎn)移到下一個狀態(tài),在轉(zhuǎn)移過程中通常伴隨有某個動作。通常用狀態(tài)轉(zhuǎn)移圖描述狀態(tài)轉(zhuǎn)移的過程。狀態(tài):指物質(zhì)系統(tǒng)所處的狀況。將一個系統(tǒng)離散化,可以得到很多種狀態(tài),例如:地鐵閘機(jī)有打開、關(guān)閉兩個狀態(tài),電風(fēng)扇可以劃分為一檔、二檔、三檔、關(guān)閉等狀態(tài)。狀態(tài)可以用狀態(tài)變量來表示。轉(zhuǎn)移:一個狀態(tài)在某個事件觸發(fā)后,進(jìn)入到另外一個狀態(tài)的過程,就稱為轉(zhuǎn)移。地鐵閘機(jī)從關(guān)閉到打開,就說狀態(tài)發(fā)生了轉(zhuǎn)移。事件:執(zhí)行某個操作的觸發(fā)條件或者口令,是狀態(tài)機(jī)中進(jìn)入某個狀態(tài)的條件,比如過地鐵閘機(jī),“刷卡”就是一個事件。動作:也稱輸出或響應(yīng),指在某個狀態(tài)時特定發(fā)生的事情。比如,地鐵閘機(jī)在關(guān)閉或打開兩個狀態(tài)轉(zhuǎn)換的過程中,就有關(guān)門、開門的動作。9.2.狀態(tài)機(jī)設(shè)計(jì)FSM設(shè)計(jì)可以將復(fù)雜的問題分解為狀態(tài)管理和狀態(tài)轉(zhuǎn)換,是數(shù)字電路中非常重要的設(shè)計(jì)方法。狀態(tài)機(jī)設(shè)計(jì)首先要畫狀態(tài)遷移圖。以地鐵閘機(jī)為例,狀態(tài)遷移過程如圖9.2-1所示。圖中圓方框是狀態(tài),方框內(nèi)“|”左邊是狀態(tài),右邊是該狀態(tài)的響應(yīng)動作,箭頭表示轉(zhuǎn)移過程,箭頭曲線上的文字表明了狀態(tài)變化的條件(事件)。圖9.2-1狀態(tài)遷移圖第五章使用行列掃描矩陣按鍵法獲得兩行8個按鍵的鍵值,本章介紹使用狀態(tài)機(jī)獲得鍵值的方法。9.2.狀態(tài)機(jī)設(shè)計(jì)矩陣按鍵檢測的狀態(tài)轉(zhuǎn)移圖如圖9.2-2所示,一共有四個狀態(tài),起始狀態(tài)空閑;當(dāng)有按鍵按下,先進(jìn)行軟件消抖,防止誤操作;當(dāng)檢測到按鍵持續(xù)按下,則確認(rèn)有按鍵按下,同時記錄按下的時間,以區(qū)分短按和長按。當(dāng)按鍵釋放,則回到起始空閑狀態(tài)。圖9.2-2按鍵檢測狀態(tài)圖傳統(tǒng)做法都是在程序中增加延時消除按鍵抖動,但是頻繁調(diào)用延時delay子函數(shù)讓單片機(jī)空操作,實(shí)用性不高,采用狀態(tài)機(jī)則可以避免單片機(jī)的空跑,任務(wù)26采用狀態(tài)機(jī)編程思想編寫按鍵檢測代碼。任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描任務(wù)要求:4行4列矩陣式鍵盤,當(dāng)任一按鍵短時按下,就在數(shù)碼管上顯示該按鍵值;當(dāng)任一按鍵長時按下就熄滅顯示。1.任務(wù)資訊及分析:(1)鍵盤是人機(jī)接口的重要輸入設(shè)備,4×4、4×2鍵盤在電子產(chǎn)品中應(yīng)用十分廣泛。同學(xué)們在理解鍵盤掃描原理的基礎(chǔ)上,還要了解數(shù)碼管顯示鍵值的技巧。(2)矩陣式鍵盤由行線和列線組成,按鍵的兩端分別連接一個行線、一個列線,按鍵電路和第5章圖5.2-4一致。鍵值從左到右、從上往下在0~15編號,鍵值=行號×4+列號(行號、列號均在0~3之間取值)如圖9.2-4所示,圖5.2-4矩陣鍵盤只有兩行,因此對應(yīng)鍵值0~7。圖9.2-3矩陣鍵盤的鍵值任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描(3)檢測按鍵鍵值的方法有逐列掃描法、行列反轉(zhuǎn)法。本次采用行列反轉(zhuǎn)法編寫程序。(4)為了避免單片機(jī)延時空轉(zhuǎn),保證實(shí)時性,采用狀態(tài)機(jī)思想編程。2.代碼規(guī)劃:(1)編寫鍵盤掃描程序,行列反轉(zhuǎn)法獲得鍵值,同時讓鍵值顯示在數(shù)碼管上。程序流程如圖9.2-4所示:圖9.2-4程序流程圖任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描(2)采用模塊化編程思想,定義狀態(tài)機(jī)及按鍵相關(guān)數(shù)據(jù)類型://狀態(tài)typedefenum_keyState_TypeDef{ keyStateIdle=0, keyStateDebounce, keyStateConfirm, keyStatePressLong, }keyStateTypeDef;//響應(yīng)typedefenum_keyRESP_TypeDef{任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描keyRESPNull=0x00, keyRESPClick=0x01, keyRESPLongPress=0x02}keyRESPTypeDef;//事件typedefenum{ keyEventPress=0, keyEventRelease}keyEventTypeDef;//與按鍵有關(guān)的數(shù)據(jù)(或?qū)傩裕﹖ypedefstruct_keyData_TypeDef{任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描unsignedintkeyCount;//按鍵次數(shù) keyRESPTypeDefkeyRESP;//按鍵事件 keyStateTypeDefkeyState;//按鍵狀態(tài) keyEventTypeDefkeyEvent;//按鍵管腳電平}keyDataTypeDef;//變量定義,函數(shù)定義keyDataTypeDefkeyData;voidKeyEventCheck(void);voidKeyReadStateMachine(void);任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描(3)狀態(tài)機(jī)函數(shù)/************檢測是否有按鍵按下************************/staticvoidKeyEventCheck(void)//檢查是否有按鍵按下{ P0=0x0f;//列線Y拉高,行線X拉低 if(P0!=0x0f)//檢查列線,是否有按鍵按下 keyData.keyEvent=keyEventPress; else keyData.keyEvent=keyEventRelease;}/******狀態(tài)機(jī),讀取矩陣鍵盤鍵值************************/voidKeyReadStateMachine(void){9.2.狀態(tài)機(jī)設(shè)計(jì)staticu8col; KeyEventCheck(); switch(keyData.keyState) { casekeyStateIdle: if(keyData.keyEvent==keyEventPress)//如果有按鍵按下 keyData.keyState=keyStateDebounce;//去抖 break; casekeyStateDebounce: if(keyData.keyEvent==keyEventPress)//去抖后依舊按下 { keyData.keyState=keyStateConfirm;

keyData.keyRESP=keyRESPNull;任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描if(P00==0)col=1;//確定列號//查詢按鍵號碼 if(P01==0)col=2; if(P02==0)col=3; if(P03==0)col=4; P0=0xf0;//列線Y拉低,行線X拉高 if(P06==0){key_value=col-1;} if(P07==0){key_value=col+3; } } else { keyData.keyState=keyStateIdle; keyData.keyRESP=keyRESPNull; }任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描 break;

casekeyStateConfirm: if((keyData.keyEvent==keyEventPress)&(keyData.keyCount>=keyLongPressTime)) { keyData.keyState=keyStatePressLong; keyData.keyCount=0; } elseif((keyData.keyEvent==keyEventPress)&(keyData.keyCount<keyLongPressTime)) {任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描 keyData.keyCount++; keyData.keyState=keyStateConfirm; } else { keyData.keyCount=0; keyData.keyState=keyStateIdle;//按鍵釋放 keyData.keyRESP=keyRESPClick;//按鍵響應(yīng) } break; casekeyStatePressLong: if(keyData.keyEvent==keyEventPress) //一直等待釋放任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描{ keyData.keyState=keyStatePressLong; keyData.keyRESP=keyRESPNull; keyData.keyCount=0; } else { keyData.keyState=keyStateIdle; keyData.keyRESP=keyRESPLongPress; keyData.keyCount=0; } break; default:break; } }任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描(4)定時器中斷程序/******定時器0中斷服務(wù)函數(shù),定時事件1ms***********************/voidTimer0_Isr(void)interrupt1{ staticu8intr=0; DisplayScan();//每隔1ms數(shù)碼管掃描一次 if(++intr==10) { intr=0; KeyReadStateMachine();//每隔10ms掃描按鍵一次 } if(keyData.keyRESP==keyRESPClick) {任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描dspbuf[7]=key_value%10;//按鍵值的個位數(shù) dspbuf[6]=key_value/10;//按鍵值的十位數(shù) } if(keyData.keyRESP==keyRESPLongPress)//數(shù)碼管熄滅 { dspbuf[7]=10; dspbuf[6]=10; dspbuf[5]=10; dspbuf[4]=10; dspbuf[3]=10; dspbuf[2]=10; dspbuf[1]=10; dspbuf[0]=10; }}任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描二維碼9.2-1狀態(tài)機(jī)矩陣按鍵掃描應(yīng)用程序任務(wù)26參考代碼及開發(fā)結(jié)果見二維碼9.2-1。以上程序依靠狀態(tài)機(jī)完成了按鍵掃描,沒有調(diào)用延時函數(shù),防止了單片機(jī)空轉(zhuǎn)。9.3.總線擴(kuò)展復(fù)用設(shè)計(jì)盡管現(xiàn)代單片機(jī)管腳功能豐富,但在實(shí)際應(yīng)用中還存在著因?yàn)楣苣_數(shù)量不夠用而需要系統(tǒng)擴(kuò)展的時候。為此引入總線的概念??偩€是計(jì)算機(jī)系統(tǒng)的重要組成部分,它是一組信號線的集合,是計(jì)算機(jī)系統(tǒng)各模塊間傳送地址、數(shù)據(jù)和控制信息的公共通路。總線是各部件聯(lián)系的紐帶,它是計(jì)算機(jī)通信接口的重要技術(shù)。單片機(jī)總線就是單片機(jī)連接擴(kuò)展設(shè)備的一組公共信號線。按照功能劃分,總線可以劃分為地址總線、數(shù)據(jù)總線和控制總線:地址總線(AddressBus,AB),單片機(jī)向外發(fā)出的地址信號,以選擇外部設(shè)備或者設(shè)備內(nèi)部存儲單元。數(shù)據(jù)總線(DataBus,DB),單片機(jī)與外部設(shè)備之間進(jìn)行數(shù)據(jù)傳送的一組信號線。數(shù)據(jù)總線是雙向的,既可以由單片機(jī)向外部輸出數(shù)據(jù),也可以由外部向單片機(jī)輸入數(shù)據(jù)??刂瓶偩€(ControlBus,CB),單片機(jī)發(fā)出的一組控制命令信號線。按照總線的數(shù)量又可以劃分為并行擴(kuò)展總線和串行擴(kuò)展總線:9.3.總線擴(kuò)展復(fù)用設(shè)計(jì)并行擴(kuò)展總線:單片機(jī)一次傳輸一個字節(jié),數(shù)據(jù)總線有8條。串行擴(kuò)展總線:單片機(jī)一次傳輸一個位,數(shù)據(jù)總線只有1條。當(dāng)單片機(jī)連接設(shè)備時,如果管腳數(shù)量不夠用,可以將設(shè)備通過擴(kuò)展總線與單片機(jī)連接起來,如圖9.3-1所示。每次只有一個設(shè)備被選中傳輸信息。圖9.3-1三總線擴(kuò)展示意圖9.3.1.總線擴(kuò)展應(yīng)用電路設(shè)計(jì)如果擴(kuò)展總線上的設(shè)備數(shù)量太多,為了節(jié)省地址線,通常增加譯碼器電路。圖9.3-2展示了一種地址總線電路設(shè)計(jì)方法。P0端口是數(shù)據(jù)總線,P27、P26、P25經(jīng)過譯碼后與WR或非后構(gòu)成了地址總線。圖9.3-2譯碼器地址總線擴(kuò)展示意圖9.3.1.總線擴(kuò)展應(yīng)用電路設(shè)計(jì)3-8譯碼器電路見圖9.3-3。地址選擇管腳CBA分別連接P27、P26、P25,使能端G1、G2A、G2B直接連接到相應(yīng)的高電平或地,輸出則連接到了圖9.3-4或非門的輸入一端。或非門的另一端WR受跳線J13控制,連接單片機(jī)P42腳或者接地。單片機(jī)自帶WR和RD功能腳,WR和RD時序由51單片機(jī)自動產(chǎn)生,在執(zhí)行MOVXA,@DPTR時,RD自動跳變到低電平;在執(zhí)行MOVX@DPTR,A時,WR自動跳變到低電平。指令MOVX意味著要訪問寄存器片外存儲器DPTR。圖9.3-4電路可以利用單片機(jī)自帶WR功能節(jié)約編程量。圖9.3-3譯碼器電路9.3.1.總線擴(kuò)展應(yīng)用電路設(shè)計(jì)鎖存器電路見圖9.3-5,使能/OE直接連接GND,LE連接或非門輸出,當(dāng)LE是高電平,鎖存器輸出跟隨輸入;當(dāng)LE是低電平時,鎖存器閉鎖,輸入不起作用,輸出Q保持原有電平。圖9.3-4或非門電路

圖9.3-5鎖存器電路9.3.1.總線擴(kuò)展應(yīng)用電路設(shè)計(jì)器的編碼情況如表9.3-1所示,僅使用了4個編碼。P2.7、P2.6、P2.5作用說明111數(shù)碼管的段選共陽數(shù)碼管1108位數(shù)碼管的位選101蜂鳴器、電機(jī)、繼電器控制P0高電平時,蜂鳴器、繼電器動作100控制LED指示燈組P0低電平時,LED點(diǎn)亮其他無無表9.3-1總線擴(kuò)展3-8譯碼器的編碼表9.3.1.總線擴(kuò)展應(yīng)用電路設(shè)計(jì)LED燈組的總線復(fù)用電路如圖9.3-6所示,LED的負(fù)極連接鎖存器輸出,譯碼器選中Y4C后,P0控制LED的亮滅。圖9.3-6LED指示燈電路9.3.1.總線擴(kuò)展應(yīng)用電路設(shè)計(jì)LED燈組的總線復(fù)用電路如圖9.3-6所示,LED的負(fù)極連接鎖存器輸出,譯碼器選中Y4C后,P0控制LED的亮滅。圖9.3-6LED指示燈電路9.3.1.總線擴(kuò)展應(yīng)用電路設(shè)計(jì)LED燈組的總線復(fù)用電路如圖9.3-6所示,LED的負(fù)極連接鎖存器輸出,譯碼器選中Y4C后,P0控制LED的亮滅。圖9.3-6LED指示燈電路任務(wù)2.狀態(tài)機(jī)實(shí)現(xiàn)鍵盤掃描二維碼9.3-1總線復(fù)用LED點(diǎn)亮應(yīng)用程序點(diǎn)亮LED燈的程序參考二維碼9.3-1:9.3.1.總線擴(kuò)展應(yīng)用電路設(shè)計(jì)數(shù)碼管總線復(fù)用數(shù)碼管連接電路如圖9.3-7所示。8位數(shù)碼管的顯示段碼短接在一起,受鎖存器U7的控制,當(dāng)Y7C被3-8譯碼器選中(高電平),顯示段碼按照P0的輸出顯示字型;當(dāng)Y7C釋放后(低電平),顯示段碼維持原有字型。因?yàn)閿?shù)碼管其實(shí)就是異形發(fā)光二極管組成,因此,顯示段碼也串聯(lián)了限流電阻。8位數(shù)碼管的位選受鎖存器U8的控制,當(dāng)Y6C被3-8譯碼器選中,P0端口的輸出就

溫馨提示

  • 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

提交評論