單片機(jī)按鍵的解決方法_第1頁
單片機(jī)按鍵的解決方法_第2頁
單片機(jī)按鍵的解決方法_第3頁
單片機(jī)按鍵的解決方法_第4頁
單片機(jī)按鍵的解決方法_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、單片機(jī)按鍵的解決解決方案1、 單片機(jī)上的按鍵控制一般采用兩種控制方法:中斷和查詢。中斷必須借助中斷引腳,而查詢按鍵可用任何IO端口。按鍵較少時,一個按鍵占用一個端口,而按鍵較多時,多采用矩陣形式(如:經(jīng)常用4個端口作為輸出,4個端口作為輸入的4X4矩陣來獲得16個按鍵);還可以用單片機(jī)的AD轉(zhuǎn)換功能一個引腳接多個按鍵,根據(jù)電阻分壓原理判斷是哪個按鍵按下。2、 中斷形式STM32可支持68個中斷通道,已經(jīng)固定分配給相應(yīng)的外部設(shè)備,每個中斷通道都具備自己的中斷優(yōu)先級控制字節(jié)PRI_n(8位,但是STM32中只使用4位,高4位有效),每4個通道的8位中斷優(yōu)先級控制字構(gòu)成一個32位的優(yōu)先級寄存器。68

2、個通道的優(yōu)先級控制字至少構(gòu)成17個32位的優(yōu)先級寄存器.4bit的中斷優(yōu)先級可以分成2組,從高位看,前面定義的是搶占式優(yōu)先級,后面是響應(yīng)優(yōu)先級。按照這種分組,4bit一共可以分成5組 第0組:所有4bit用于指定響應(yīng)優(yōu)先級; 第1組:最高1位用于指定搶占式優(yōu)先級,后面3位用于指定響應(yīng)優(yōu)先級; 第2組:最高2位用于指定搶占式優(yōu)先級,后面2位用于指定響應(yīng)優(yōu)先級; 第3組:最高3位用于指定搶占式優(yōu)先級,后面1位用于指定響應(yīng)優(yōu)先級; 第4組:所有4位用于指定搶占式優(yōu)先級。所謂搶占式優(yōu)先級和響應(yīng)優(yōu)先級,他們之間的關(guān)系是:具有高搶占式優(yōu)先級的中斷可以在具有

3、低搶占式優(yōu)先級的中斷處理過程中被響應(yīng),即中斷嵌套。當(dāng)兩個中斷源的搶占式優(yōu)先級相同時,這兩個中斷將沒有嵌套關(guān)系,當(dāng)一個中斷到來后,如果正在處理另一個中斷,這個后到來的中斷就要等到前一個中斷處理完之后才能被處理。如果這兩個中斷同時到達(dá),則中斷控制器根據(jù)他們的響應(yīng)優(yōu)先級高低來決定先處理哪一個;如果他們的搶占式優(yōu)先級和響應(yīng)優(yōu)先級都相等,則根據(jù)他們在中斷表中的排位順序決定先處理哪一個。每一個中斷源都必須定義2個優(yōu)先級。有幾點(diǎn)需要注意的是: 1)如果指定的搶占式優(yōu)先級別或響應(yīng)優(yōu)先級別超出了選定的優(yōu)先級分組所限定的范圍,將可能得到意想不到的結(jié)果; 2)搶占式優(yōu)先級別相同的中斷源之間沒有嵌

4、套關(guān)系;3)如果某個中斷源被指定為某個搶占式優(yōu)先級別,又沒有其它中斷源處于同一個搶占式優(yōu)先級別,則可以為這個中斷源指定任意有效的響應(yīng)優(yōu)先級別。GPIO外部中斷:STM32中,每一個GPIO都可以觸發(fā)一個外部中斷,但是,GPIO的中斷是以組為一個單位的,同組間的外部中斷同一時間智能使用一個,如:PA0,PB0,PC0,PD0,PE0,PF0這些為1組,如果我們使用PA0作為外部中斷源,那么別的就不能使用了,在此情況下我們使用類似于PB1,PC2這種末端序號不同的外部中斷源,每一組使用一個中斷標(biāo)志EXTI x.EXTI0EXTI4這5個外部中斷有著自己單獨(dú)的中斷響應(yīng)函數(shù)。EXTI5EXTI9共用一

5、個中斷響應(yīng)函數(shù),EXTI10EXTI15共使用一個中斷響應(yīng)函數(shù)。對于中斷的控制,STM32有一個專用的管理機(jī)構(gòu)NVIC.中斷的使能,掛起,優(yōu)先級,活動等等都是由NVIC在管理的。編寫IO口外部中斷步驟及其注意事項(xiàng):(1) 設(shè)置中斷優(yōu)先級組;(2)開啟時鐘(IO口時鐘,復(fù)用時鐘);(3)設(shè)置中斷線并對中斷進(jìn)行初始化配置(設(shè)置中斷線,確定中斷模式,中斷觸發(fā)沿設(shè)置,使用指定設(shè)置初始化外部中斷);(4)設(shè)置中斷管理器NVIC各參數(shù)(包括:使能產(chǎn)生外部中斷外設(shè)的IO口所在的外部中斷通道;設(shè)置外部中斷的優(yōu)先級-搶占優(yōu)先級,響應(yīng)優(yōu)先級;使能外部中斷通道;使用設(shè)置好的各個中斷管理器上的參數(shù)來初始化中斷管理器)

6、。外部中斷服務(wù)函數(shù)完成中斷操作需要最終達(dá)到的目標(biāo)。3、 矩陣形式鍵盤矩陣原理:a*b矩陣鍵盤由a條行線和b條列線組成,行線接端口P3(p3表任一端口)P3.0、P3.1、P3.2p3.(a-1);列線接p 3.a,p3.(a+1)P3.(b-1).按鍵位于每條行線和列線的交叉點(diǎn)上。按鍵的識別可采用行掃描法和線反轉(zhuǎn)法,這里采用簡單的線反轉(zhuǎn)法,只需三步。第一步,執(zhí)行程序使X0X3均為低電平,此時讀取各列線Y0Y3的狀態(tài)即可知道是否有鍵按下。當(dāng)無鍵按下時,各行線與各列線相互斷開,各列線仍保持為高電平;當(dāng)有鍵按下時,則相應(yīng)的行線與列線通過該按鍵相連,該列線就變?yōu)榈碗娖?,此時讀取Y0Y1Y2Y3的狀態(tài),

7、得到列碼。第二步,執(zhí)行程序使Y0Y3均為低電平,當(dāng)有鍵按下時,X0X3中有一條行線為低電平,其余行線為高電平,讀取X0X1X2X3的狀態(tài),得到行碼。第三步,將第一步得到的列碼和第二步得到的行碼合并得到按鍵的位置碼,即是Y3Y2Y1Y0X3X2X1X0(因?yàn)樾芯€和列線各有一條電平,其余為高電平,所以位置碼低四位和高四位分別只有一位低電平,其余為高電平)。也就是說,當(dāng)某個鍵按下時,該鍵兩端所對應(yīng)的行線和列線為低電平,其余行線和列線為高電平.比如,當(dāng)0鍵按下時,行線X0和列線Y0為低電平,其余行列線為高電平,于是可以得到0鍵的位置碼Y3Y2Y1Y0x3X2X1X0為11101110即是0xEE.全部

8、按鍵碼為: 矩陣鍵盤在單片機(jī)上的簡單應(yīng)用-顯示數(shù)碼管:0F(51單片機(jī)) #include<reg51.h> #define uchar unsigned char#define uint unsigned intSbit buzzer =P10;Uchar code_dis=/09,AF 0xC0,0XF9,0XA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90,0z88,0x83,0xC6,0xA1,0x86,0x8E;Uchar code_tab=/矩陣鍵盤按鍵位置碼 0x77,0xb7,0xd7,0xe7, 0x7b,0xbb,0xdb,0xeb,0

9、x7d,0xbd,0xdd,0xed,0x7e,0xbe,0xde,0xee;void delay(uint x) /延時函數(shù)uchar i; while(x-) for(i=0;i<120;i+); uchar scan()/矩陣鍵盤掃描函數(shù),得到按鍵號,采用線反轉(zhuǎn)法 uchar a,b,c,i; P3=0XF0; /P3口輸出11110000 a=P3; /讀取列碼delay(10); /防抖延時10ms P3=0X0F; /P3口輸出00001111 b=P3; /讀取行碼c=a+b;/得到位置碼for(i=0;i<16;i+) if(c=tabi)return i; /查表

10、得到按鍵序號并返回 return -1; /無按鍵,則返回-1Void beep(void)/蜂鳴器發(fā)出聲音,模擬按鍵聲音 Uchar i; For(i=0;i<100;i+)Buzzer=buzzer;Delay(1);Buzzer=0;Void main(void) uchar key; buzzer=0; /關(guān)閉蜂鳴器while(1) key=scan(); /得到按鍵號if(key!=-1)/有按鍵則顯示,并且蜂鳴器發(fā)出聲音 P0=diskey; beep(); delay(100); 掃描法:矩陣鍵盤工作原理:由于按鍵沒有接地,4行  4列正好占用8個I/O 

11、; 如果4行我們送 P3.0到P3.3送入0 1 1 1 然后去讀取 4列的值,如果P3.0的按鍵按下那么P3.4-P3.7的值等于 0 1 1 1,假如是第2個鍵按下的話那么讀回來的值是 1 0 1 1 ,如果第3個鍵按下去讀回來的值是 1 1 0 1 ,如果第4個鍵按下去讀回來的值是 1 1 1 0 ,如果沒有鍵按下去讀回來就是1 1 1 1。  所以我們就根據(jù)讀回來的值來判斷按下去的是那個鍵。當(dāng)然這是對P3.0這一行,因?yàn)榫仃囨I盤是掃描的,所以下次把P3.0 給1  P3.1 給0對第2行,陸續(xù)的第3 行第4行, 0111 1011 1101 11

12、10  而每次都去從新掃描一遍列值列有4個值,以確定是那個鍵按下。無論何時任何一個時間有一個按鍵被按下就跳出循環(huán)。當(dāng)然不可能有2個鍵剛好一起按下你的手沒有這么好的力度,就算有2個鍵一起按鍵,程序也有先后檢測的順序,只能檢測一個后面的檢測不到。P3 = 0XFE; /第一行給0temp ;定義個變量temp = P3 ;讀回來  由于讀需要先寫1  因?yàn)镻3= FE  已經(jīng)把高4位給1了  所以能讀了temp & oxf0   如果沒有按鍵按下結(jié)果還是0xf0 .如果有鍵按下結(jié)果就不是0xf0了。num &#

13、160; 然后我們再定義一個變量 讓它賦值給這個按下去的按鍵值。 一次類推把第一行賦值0 掃描一遍 然后把第2行賦值0掃描一遍.共掃描16遍。只要有鍵按下 就會得到一個值 num 就從1排到16. 共16個按鍵 4*4 的矩陣鍵盤。我再總結(jié)下思路:首先 低4位是行 共4行  分別把每行給0 低電平   就4次 0 1 1 1 、1 0 1 1 、 1 1 0 1 、1 1 1 0 對吧然后去檢測高4位  4列啊 先不考慮極端情況,4列就4個按鍵只要按下一個 P3口的高4位就會有一個值。根據(jù)這個值就能判斷是

14、那個鍵了。如:P3= 1111 1110   低四位是行先把第一行給0 有按鍵下的話 temp = P3 讀回來  1101 1110 然后temp &  0xf0  與運(yùn)算下就判斷下還等于oxf0嗎?如還等于就沒有按下,如果不等于就肯定有按鍵按下。定義個變量讓它等于這個不是0XF0的值,做個標(biāo)記。依次類推。然后用這個思路寫個程序吧!寫的不太好看的不是很清楚只是做個參考吧,只要把思路理清楚就行了。是這樣我們分別按這16個按鍵讓它分別顯示是第幾個 比如 按下第一個數(shù)碼管就顯示1 第2個數(shù)碼管就顯示2,依次類推

15、。一直到 F  (為了方便讓所有的數(shù)碼管顯示同一個數(shù)0-F)#include#define uint unsigned int#define uchar unsigned charsbit dula = P26;sbit wela = P27;sbit key1= P34;uchar code table =0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0/加這個0就是什么都不顯示;uchar num,temp,num1;void delay(uint z) u

16、int x,y; for(x=z;x>0;x-)  for(y=110;y>0;y-);uchar keyscan();/聲明一下/void display(uchar num1);/這里可以做個顯示函數(shù),但是我沒做。void main()     num = 17;/讓它顯示0 什么都不顯示。 因?yàn)楹瘮?shù)返回num值     dula =1 ;     P0= 0;     dula =0;&#

17、160;    wela = 1;     P0= 0xc0;     wela = 0;      /以上P0口控制數(shù)碼管的一上電什么都不顯示   while(1)               num1 = keyscan();/沒按下返回17 &

18、#160;             dula =1;               P0= tablenum1-1;/17-1 =16               dula = 0; 

19、0;            /用uchar keyscan() 帶返回值的函數(shù) 代替整個矩陣鍵盤  當(dāng)然顯示就不要了 dula  那3行我注釋掉了uchar keyscan()P3= 0xfe; /高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求temp =P3;/讀回來了temp &= 0xf0;/因?yàn)槲覀冎皇亲x回來高4位while (temp != 0xf0) /下面的幾個while循環(huán)判斷可以用if好理解。只看到第一行就行了。/這幾個

20、while 都是做判斷用的delay(5);/消除抖動的temp=P3;temp &= 0xf0;while(temp != 0xf0) /確實(shí)不等于0xf0有按鍵按下temp = P3;/我們這個時候只是把P3口的值賦給了tempswitch (temp) /檢測P3口。  case 0xee:      num = 1;   break;  case 0xde:       

21、num=2; break;  case 0xbe:      num=3;   break;  case 0x7e:    num=4; break;    while(temp != 0xf0)/有按鍵按下可能是不等于的   循環(huán)在這里面  松手檢測   temp = P3;  temp = temp & 0xf0; /這個是松

22、手檢測  松手這里就等于了0xf0  /下面就顯示一下  退出整個一行的循環(huán),不加松手檢測會退不出去循環(huán)/到這里是把第一行檢測了。/以下下是其他幾行檢測的代碼P3= 0xfd; /高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求temp =P3;/讀回來temp &= 0xf0;/因?yàn)槲覀冎皇亲x回來高4位while (temp != 0xf0) delay(5);/消除抖動的 temp=P3; temp &= 0xf0; while(temp != 0xf0) /確實(shí)不等于0xf0有按鍵按下

23、 temp = P3;/我們這個時候只是把P3口的值賦給了temp switch (temp) /檢測P3口。  case 0xed:      num = 5;   break; case 0xdd:      num=6;break; case 0xbd:    num=7; break; case 0x7d:&#

24、160;     num=8;  break;  while(temp != 0xf0)/有按鍵按下可能是不等于的   循環(huán)在這里面  松手檢測 temp = P3;temp = temp & 0xf0; /這個是松手檢測  松手這里就等于了0xf0 /下面就顯示一下  退出整個2行的循環(huán)。不加松手檢測會退不出去循環(huán) /到這里是把第2行檢測了。       P

25、3= 0xfb; /高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求       temp =P3;/讀回來了       temp &= 0xf0;/因?yàn)槲覀冎皇亲x回來高4位       while (temp != 0xf0)            delay(5);/消除抖動的 

26、;           temp=P3;            temp &= 0xf0;          while(temp != 0xf0) /確實(shí)不等于0xf0有按鍵按下          &

27、#160;  temp = P3;/我們這個時候只是把P3口的值賦給了temp             switch (temp) /檢測P3口。                  case 0xeb:        &

28、#160;             num =9;                       break;             

29、60;   case 0xdb:                      num=10;                     break;  &

30、#160;              case 0xbb:                     num=11;            &

31、#160;         break;                 case 0x7b:                    num=12;  

32、0;                 break;        while(temp != 0xf0)/有按鍵按下可能是不等于的   循環(huán)在這里面  松手檢測  temp = P3;temp = temp & 0xf0; /這個是松手檢測松手這里就等于了0xf0    

33、                  /下面就顯示一下  退出整個3行的循環(huán)。  不加松手檢測會退不出去循環(huán)    /到這里是把第3行檢測了。                   

34、P3= 0xf7; /高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求       temp =P3;/讀回來了       temp &= 0xf0;/因?yàn)槲覀冎皇亲x回來高4位       while (temp != 0xf0)            delay(5);/消除抖動的

35、0;           temp=P3;            temp &= 0xf0;          while(temp != 0xf0) /確實(shí)不等于0xf0有按鍵按下         temp =

36、 P3;/我們這個時候只是把P3口的值賦給了temp switch (temp) /檢測P3口                   case 0xe7:                      num =13

37、 ;                       break;                 case 0xd7:                      num=14;                   

溫馨提示

  • 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

提交評論