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