s5pv210——按键
以下內(nèi)容源于朱有鵬嵌入式課程的學(xué)習(xí),以及博客http://www.cnblogs.com/biaohc/p/6353954.html的學(xué)習(xí)整理,如有侵權(quán),請(qǐng)告知?jiǎng)h除。
一、按鍵
1、按鍵的物理特性
- 按鈕沒(méi)有被按下時(shí),內(nèi)部是斷開(kāi)的。
- 按鈕被按下時(shí),內(nèi)部保持接通(閉合)狀態(tài);如果放手,則由于彈簧作用,按鈕又被彈開(kāi),內(nèi)部斷開(kāi)。
- 一般按鍵有4個(gè)引腳,分成2對(duì):一對(duì)是常開(kāi)觸點(diǎn)(像上面描述的不按則斷開(kāi),按下則閉合);一對(duì)是常閉觸點(diǎn)(平時(shí)不按時(shí)是閉合的,按下后是斷開(kāi)的)。
2、按鍵的電學(xué)原理(結(jié)合原理圖分析)
(1)硬件接法: SW5:GPH0_2,SW6:GPH0_3,SW78910:GPH2_0123;
(2)按鍵的電路連接分析
- 按鈕沒(méi)有按下,則按鈕內(nèi)部斷開(kāi),GPIO引腳處電壓為高電平;
- 按鈕被按下時(shí),則按鈕內(nèi)部導(dǎo)通,外部VDD經(jīng)過(guò)電阻和按鈕連接到地,形成回路,此時(shí)GPIO引腳處電壓就變成了低電平。
(3)總結(jié)
- 按鍵的按下與彈開(kāi),分別對(duì)應(yīng)GPIO的兩種電平狀態(tài)(按下則GPIO為低電平,彈開(kāi)則GPIO為高電平)。
- SoC內(nèi)部通過(guò)檢測(cè)這個(gè)GPIO的電平高低來(lái)判斷按鍵是否被按下,這個(gè)判斷結(jié)果即可作為SoC的輸入信號(hào)。
3、按鍵屬于輸入類(lèi)設(shè)備
按鍵一般用來(lái)做輸入設(shè)備(向SoC發(fā)送信息的設(shè)備,叫輸入設(shè)備),由人向SoC發(fā)送按鍵信號(hào)(按鍵信號(hào)有2種:按下信號(hào)和彈開(kāi)信號(hào))。
- 有些設(shè)備是單純的輸入設(shè)備,譬如按鍵、觸摸屏等;
- 有些設(shè)備是單純的輸出設(shè)備,譬如LCD;
- 有些設(shè)備是既能輸入又能輸出的,叫輸入輸出設(shè)備(IO),譬如串口。
4、按鍵的2種處理方式
SoC處理按鍵有2種思路:輪詢(xún)方式和中斷方式。
- 輪詢(xún)方式:SoC每隔一段時(shí)間去讀取(按鍵所對(duì)應(yīng)的)GPIO的電平高低,以此獲得按鍵信息;缺點(diǎn)在于CPU要一直注意按鍵事件,會(huì)影響CPU做其他事情。
- 中斷方式:SoC事先設(shè)定好GPIO觸發(fā)的中斷所對(duì)應(yīng)的中斷處理程序ISR,當(dāng)按鍵按下或彈開(kāi)時(shí)會(huì)觸發(fā)GPIO對(duì)應(yīng)的外部中斷,導(dǎo)致ISR執(zhí)行,從而自動(dòng)處理按鍵信息。
二、輪詢(xún)方式處理按鍵
1、X210開(kāi)發(fā)板的按鍵接法
- 由原理圖可以看出:按下時(shí)是低電平,彈起時(shí)是高電平
2、按鍵對(duì)應(yīng)的GPIO模式設(shè)置
- 按鍵接到GPIO上,按鍵按下還是彈起,決定外部電路的接通與否,從而決定這個(gè)GPIO引腳的電壓是高還是低;
- 這個(gè)電壓可以作為這個(gè)GPIO引腳的輸入信號(hào),此時(shí)GPIO配置為輸入模式,即可從SoC內(nèi)部讀取該引腳的電平為1還是0(1對(duì)應(yīng)高電平,0對(duì)應(yīng)低電平)。
- GPH0CON(0xE0200C00),GPH0DAT(0xE0200C04),GPH2CON(0xE0200C40),GPH2DAT(0xE0200C44)。
- 在CON寄存器中將GPIO設(shè)置為input模式,然后讀取DAT寄存器:讀取到的相應(yīng)位的值為1表示外部是高電平,讀取到的位的值為0表明外部是低電平。
- GPH0CON的每4bit(GPH0CON[?])控制GPH0的一個(gè)引腳(引腳?)的模式。
3、輪詢(xún)方式處理按鍵的程序流程
- 第一步,先初始化GPIO模式為input;
- 第二步,循環(huán)讀取GPIO的電平值,然后判斷有無(wú)按鍵按下;
4、輪詢(xún)方式檢測(cè)有無(wú)按鍵
/** s5pv210裸機(jī)實(shí)驗(yàn)* * key**/#define _REG_GPH0CON (*(volatile unsigned int *)0xE0200C00) #define _REG_GPH0DAT (*(volatile unsigned int *)0xE0200C04) #define _REG_GPH2CON (*(volatile unsigned int *)0xE0200C40) #define _REG_GPH2DAT (*(volatile unsigned int *)0xE0200C44)void led_blink(void); void led_off(void);void key_init(void) {//EINT2配置為輸入模式_REG_GPH0CON &= ~(0xFF<<8); //GPH2_0~GPH2_3置為輸入_REG_GPH2CON &= ~(0xFFFF<<0);}void key_polling(void) {key_init();while (1) { //由于通過(guò)_REG_GPH0CON設(shè)置GPH0_2這個(gè)引腳為輸入模式, //_REG_GPH0DAT這個(gè)寄存器對(duì)應(yīng)的位就是對(duì)應(yīng)引腳的值if (!(_REG_GPH0DAT & (0x1<<2))) {led_blink();}if (!(_REG_GPH0DAT & (0x1<<3))) {led_blink();}if (!(_REG_GPH2DAT & (0x1<<0))) {led_blink();}if (!(_REG_GPH2DAT & (0x1<<1))) {led_blink();}if (!(_REG_GPH2DAT & (0x1<<2))) {led_blink();}if (!(_REG_GPH2DAT & (0x1<<3))) {led_blink();}}}三、外部中斷
1、什么是外部中斷?數(shù)據(jù)手冊(cè)在哪里?
(1)SoC支持的中斷類(lèi)型中有一類(lèi)叫外部中斷。
- 內(nèi)部中斷,指中斷源來(lái)自于SoC內(nèi)部(一般是內(nèi)部外設(shè)),譬如串口、定時(shí)器等部件產(chǎn)生的中斷;
- 外部中斷是SoC外部的設(shè)備,通過(guò)外部中斷對(duì)應(yīng)的GPIO引腳產(chǎn)生的中斷。
(2)按鍵在SoC中就使用外部中斷來(lái)實(shí)現(xiàn)。
- 將按鍵電路接在外部中斷的GPIO上,然后將GPIO配置為外部中斷模式。
- 此時(shí)通過(guò)按按鍵改變按鍵電路的電壓高低,這個(gè)電壓高低會(huì)觸發(fā)GPIO對(duì)應(yīng)的外部中斷,通過(guò)引腳傳進(jìn)去給CPU處理。
2、電平觸發(fā)和邊沿觸發(fā)
- 外部中斷的觸發(fā)模式主要有2種:電平觸發(fā)和邊沿觸發(fā)。
- 電平觸發(fā):電平觸發(fā)分為高電平觸發(fā)和低電平觸發(fā)。電平觸發(fā)的特點(diǎn)是,只要電平滿(mǎn)足條件就會(huì)不停觸發(fā)中斷。
- 邊沿觸發(fā)分為上升沿觸發(fā)、下降沿觸發(fā)和雙邊沿觸發(fā)三種。邊沿觸發(fā)不關(guān)心電平常規(guī)狀態(tài),只關(guān)心電平變化的瞬間(邊沿觸發(fā)不關(guān)心電平本身是高還是低,只關(guān)心變化是從高到低還是從低到高的這個(gè)過(guò)程)。如果關(guān)注的是按鍵按下和彈起這兩個(gè)事件本身,那么應(yīng)該用邊沿觸發(fā)來(lái)處理按鍵;如果關(guān)心的是按鍵按下/彈起的那一段時(shí)間,那么應(yīng)該用電平觸發(fā)。
3、關(guān)鍵寄存器:CON、PEND、MASK
(1)外部中斷設(shè)置需要涉及到4個(gè)寄存器
- 接線(xiàn)引腳要設(shè)置為中斷模式;(通過(guò)對(duì)應(yīng)的GPIO控制寄存器,比如GPH0是通過(guò)GPH0CON寄存器控制的)
- 設(shè)置中斷觸發(fā)的方式;
- 中斷掩碼設(shè)置為使能中斷;
- 中斷掛起要設(shè)置為0,發(fā)生中斷以后,中斷處理函數(shù)要把中斷掛起為重新寫(xiě)為0;
(2)GPH0CON寄存器
- 接入中斷的引腳要設(shè)置為EXT_INT中斷模式;
(3)EXT_INT_0_CON寄存器
- 配置外部中斷的觸發(fā)方式。觸發(fā)方式就是說(shuō)外部電平怎么變化就能觸發(fā)中斷,也就是說(shuō)這個(gè)外部中斷產(chǎn)生的條件是什么。
(4)EXT_INT_0_PEND寄存器(中斷掛起寄存器)
- 每一位對(duì)應(yīng)一個(gè)外部中斷,沒(méi)有中斷時(shí)值為0。
- 發(fā)生中斷后,硬件自動(dòng)將此寄存器中該中斷對(duì)應(yīng)的位置1,我們?nèi)ヌ幚硗赀@個(gè)中斷后應(yīng)該手工將該位置0。
- PEND寄存器的位相當(dāng)于一個(gè)標(biāo)志,如果發(fā)生了中斷暫時(shí)忙來(lái)不及去處理時(shí),這個(gè)位一直是1(這就是掛起),直到處理了此中斷才會(huì)手工清除(寫(xiě)代碼清除)這個(gè)掛起位,表示此中斷被處理了。
(5)EXT_INT_0_MASK寄存器
- 各個(gè)外部中斷的使能/禁止開(kāi)關(guān)。
-
EXT_INT_0_MASK:中斷掩碼要設(shè)置為0。
4、中斷方式處理按鍵?
#define EXT_INT_0_CON 0xE0200E00 #define EXT_INT_2_CON 0xE0200E08 #define EXT_INT_0_PEND 0xE0200F40 #define EXT_INT_2_PEND 0xE0200F48 #define EXT_INT_0_MASK 0xE0200F00 #define EXT_INT_2_MASK 0xE0200F08#define _REG_EXT_INT_0_CON (*(volatile unsigned int *)EXT_INT_0_CON) #define _REG_EXT_INT_2_CON (*(volatile unsigned int *)EXT_INT_2_CON) #define _REG_EXT_INT_0_PEND (*(volatile unsigned int *)EXT_INT_0_PEND) #define _REG_EXT_INT_2_PEND (*(volatile unsigned int *)EXT_INT_2_PEND) #define _REG_EXT_INT_0_MASK (*(volatile unsigned int *)EXT_INT_0_MASK) #define _REG_EXT_INT_2_MASK (*(volatile unsigned int *)EXT_INT_2_MASK)//中斷方式初始化按鍵 void key_inter_init(void) {//ENIT2、ENIT3引腳設(shè)置為中斷模式_REG_GPH0CON |= (0xFF<<8);//ENIT16、ENIT17、ENIT18、ENIT19引腳設(shè)置為中斷模式_REG_GPH2CON |= (0xFFFF<<0);//設(shè)置ENIT2、ENIT3為下降沿觸發(fā)_REG_EXT_INT_0_CON &= ~(0xFF<<8);_REG_EXT_INT_0_CON |= ((0x2<<8) | (0x2<<12));//設(shè)置ENIT16、ENIT17、ENIT18、ENIT19為下降沿觸發(fā)_REG_EXT_INT_2_CON &= ~(0xFFFF<<0);_REG_EXT_INT_0_CON |= ((0x2<<0) | (0x2<<4) | (0x2<<8) | (0x2<<12));//使ENIT2、ENIT3能外部中斷;_REG_EXT_INT_0_MASK &= ~(0x3<<2);//使ENIT16、ENIT17、ENIT18、ENIT19能外部中斷;_REG_EXT_INT_2_MASK &= ~(0xF<<0);/* //清ENIT2、ENIT3中斷掛起_REG_EXT_INT_0_PEND |= (0x3<<2);//清ENIT16、ENIT17、ENIT18、ENIT19中斷掛起_REG_EXT_INT_2_PEND |= (0xF<<0);*/clean_int_pend(); }?總結(jié):
(1)由于按鍵的連接方式,知按鍵是連接到GPH0和GPH1的。
以GPH0為例,接了按鍵eint1、enit2。可以通過(guò)GPH0CON寄存器控制GPH0每個(gè)引腳的模式(輸出、輸入、中斷)。如果是中斷,可知eint1和eint2的中斷號(hào)分別為2,3,可以統(tǒng)一看做是中斷組號(hào)0下的中斷,因此是在ext_int_0_前綴的寄存器下繼續(xù)進(jìn)行觸發(fā)條件的設(shè)置(EXT_INT_0_CON寄存器),以及是否啟用中斷的設(shè)置(EXT_INT_0_MASK寄存器)。由于是中斷2,3,因此設(shè)置的是2,3中斷對(duì)應(yīng)的位([]中為2,3的)。
?
?
附:串口輸出和按鍵消抖
1、基于串口標(biāo)準(zhǔn)輸出的按鍵調(diào)試
- 以之前的串口stdio的工程為基礎(chǔ)來(lái)移植添加輪詢(xún)方式按鍵處理。
- 注意USB下載方式可能有錯(cuò)誤(有可能不下載,也有可能下載了執(zhí)行不對(duì)),解決方案是用SD卡啟動(dòng)來(lái)替代。
2、按鍵消抖
(1)按鍵這種物理器件本身會(huì)有抖動(dòng)信號(hào)
- 抖動(dòng)信號(hào)指的是在電平由高到低(也就是按鍵按下時(shí))或者電平由低到高(也就是按鍵彈起時(shí))過(guò)程中,電平的變化不是立刻變化,而是經(jīng)過(guò)了一段時(shí)間的不穩(wěn)定期才完成變化,在這個(gè)不穩(wěn)定期間電平可能會(huì)時(shí)高時(shí)低反復(fù)變化,這個(gè)不穩(wěn)定期就叫抖動(dòng)。
- 抖動(dòng)期內(nèi)獲取按鍵信息是不可靠的,要想辦法消抖。
(2)什么叫消抖?
- 消抖就是用硬件或者軟件方法來(lái)盡量減小抖動(dòng)期對(duì)按鍵獲取的影響。
- 第一是硬件消抖,消抖思路就是盡量減小抖動(dòng)時(shí)間,方法是通過(guò)硬件添加電容等元件來(lái)減小抖動(dòng);
- 第二是軟件消抖,消抖思路是發(fā)現(xiàn)一次按鍵按下/彈起事件后,不立即處理按鍵,而是延時(shí)一段時(shí)間(一般10~20ms,這就是消抖時(shí)間)后再次獲取按鍵鍵值,如果此次獲取和上次一樣是按下/彈起,那就認(rèn)為真的按下/彈起了。
- 一般比較精密需要的時(shí)候,需要硬件消抖和軟件消抖一起配合。
總結(jié)
以上是生活随笔為你收集整理的s5pv210——按键的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 27款优秀的Android逆向工程工具
- 下一篇: java自学网站,看完不后悔,千万不要做