日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2.1 rtthread pin设备详解

發布時間:2024/3/26 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2.1 rtthread pin设备详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

1、PIN設備說明 ? ? ? ?

2、PIN設備的初始化及注冊

3、PIN設備的操作

3.1 獲取管腳編號的實現

3.1.1使用API

3.1.2使用宏定義

3.1.3查看驅動文件

3.2?設置引腳模式

3.3?輸出控制

3.4?輸入獲取

3.5?中斷回調的綁定

3.6?中斷回調的解綁

3.7 中斷的使能和禁用

3.8?中斷回調函數的實現


1、PIN設備說明 ? ? ? ?

????????rtthread通過pin.c和pin.h兩個文件進行pin設備的管理。通過pin.h中的結構體rt_device_pin進行pin設備的定義,pin設備繼承自設備基類rt_device,rt_device繼承自rt_object基類,繼承關系如下

? ? ? ??PIN設備通過結構體的定義實現了對rt_device設備基類的繼承,結構體中的成員rt_pin_ops來實現pin設備的具體操作實現。

struct rt_device_pin {struct rt_device parent;const struct rt_pin_ops *ops; }; struct rt_pin_ops {void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value);int (*pin_read)(struct rt_device *device, rt_base_t pin);rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_int32_t pin,rt_uint32_t mode, void (*hdr)(void *args), void *args);rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin);rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled);rt_base_t (*pin_get)(const char *name); };

2、PIN設備的初始化及注冊

????????

? ? ? ? ?啟動階段rtthread會根據是否進行了RT_USING_PIN定義,在hw_board_init函數中進行pin設備的初始化,在rt_hw-pin_init函數中首先進行了時鐘的初始化,最終調用函數rt_device_pin_register來實現STM32的IO和pin設備的關聯及設備的掛載。

????????

/* 進行PIN設備的結構體定義 */ static struct rt_device_pin _hw_pin; int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data) {/*PIN設備的父設備,設備基類的類型進行定義,定義為RT_Device_Class_Miscellaneous,雜類*/_hw_pin.parent.type = RT_Device_Class_Miscellaneous;/*收發回調函數為空*/_hw_pin.parent.rx_indicate = RT_NULL;_hw_pin.parent.tx_complete = RT_NULL;/*設備基類的初始化燈相關函數指針賦值。*/ #ifdef RT_USING_DEVICE_OPS_hw_pin.parent.ops = &pin_ops; #else_hw_pin.parent.init = RT_NULL;_hw_pin.parent.open = RT_NULL;_hw_pin.parent.close = RT_NULL;_hw_pin.parent.read = _pin_read;_hw_pin.parent.write = _pin_write;_hw_pin.parent.control = _pin_control; #endif/*PIN設備ops,即STM32的具體實現方式進行賦值。*/_hw_pin.ops = ops;_hw_pin.parent.user_data = user_data;/*設備注冊*//* register a character device */rt_device_register(&_hw_pin.parent, name, RT_DEVICE_FLAG_RDWR);return 0; }

?????????rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL)中參數_stm32_pin_ops為rt_pin_ops,具體定義內容如下,實現了GPIO的模式配置,輸入輸出控制,中斷控制和管腳查找等功能在STM32下得具體實現方式函數指針的定義。

const static struct rt_pin_ops _stm32_pin_ops = {stm32_pin_mode,stm32_pin_write,stm32_pin_read,stm32_pin_attach_irq,stm32_pin_dettach_irq,stm32_pin_irq_enable,stm32_pin_get, };

3、PIN設備的操作

? ? ? ? PIN設備對外提供如下接口函數

函數描述
rt_pin_get()獲取引腳編號
rt_pin_mode()設置引腳模式
rt_pin_write()設置引腳電平
rt_pin_read()讀取引腳電平
rt_pin_attach_irq()綁定引腳中斷回調函數
rt_pin_irq_enable()使能引腳中斷
rt_pin_detach_irq()脫離引腳中斷回調函數

3.1 獲取管腳編號的實現

?????????RT-Thread 提供的引腳編號需要和芯片的引腳號區分開來,它們并不是同一個概念,引腳編號由 PIN 設備驅動程序定義,和具體的芯片相關。管腳序號是后續其他輸入輸出中斷函數實現的一個重要參數。STM32的驅動中對GPIOA(0-15)到GPIOx(0-15)進行了按順序的編號操作。

? ? ? ? RTT官方文檔描述針對STM32的GPIO驅動drv_gpio.c中針對管腳編號提供了三種方式進行實現:

3.1.1使用API

? ? ? ? 此處需要注意

? ? ? ? 舊版本的drv_gpio.c文件在_stm32_pin_ops?中并沒有定義函數stm32_pin_get,的實現,所以舊版本的驅動無法使用API獲取到管腳編號。新建工程時,系統使用的驅動任為舊版本的

????????gpio驅動所以需要更新,可以從gitee進行文件下載bsp/stm32/libraries/HAL_Drivers/drv_gpio.c · RT-Thread/rt-thread - Gitee.com。具體實現方式函數如下

/*根據輸入字符串的端口號A-Z,轉換為數值0-25根據輸入字符串的管腳號0-15,轉換為數值0-15將兩者結合端口號為高位,管腳號為地位 */ static rt_base_t stm32_pin_get(const char *name) {rt_base_t pin = 0;int hw_port_num, hw_pin_num = 0;int i, name_len;name_len = rt_strlen(name); if ((name_len < 4) || (name_len >= 6)) //進行字符串長度驗證PA.0 PA.15 最短4,最長5{return -RT_EINVAL;}if ((name[0] != 'P') || (name[2] != '.')) //字符串第一個必須為P 第三個必須為.{return -RT_EINVAL;}if ((name[1] >= 'A') && (name[1] <= 'Z')) //端口范圍在A-Z{hw_port_num = (int)(name[1] - 'A'); //端口編號計算,A-Z轉換為0-25}else{return -RT_EINVAL;}for (i = 3; i < name_len; i++) //根據字符串的第4個進行編號轉換PA.0=0 PA.15 = 15{hw_pin_num *= 10;hw_pin_num += name[i] - '0';}pin = PIN_NUM(hw_port_num, hw_pin_num); //進行最后引腳編號的處理return pin; }

? ??最終調用宏定義如下來進行引腳編號的獲取

#define PIN_NUM(port, no) (((((port) & 0xFu) << 4) | ((no) & 0xFu)))

測算結果如下表,后續IO以此類推

nameportnoresultnameportnoresult
PA.0000PB.01016
PA.1011PB.11117
PA.2022PB.21218
PA.3033PB.31319
PA.4044PB.41420
PA.5055PB.51521
PA.6066PB.61622
PA.7077PB.71723
PA.8088PB.81824
PA.9099PB.91925
PA.1001010PB.1011026
PA.1101111PB.1111127
PA.1201212PB.1211228
PA.1301313PB.1311329
PA.1401414PB.1411430
PA.1501515PB.1511531

3.1.2使用宏定義

? ? ? ? 針對STM32,RTT提供了宏定義GET_PIN來進行管腳編號的獲取,再未更新drv_gpio驅動前,該定義再drv_common.h中進行了定義,更新驅動后在drv_gpio.h中也進行了定義,兩者定義相同。內容如下。

//drv_common.h中的宏定義 #define __STM32_PORT(port) GPIO##port##_BASE #define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN)//drv_gpio.h中的宏定義 #define __STM32_PORT(port) GPIO##port##_BASE#if defined(SOC_SERIES_STM32MP1) #define GET_PIN(PORTx,PIN) (GPIO##PORTx == GPIOZ) ? (176 + PIN) : ((rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x1000UL) )) + PIN)) #else #define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN) #endif

????????如上圖,對GET_PIN宏定義進行了重復定義,可以看出drv_gpio.h中對宏定義進行了預編譯,包含了STM32MP1的支持。

? ? ? ? 全局搜索GET_PIN的使用情況如下

? ? ? ? ?board.h、drv_gpio.h和drv_usart.c中均進行了drv_common.h的包含。僅在drv_gpio.c文件中進行了drv_gpio.h的包含。所以我們可以將drv_gpio.h中關于GET_PIN的相關宏定義進行刪除(不涉及STM32MP1的使用)。來保證宏定義的唯一性。

? ? ? ? 宏定義根據參數portx進行管腳端口的地址獲取,將A-Z分別轉換為0-25。參數PIN為端口下得具體IO。最終轉換結果為端口序號*16+IO編號。與API轉換結果相同。

宏定義PORTx16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )PINresult
GET_PIN(A, 0)GPIOA_BASED3_AHB1PERIPH_BASE + 0x0000UL000
GET_PIN(A, 1)GPIOA_BASED3_AHB1PERIPH_BASE + 0x0000UL000
GET_PIN(A, 2)GPIOA_BASED3_AHB1PERIPH_BASE + 0x0000UL000
GET_PIN(A, 3)GPIOA_BASED3_AHB1PERIPH_BASE + 0x0000UL000
GET_PIN(B, 0)GPIOB_BASED3_AHB1PERIPH_BASE + 0x0400UL1016
GET_PIN(B, 1)GPIOB_BASED3_AHB1PERIPH_BASE + 0x0400UL1117
GET_PIN(B, 2)GPIOB_BASED3_AHB1PERIPH_BASE + 0x0400UL1218

3.1.3查看驅動文件

? ? ? ? 舊版本的drv_gpio驅動提供了管腳與編號的對應定義,可以通過查看直接進行管腳序號的定義。

? ? ? ? ?新版本驅動更新了管腳編號識別邏輯,不在提供該驅動文件查看的方式。

3.2?設置引腳模式

? ? ? ? rtt通過rt_pin_mode進行管腳模式的配置

void rt_pin_mode(rt_base_t pin, rt_base_t mode) {RT_ASSERT(_hw_pin.ops != RT_NULL);_hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode); }

? ? ? ? 最終調用的函數為pin設備類的ops下的pin_mode函數,在初始階段該函數指針設置為了stm32_pin_mode,具體實現如下

/*1、管腳序號的識別通過宏定義#define PIN_STPIN(pin) ((uint16_t)(1u << PIN_NO(pin))) 轉換為位信息#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu)) 轉換為0-15來進行序號識別 2、端口識別#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))來進行引腳編號到端口結構體地址的轉換。3、最終調用庫函數進行GPIO的配置。 */ static void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) {GPIO_InitTypeDef GPIO_InitStruct;//驗證端口是否大于最大端口,是否合法if (PIN_PORT(pin) >= PIN_STPORT_MAX){return;}//配置端口IO為默認推挽輸出,不上下拉,輸出速度HIGHGPIO_InitStruct.Pin = PIN_STPIN(pin);GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;//根據實際傳入參數的模式來進行配置if (mode == PIN_MODE_OUTPUT){/* output setting */GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;}else if (mode == PIN_MODE_INPUT){/* input setting: not pull. */GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;}else if (mode == PIN_MODE_INPUT_PULLUP){/* input setting: pull up. */GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;}else if (mode == PIN_MODE_INPUT_PULLDOWN){/* input setting: pull down. */GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLDOWN;}else if (mode == PIN_MODE_OUTPUT_OD){/* output setting: od. */GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;}//調用庫函數進行初始化HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct); }

3.3?輸出控制

? ? ? ? rtt通過rt_pin_write進行管腳模式的配置。

void rt_pin_write(rt_base_t pin, rt_base_t value) {RT_ASSERT(_hw_pin.ops != RT_NULL);_hw_pin.ops->pin_write(&_hw_pin.parent, pin, value); }

????????最終調用的函數為pin設備類的ops下的pin_write函數,在初始階段該函數指針設置為了stm32_pin_write,具體實現如下

/*1、管腳序號的識別通過宏定義#define PIN_STPIN(pin) ((uint16_t)(1u << PIN_NO(pin))) 轉換為位信息#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu)) 轉換為0-15來進行序號識別 2、端口識別#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))來進行引腳編號到端口結構體地址的轉換。3、最終調用庫函數進行GPIO的配置。 */ static void stm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) {GPIO_TypeDef *gpio_port;uint16_t gpio_pin;if (PIN_PORT(pin) < PIN_STPORT_MAX){//獲取端口gpio_port = PIN_STPORT(pin);//獲取IO編號gpio_pin = PIN_STPIN(pin);//庫函數輸出HAL_GPIO_WritePin(gpio_port, gpio_pin, (GPIO_PinState)value);} }

3.4?輸入獲取

? ? ? ? rtt通過rt_pin_read進行管腳模式的配置。

int rt_pin_read(rt_base_t pin) {RT_ASSERT(_hw_pin.ops != RT_NULL);return _hw_pin.ops->pin_read(&_hw_pin.parent, pin); }

????????最終調用的函數為pin設備類的ops下的pin_read函數,在初始階段該函數指針設置為了stm32_pin_read,具體實現如下

/*1、管腳序號的識別通過宏定義#define PIN_STPIN(pin) ((uint16_t)(1u << PIN_NO(pin))) 轉換為位信息#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu)) 轉換為0-15來進行序號識別 2、端口識別#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))來進行引腳編號到端口結構體地址的轉換。3、最終調用庫函數進行GPIO的配置。 */ static int stm32_pin_read(rt_device_t dev, rt_base_t pin) {GPIO_TypeDef *gpio_port;uint16_t gpio_pin;int value = PIN_LOW;if (PIN_PORT(pin) < PIN_STPORT_MAX){gpio_port = PIN_STPORT(pin);gpio_pin = PIN_STPIN(pin);value = HAL_GPIO_ReadPin(gpio_port, gpio_pin);}return value; }

3.5?中斷回調的綁定

? ????????rtt通過rt_pin_attach_irq進行中斷回調的綁定。

rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,void (*hdr)(void *args), void *args) {RT_ASSERT(_hw_pin.ops != RT_NULL);if(_hw_pin.ops->pin_attach_irq){return _hw_pin.ops->pin_attach_irq(&_hw_pin.parent, pin, mode, hdr, args);}return -RT_ENOSYS; }

????????最終調用的函數為pin設備類的ops下的pin_attach_irq函數,在初始階段該函數指針設置為了stm32_pin_attach_irq,具體實現如下

/*該函數不進行底層STM32的外部中斷的實際操作。進行了pin設備的中斷相關結構體賦值。 */ static rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) {rt_base_t level;rt_int32_t irqindex = -1;//識別端口號是否正確if (PIN_PORT(pin) >= PIN_STPORT_MAX){return -RT_ENOSYS;}/*進行中斷序號的識別1、通過管腳序號進行了中斷序號的識別,首先通過PIN_STDPIN進行了位的轉換2、通過函數bit2bitno實現了位序號的識別。3、實際可以通過PIN_NO來替代上述流程來進行識別*/irqindex = bit2bitno(PIN_STPIN(pin));/*判斷中斷序號是否合法*/if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)){return RT_ENOSYS;}/*進行pin設備的中斷模式和回調函數的賦值*/level = rt_hw_interrupt_disable();if (pin_irq_hdr_tab[irqindex].pin == pin &&pin_irq_hdr_tab[irqindex].hdr == hdr &&pin_irq_hdr_tab[irqindex].mode == mode &&pin_irq_hdr_tab[irqindex].args == args){rt_hw_interrupt_enable(level);return RT_EOK;}if (pin_irq_hdr_tab[irqindex].pin != -1){rt_hw_interrupt_enable(level);return RT_EBUSY;}pin_irq_hdr_tab[irqindex].pin = pin;pin_irq_hdr_tab[irqindex].hdr = hdr;pin_irq_hdr_tab[irqindex].mode = mode;pin_irq_hdr_tab[irqindex].args = args;rt_hw_interrupt_enable(level);return RT_EOK; }

3.6?中斷回調的解綁

? ????????rtt通過rt_pin_detach_irq進行管腳模式的配置。

rt_err_t rt_pin_detach_irq(rt_int32_t pin) {RT_ASSERT(_hw_pin.ops != RT_NULL);if(_hw_pin.ops->pin_detach_irq){return _hw_pin.ops->pin_detach_irq(&_hw_pin.parent, pin);}return -RT_ENOSYS; }

????????最終調用的函數為pin設備類的ops下的pin_detach_irq函數,在初始階段該函數指針設置為了stm32_pin_dettach_irq,具體實現如下

static rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin) {rt_base_t level;rt_int32_t irqindex = -1;//識別輸入端口是否合法if (PIN_PORT(pin) >= PIN_STPORT_MAX){return -RT_ENOSYS;}/*進行中斷序號的識別1、通過管腳序號進行了中斷序號的識別,首先通過PIN_STDPIN進行了位的轉換2、通過函數bit2bitno實現了位序號的識別。3、實際可以通過PIN_NO來替代上述流程來進行識別*/irqindex = bit2bitno(PIN_STPIN(pin));/*判斷中斷序號是否合法*/if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)){return RT_ENOSYS;}/*中斷模式和中斷管腳回調函數的復位*/level = rt_hw_interrupt_disable();if (pin_irq_hdr_tab[irqindex].pin == -1){rt_hw_interrupt_enable(level);return RT_EOK;}pin_irq_hdr_tab[irqindex].pin = -1;pin_irq_hdr_tab[irqindex].hdr = RT_NULL;pin_irq_hdr_tab[irqindex].mode = 0;pin_irq_hdr_tab[irqindex].args = RT_NULL;rt_hw_interrupt_enable(level);return RT_EOK; }

3.7 中斷的使能和禁用

? ????????rtt通過rt_pin_irq_enable進行管腳模式的配置。

rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled) {RT_ASSERT(_hw_pin.ops != RT_NULL);if(_hw_pin.ops->pin_irq_enable){return _hw_pin.ops->pin_irq_enable(&_hw_pin.parent, pin, enabled);}return -RT_ENOSYS; }

????????最終調用的函數為pin設備類的ops下的pin_irq_enable函數,在初始階段該函數指針設置為了stm32_pin_irq_enable,具體實現如下

static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,rt_uint32_t enabled) {const struct pin_irq_map *irqmap;rt_base_t level;rt_int32_t irqindex = -1;GPIO_InitTypeDef GPIO_InitStruct;//識別IO是否合法if (PIN_PORT(pin) >= PIN_STPORT_MAX){return -RT_ENOSYS;}//使能中斷if (enabled == PIN_IRQ_ENABLE){//獲取判斷中斷序號是否合法irqindex = bit2bitno(PIN_STPIN(pin));if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)){return RT_ENOSYS;}level = rt_hw_interrupt_disable();if (pin_irq_hdr_tab[irqindex].pin == -1){rt_hw_interrupt_enable(level);return RT_ENOSYS;}//查表獲取中斷序號對應的內容irqmap = &pin_irq_map[irqindex];/*中斷具體配置*/GPIO_InitStruct.Pin = PIN_STPIN(pin);GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;switch (pin_irq_hdr_tab[irqindex].mode){case PIN_IRQ_MODE_RISING:GPIO_InitStruct.Pull = GPIO_PULLDOWN;GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;break;case PIN_IRQ_MODE_FALLING:GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;break;case PIN_IRQ_MODE_RISING_FALLING:GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;break;}HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct);//設置中斷優先級HAL_NVIC_SetPriority(irqmap->irqno, 5, 0);HAL_NVIC_EnableIRQ(irqmap->irqno);pin_irq_enable_mask |= irqmap->pinbit;rt_hw_interrupt_enable(level);}//禁用中斷else if (enabled == PIN_IRQ_DISABLE){irqmap = get_pin_irq_map(PIN_STPIN(pin));if (irqmap == RT_NULL){return RT_ENOSYS;}level = rt_hw_interrupt_disable();//復位管腳HAL_GPIO_DeInit(PIN_STPORT(pin), PIN_STPIN(pin));pin_irq_enable_mask &= ~irqmap->pinbit; #if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)if ((irqmap->pinbit >= GPIO_PIN_0) && (irqmap->pinbit <= GPIO_PIN_1)){if (!(pin_irq_enable_mask & (GPIO_PIN_0 | GPIO_PIN_1))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else if ((irqmap->pinbit >= GPIO_PIN_2) && (irqmap->pinbit <= GPIO_PIN_3)){if (!(pin_irq_enable_mask & (GPIO_PIN_2 | GPIO_PIN_3))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else if ((irqmap->pinbit >= GPIO_PIN_4) && (irqmap->pinbit <= GPIO_PIN_15)){if (!(pin_irq_enable_mask & (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 |GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else{HAL_NVIC_DisableIRQ(irqmap->irqno);} #elseif ((irqmap->pinbit >= GPIO_PIN_5) && (irqmap->pinbit <= GPIO_PIN_9)){if (!(pin_irq_enable_mask & (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else if ((irqmap->pinbit >= GPIO_PIN_10) && (irqmap->pinbit <= GPIO_PIN_15)){if (!(pin_irq_enable_mask & (GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else{HAL_NVIC_DisableIRQ(irqmap->irqno);} #endifrt_hw_interrupt_enable(level);}else{return -RT_ENOSYS;}return RT_EOK; }

3.8?中斷回調函數的實現

? ? ? ? 在使能了外部中斷后,STM32的底層在中斷觸發后會進行中斷函數的調用如下函數。

  • EXTI0_IRQHandler~EXTI4_IRQHandler
  • EXTI9_5_IRQHandler
  • EXTI15_10_IRQHandler

? ? ? ? 函數內部調用為HAL_GPIO_EXTI_IRQHandler。在該函數內部最終調用了回調函數HAL_GPIO_EXTI_Callback來進行回調函數的實現。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {pin_irq_hdr(bit2bitno(GPIO_Pin)); }

? ? ? ? 如上回調函數調用了pin_irq_hdr進行了與pin設備所綁定的回調函數的關聯。

rt_inline void pin_irq_hdr(int irqno) {if (pin_irq_hdr_tab[irqno].hdr){pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);} }

總結

以上是生活随笔為你收集整理的2.1 rtthread pin设备详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 男人天堂中文字幕 | 日韩精品在线观看一区二区三区 | 精品欧美一区二区三区在线观看 | 天天射干 | 久草网站 | 久久久久久久久久久97 | 欧美性俱乐部 | 91视频网页 | 日韩啪啪网站 | 黄色在线视频网址 | 欧美亚洲国产一区 | 青青在线观看视频 | 处破女av一区二区 | 亚洲自拍偷拍网 | 欧美激情国产精品 | 96人xxxxxxxxx69| 天天射夜夜爽 | 亚洲 欧美 视频 | 日本后进式猛烈xx00动态图 | 久久久激情网 | 亚洲人成影视 | 亚洲国产精品久久人人爱 | 欧美第一视频 | 久久久社区 | 美女二区| 这里只有精品在线播放 | 精品人妻一区二区三区四区在线 | 久久久久久69 | 精品久久久久中文慕人妻 | 中文字幕精品一区二区三区精品 | 中文字幕观看在线 | 国产永久精品大片wwwapp | 奇米在线 | 欧美日韩伦理片 | 福利视频91 | 亚洲一区二区日本 | www.av色| 国产精品久久久国产盗摄 | 香蕉视频A| 永久免费视频网站直接看 | 91一区二区三区在线 | 在线看污片 | 草草在线观看 | 国模私拍一区二区三区 | 国产精品综合一区二区 | av毛片基地 | 美女被草出水 | 久久激情视频 | 噼里啪啦国语高清 | 永久免费在线观看av | 99啪啪| 国产激情毛片 | 亚洲特级毛片 | 精品国产免费视频 | 亚洲一区二区三区无码久久 | 欧美色99| 国产一区二区欧美 | 久久精品视频3 | 免费黄色片子 | 国产对白刺激视频 | 无码一区二区 | 久久综合久久鬼 | 色噜噜一区二区 | 蜜桃91麻豆精品一二三区 | 在线观看成人免费 | 性生生活大片又黄又 | 国自产拍偷拍精品啪啪一区二区 | 亚洲色欲色欲www在线观看 | 最新毛片网站 | 狠狠视频| 成人精品一区二区三区四区 | 国产精品入口夜色视频大尺度 | 亚洲一区二区三区三州 | 特级西西444www高清大胆 | 日本三级吃奶头添泬 | 91av色| 激情开心成人网 | 亚洲精品成人片在线观看精品字幕 | 欧美三级手机在线观看 | 国色天香网站 | 欧美一区二区久久久 | 久久久久久久久久久久国产 | 97高清国语自产拍 | 久久久永久久久人妻精品麻豆 | 国产免费又黄又爽又色毛 | 亚洲日本黄色 | 国产成人在线观看 | 久久国产精品99久久人人澡 | 最近的中文字幕 | 久久妇女 | 91手机在线| 国产精品九九九九 | 91jk制服白丝超短裙大长腿 | 久久久久一区 | 久久高清免费 | 国产网址 | 中文在线观看免费高清 | 国产自精品| 亚洲av色一区二区三区精品 |