RT-Thread Pin设备驱动API应用介绍
概要
本文主要涉及Pin驅動相關的API接口的簡要介紹及使用示例,有興趣深入了解Pin驅動程序框架可參考:RT-Thread pin設備驅動代碼結構剖析
PIN設備的操作方法
應用程序通過RT-Thred提供的pin設備管理接口來操作GPIO,函數接口如下表:
| rt_pin_mode() | 設置引腳模式 |
| rt_pin_write() | 設置引腳電平 |
| rt_pin_read() | 讀取引腳電平 |
| rt_pin_attach_irq() | 綁定引腳中斷回調函數 |
| rt_pin_detach_irq() | 脫離引腳中斷回調函數 |
| rt_pin_irq_enable() | 使能引腳中斷 |
1. 設置引腳模式
在使用引腳之前需要先設定引腳的工作模式,通過下面函數完成:
void rt_pin_mode(rt_base_t pin, rt_base_t mode);
| pin | 引腳編號 |
| mode | 引腳工作模式 |
| 返回 | 描述 |
| 無 | 無 |
1.1 參數 pin
RT-Thread 提供的引腳編號需要和芯片的引腳號區分開來,它們并不是同一個概念,引腳編號由 PIN 設備驅動程序定義,和具體的芯片相關。有2種方式可以獲取引腳編號:使用宏定義或者查看PIN 驅動文件。
如果使用 rt-thread/bsp/stm32 目錄下的 BSP 則可以使用下面的宏獲取引腳編號:
GET_PIN(port, pin)
獲取引腳號為 PF9 的 LED0 對應的引腳編號的示例代碼如下所示:
#define LED0_PIN GET_PIN(F, 9)
如果使用其他 BSP 則需要查看 PIN 驅動代碼 drv_gpio.c 文件確認引腳編號。此文件里有一個數組存放了每個 PIN 腳對應的編號信息,如下所示:
static const rt_uint16_t pins[] = {__STM32_PIN_DEFAULT,__STM32_PIN_DEFAULT,__STM32_PIN(2, A, 15),__STM32_PIN(3, B, 5),__STM32_PIN(4, B, 8),__STM32_PIN_DEFAULT,__STM32_PIN_DEFAULT,__STM32_PIN_DEFAULT,__STM32_PIN(8, A, 14),__STM32_PIN(9, B, 6),... ... }以__STM32_PIN(2, A, 15)為例,2 為 RT-Thread 使用的引腳編號,A 為端口號,15 為引腳號,所以 PA15 對應的引腳編號為 2。
1.2 參數 mode
RT-Thread目前支持的模式有下面5種:
#define PIN_MODE_OUTPUT 0x00 /*推挽輸出*/ #define PIN_MODE_INPUT 0x01 /*浮空輸入*/ #define PIN_MODE_INPUT_PULLUP 0x02 /*上拉輸入*/ #define PIN_MODE_INPUT_PULLDOWN 0x03 /*下拉輸出*/ #define PIN_MODE_OUTPUT_OD 0x04 /*開漏輸出*/1.3 示例
使用示例如下所示:
#define BEEP_PIN_NUM GET_PIN(B, 0) /* PB0 *//* 蜂鳴器引腳為輸出模式 */ rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);2. 設置引腳電平
設置引腳輸出電平的函數如下所示:
void rt_pin_write(rt_base_t pin, rt_base_t value);
| pin | 引腳編號 |
| value | 電平邏輯值,可取 2 種宏定義值之一:PIN_LOW 低電平,PIN_HIGH 高電平 |
使用示例如下所示:
#define BEEP_PIN_NUM 35 /* PB0 *//* 蜂鳴器引腳為輸出模式 */ rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT); /* 設置低電平 */ rt_pin_write(BEEP_PIN_NUM, PIN_LOW);3. 讀取引腳電平
讀取引腳電平的函數如下所示:
int rt_pin_read(rt_base_t pin);
| pin | 引腳編號 |
| 返回 | —— |
| PIN_LOW | 低電平 |
| PIN_HIGH | 高電平 |
使用示例如下所示:
#define BEEP_PIN_NUM 35 /* PB0 */ int status;/* 蜂鳴器引腳為輸出模式 */ rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT); /* 設置低電平 */ rt_pin_write(BEEP_PIN_NUM, PIN_LOW);status = rt_pin_read(BEEP_PIN_NUM);4. 綁定引腳中斷回調函數
若要使用到引腳的中斷功能,可以使用如下函數將某個引腳配置為某種中斷觸發模式并綁定一個中斷回調函數到對應引腳,當引腳中斷發生時,就會執行回調函數:
rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args);
| pin | 引腳編號 |
| mode | 中斷觸發模式 |
| hdr | 中斷回調函數,用戶需要自行定義這個函數 |
| args | 中斷回調函數的參數,不需要時設置為 RT_NULL |
| 返回 | —— |
| RT_EOK | 綁定成功 |
| 錯誤碼 | 綁定失敗 |
中斷觸發模式 mode 可取如下 5 種宏定義值之一:
#define PIN_IRQ_MODE_RISING 0x00 /* 上升沿觸發 */ #define PIN_IRQ_MODE_FALLING 0x01 /* 下降沿觸發 */ #define PIN_IRQ_MODE_RISING_FALLING 0x02 /* 邊沿觸發(上升沿和下降沿都觸發)*/ #define PIN_IRQ_MODE_HIGH_LEVEL 0x03 /* 高電平觸發 */ #define PIN_IRQ_MODE_LOW_LEVEL 0x04 /* 低電平觸發 */使用示例如下所示:
#define KEY0_PIN_NUM 55 /* PD8 */ /* 中斷回調函數 */ void beep_on(void *args) {rt_kprintf("turn on beep!\n");rt_pin_write(BEEP_PIN_NUM, PIN_HIGH); } static void pin_beep_sample(void) {/* 按鍵0引腳為輸入模式 */rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);/* 綁定中斷,下降沿模式,回調函數名為beep_on */rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL); }5. 使能引腳中斷
綁定好引腳中斷回調函數后使用下面的函數使能引腳中斷:
rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled);
| pin | 引腳編號 |
| enabled | 狀態,可取 2 種值之一:PIN_IRQ_ENABLE(開啟),PIN_IRQ_DISABLE(關閉) |
| 返回 | —— |
| RT_EOK | 使能成功 |
| 錯誤碼 | 使能失敗 |
使用示例如下所示:
#define KEY0_PIN_NUM 55 /* PD8 */ /* 中斷回調函數 */ void beep_on(void *args) {rt_kprintf("turn on beep!\n");rt_pin_write(BEEP_PIN_NUM, PIN_HIGH); } static void pin_beep_sample(void) {/* 按鍵0引腳為輸入模式 */rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);/* 綁定中斷,下降沿模式,回調函數名為beep_on */rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);/* 使能中斷 */rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE); }6. 脫離引腳中斷回調函數
可以使用如下函數脫離引腳中斷回調函數:
rt_err_t rt_pin_detach_irq(rt_int32_t pin);
| pin | 引腳編號 |
| 返回 | —— |
| RT_EOK | 脫離成功 |
| 錯誤碼 | 脫離失敗 |
引腳脫離了中斷回調函數以后,中斷并沒有關閉,還可以調用綁定中斷回調函數再次綁定其他回調函數。
#define KEY0_PIN_NUM 55 /* PD8 */ /* 中斷回調函數 */ void beep_on(void *args) {rt_kprintf("turn on beep!\n");rt_pin_write(BEEP_PIN_NUM, PIN_HIGH); } static void pin_beep_sample(void) {/* 按鍵0引腳為輸入模式 */rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);/* 綁定中斷,下降沿模式,回調函數名為beep_on */rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);/* 使能中斷 */rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE);/* 脫離中斷回調函數 */rt_pin_detach_irq(KEY0_PIN_NUM); }注意:脫離中斷回調函數后,中斷并沒有關掉,只是不再執行被脫離的回調函數
PIN 設備使用示例
PIN 設備的具體使用方式可以參考如下示例代碼,示例代碼的主要步驟如下:
設置蜂鳴器對應引腳為輸出模式,并給一個默認的低電平狀態。
設置按鍵 0 和 按鍵1 對應引腳為輸入模式,然后綁定中斷回調函數并使能中斷。
按下按鍵 0 蜂鳴器開始響,按下按鍵 1 蜂鳴器停止響。
/** 程序清單:這是一個 PIN 設備使用例程* 例程導出了 pin_beep_sample 命令到控制終端* 命令調用格式:pin_beep_sample* 程序功能:通過按鍵控制蜂鳴器對應引腳的電平狀態控制蜂鳴器 */#include <rtthread.h> #include <rtdevice.h>/* 引腳編號,通過查看設備驅動文件drv_gpio.c確定 */ #ifndef BEEP_PIN_NUM#define BEEP_PIN_NUM 35 /* PB0 */ #endif #ifndef KEY0_PIN_NUM#define KEY0_PIN_NUM 55 /* PD8 */ #endif #ifndef KEY1_PIN_NUM#define KEY1_PIN_NUM 56 /* PD9 */ #endifvoid beep_on(void *args) {rt_kprintf("turn on beep!\n");rt_pin_write(BEEP_PIN_NUM, PIN_HIGH); }void beep_off(void *args) {rt_kprintf("turn off beep!\n");rt_pin_write(BEEP_PIN_NUM, PIN_LOW); }static void pin_beep_sample(void) {/* 蜂鳴器引腳為輸出模式 */rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);/* 默認低電平 */rt_pin_write(BEEP_PIN_NUM, PIN_LOW);/* 按鍵0引腳為輸入模式 */rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);/* 綁定中斷,下降沿模式,回調函數名為beep_on */rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);/* 使能中斷 */rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE);/* 按鍵1引腳為輸入模式 */rt_pin_mode(KEY1_PIN_NUM, PIN_MODE_INPUT_PULLUP);/* 綁定中斷,下降沿模式,回調函數名為beep_off */rt_pin_attach_irq(KEY1_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_off, RT_NULL);/* 使能中斷 */rt_pin_irq_enable(KEY1_PIN_NUM, PIN_IRQ_ENABLE); } /* 導出到 msh 命令列表中 */ MSH_CMD_EXPORT(pin_beep_sample, pin beep sample);總結
以上是生活随笔為你收集整理的RT-Thread Pin设备驱动API应用介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详解C语言中 # 和 ## 的用法
- 下一篇: C语言string.h文件函数汇总详解