GPIO輸入——按鍵檢測
按鍵檢測使用到GPIO外設(shè)的基本輸入功能,本章中不再贅述GPIO外設(shè)的概念,如您忘記了可重新回到第八章節(jié)進(jìn)行閱讀。
12.1. 硬件設(shè)計
按鍵機械觸點斷開、閉合時,由于觸點的彈性作用,按鍵開關(guān)不會馬上穩(wěn)定接通或一下子斷開,使用按鍵時會產(chǎn)生 圖12_1中的帶波紋信號,需要用軟件消抖處理濾波,不方便輸入檢測。
本實驗用到的野火啟明6M5開發(fā)板的按鍵帶硬件消抖功能,它利用電容充放電的延時,消除了波紋,從而簡化軟件的處理,軟件只需要直接檢測引腳的電平即可。
瑞薩設(shè)計的微處理器(MCU)擁有硬件數(shù)字濾波的功能用來實現(xiàn)去除按鍵帶來的紋波影響, 不過前提是按鍵用在外部中斷作為按鍵信號輸入的情況下使用, 通過使用數(shù)字濾波的方式能夠替代掉用電容式濾波的方法來消除紋波, 從而減少我們在硬件上的開發(fā)成本。
野火啟明6M5開發(fā)板的按鍵電路圖如 圖12_2所示,圖中RA6M5芯片的P004、P005引腳分別通過一個10KΩ的貼片電阻連接到電源的正極,所以按鍵在沒有被按下的時候,GPIO引腳的輸入狀態(tài)為高電平狀態(tài), 分別又通過串聯(lián)一個100Ω的貼片電阻和一個按鍵接地,所以按鍵在被按下的時候,GPIO引腳的輸入狀態(tài)為低電平狀態(tài)。 只要我們檢測引腳的輸入電平,即可判斷按鍵是否被按下。
若您使用的實驗板按鍵的連接方式或引腳不一樣,只需根據(jù)我們的工程修改引腳即可,程序的控制原理相同。
12.2. 按鍵程序設(shè)計
使用瑞薩官方提供的FPS庫進(jìn)行編程,瑞薩官方提供的FPS庫具有方便、快捷、簡潔的特性。 在下面會教大家如何使用FPS庫進(jìn)行編程。
12.2.1. 新建工程
對于 e2 studio 開發(fā)環(huán)境:拷貝一份我們之前的 e2s 工程模板 “11_GPIO_LED” , 然后將工程文件夾重命名為 “12_Key” ,最后再將它導(dǎo)入到我們的 e2 studio 工作空間中。
對于 Keil 開發(fā)環(huán)境:拷貝一份我們之前的 Keil 工程模板 “11_GPIO_LED” , 然后將工程文件夾重命名為 “12_Key” ,并進(jìn)入該文件夾里面雙擊 Keil 工程文件,打開該工程。
工程新建好之后,在工程根目錄的 “src” 文件夾下面新建 “key” 文件夾, 再進(jìn)入 “key” 文件夾里面新建 key 驅(qū)動的源文件和頭文件:“bsp_key.c” 和 “bsp_key.h”。 工程文件結(jié)構(gòu)如下。
文件結(jié)構(gòu)
12_Key
├─ ......
└─ src
├─ led
│ ├─ bsp_led.c
│ └─ bsp_led.h
├─ key
│ ├─ bsp_key.c
│ └─ bsp_key.h
└─ hal_entry.c
警告
注意:對于使用 Keil 開發(fā)環(huán)境的用戶,將代碼文件放到 “src” 文件夾下之后, Keil 軟件并不會自動將它們加入到工程,這時候需要打開 RASC FSP 配置界面, 點擊一次單擊右上角的 “Generate Project Content” 按鈕,從而 “src” 文件夾下的代碼文件就會被自動加進(jìn)工程中。 接著關(guān)閉 FSP 配置界面返回到 Keil,然后進(jìn)行一次編譯會彈出一個提示框提示工程結(jié)構(gòu)發(fā)生了變化,點擊確定即可。 對于使用 e2 studio 的用戶則不需如此。
12.2.2. FSP配置
接下來我們要在fsp里配置芯片的引腳相關(guān)的屬性。
在打開 “FSP” 配置界面后, 在 “FSP” 配置界面里面點開 “Pins” -> “Ports” -> “P0” -> “P004” , 然后將連接到按鍵的IO引腳的 “Mode” 屬性配置為 “Input Mode” ,其他的屬性默認(rèn)即可,LED引腳的配置同上節(jié)一樣配置。
Pin Configuration 頁面的 IOPORT 屬性介紹:
IOPORT 屬性介紹
IOPORT 屬性 | 描述 |
---|---|
---------------------------------------------------- |
模式 | IO引腳的工作模式,包括輸入模式和輸出模式。 |
---|---|
拔 | IO引腳是否上拉。 |
驅(qū)動器容量 | IO引腳的驅(qū)動能力設(shè)置。 |
輸出類型 | IO引腳的輸出類型。 可以選 CMOS 推挽輸出或開漏輸出。 |
配置完成之后的配置界面如圖所示。
配置完成之后按下快捷鍵“Ctrl + S”保存,最后點右上角的 “Generate Project Content” 圖標(biāo), 讓軟件根據(jù)我們的設(shè)置自動生成配置代碼即可。
對于 Keil 這邊 RASC 的 FSP 配置也是一樣的,需要先通過 RASC 軟件打開 Keil 工程相關(guān)的 FSP 配置界面。 具體的方法在前面的章節(jié)已經(jīng)詳述過了,這里不再重復(fù)說明。
12.3. 按鍵程序思路
使用瑞薩的FSP對軟件設(shè)計的思路非常地簡單:首先通過R_IOPORT_Open函數(shù)初始化配置 LED 引腳,之后使用R_IOPORT_PinRead 函數(shù)來獲取當(dāng)前引腳的電平的狀態(tài)。
12.3.1. R_IOPORT_PinRead 函數(shù)
通過 R_IOPORT_Open 函數(shù)初始化相應(yīng)的引腳之后,我們使用R_IOPORT_PinRead函數(shù)來獲取引腳的電平的狀態(tài)。 我們通過分析R_IOPORT_PinRead函數(shù),最主要的是通過p_pin_value這個枚舉類型來獲取IO的狀態(tài)。
fsp_err_t R_IOPORT_PinRead (ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t * p_pin_value)
注解
bsp_io_port_pin_t枚舉來決定需要獲取的引腳,通過bsp_io_level_t來獲取當(dāng)前GPIO的狀態(tài)。
e_bsp_io_level枚舉
/* IOPORT 實例控制塊 */
typedef enum e_bsp_io_level
{
BSP_IO_LEVEL_LOW = 0, ///< Low
BSP_IO_LEVEL_HIGH ///< High
} bsp_io_level_t;
12.3.2. 主函數(shù)
在while(1)里不斷調(diào)用R_IOPORT_PinRead函數(shù),并判斷其返回值,若返回值表示按鍵按下,則LED燈的點亮,否則LED燈滅掉。
完整代碼如下:
代碼清單 12-4:主函數(shù)
void hal_entry(void)
{
fsp_err_t err; //
err = R_IOPORT_Open(&g_ioport_ctrl, &g_bsp_pin_cfg); //初始化引腳
assert(FSP_SUCCESS == err); //判斷是否初始化成功
bsp_io_level_t Pin_P004; //定義獲取函數(shù)的結(jié)構(gòu)體
while(1)
{
R_IOPORT_PinRead(&g_ioport_ctrl,BSP_IO_PORT_00_PIN_04, &Pin_P004); //運行函數(shù)并把獲取的數(shù)據(jù)賦值結(jié)構(gòu)體
if(Pin_P004 == BSP_IO_LEVEL_LOW){ //判斷按鍵有沒有按下
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_HIGH);//點亮LED
}else if(Pin_P004 == BSP_IO_LEVEL_HIGH){ //判斷按鍵有沒有松開
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW); //關(guān)閉LED
}
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
注解
使用這種方式來獲取IO口的狀態(tài)相對會比較復(fù)雜,下面將介紹一種新的寫法來簡化這一個過程,可以使程序看起來更簡單,讓我們開發(fā)起來更加的順暢。
12.4. 封裝 Key 設(shè)備驅(qū)動程序
R_key_read函數(shù)
/*
* 按鍵讀取函數(shù) 輸入引腳 返回當(dāng)前引腳的狀態(tài)
* */
uint32_t R_key_read(bsp_io_port_pin_t key)
{
bsp_io_level_t state;
R_IOPORT_PinRead(&g_ioport_ctrl, key, &state);
return state;
}
我們這里對R_IOPORT_PinRead進(jìn)行一次封裝,為什么要加這一層封裝呢,因為在對R_IOPORT_PinRead編程中多了一個指向型bsp_io_port_pin_t枚舉類型數(shù)據(jù), 每當(dāng)程序中增加一個需要讀取的IO口時我們就需要增加一個枚舉類型數(shù)據(jù),這樣大大增加了我們程序的冗余程度。 我們封裝的過程中通過輸入當(dāng)前的引腳,然后return返回當(dāng)前的狀態(tài),這樣簡化了我們進(jìn)行程序的編寫。
Key_Scan函數(shù)
/*
* 按鍵掃描函數(shù)判斷你的手是否松開
*/
uint32_t Key_Scan(bsp_io_port_pin_t key)
{
if(R_key_read(key) == BSP_IO_LEVEL_HIGH)
{
return KEY_OFF;
}
else
{
do //等待按鍵釋放
{
R_key_read(key);
} while (BSP_IO_LEVEL_LOW == R_key_read(key));
}
return KEY_ON;
}
這是一個對R_IOPORT_PinRead函數(shù)的使用案例,當(dāng)按下按鍵的時候單片機會檢測手是否松開當(dāng)手離開的時候返回KEY_ON數(shù)值,當(dāng)按鍵沒有被按下的時候Key_Scan函數(shù)則返回KEY_OFF的數(shù)值, 下面是一個Key_Scan函數(shù)的實踐案列。
主函數(shù)hal_entry()
void hal_entry(void)
{
while(1)
{
if( Key_Scan(KEY_SW2_PIN) == KEY_ON ) //掃描判斷按鍵
{
LED1_ON; //宏定義LED開
LED2_ON;
LED3_ON;
}
if( Key_Scan(KEY_SW3_PIN) == KEY_ON )
{
LED1_OFF; //宏定義LED關(guān)
LED2_OFF;
LED3_OFF;
}
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
在 “hal_entry.c” 文件中添加對頭文件 “bsp_key.h” 的包含, 然后將 hal_entry 入口函數(shù)的內(nèi)容改為如上所示。
12.5. 下載驗證
把編譯好的程序下載到開發(fā)板并復(fù)位,按下按鍵可以控制LED燈亮滅。
-
電路圖
+關(guān)注
關(guān)注
10340文章
10720瀏覽量
530195 -
led燈
+關(guān)注
關(guān)注
22文章
1592瀏覽量
107950 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5032瀏覽量
97371 -
GPIO
+關(guān)注
關(guān)注
16文章
1204瀏覽量
52051 -
按鍵檢測
+關(guān)注
關(guān)注
0文章
23瀏覽量
4834
發(fā)布評論請先 登錄
相關(guān)推薦
評論