国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

簡單實用的IO輸入輸出框架

GReq_mcu168 ? 來源:硬件攻城獅 ? 作者:硬件攻城獅 ? 2022-06-02 14:12 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

在一個嵌入式系統中,可能存在許多輸入或輸出的IO口,輸入有霍爾傳感器紅外對管等,輸出有LED電源控制開關等。 如果說硬件可以一次成型,那么隨便一份代碼都可以完成IO的配置工作,但研發階段的產品,硬件各種修改是難免的,每一次 IO 的修改,對于底層開發人員來說,可能都是一次挑戰。 因為一旦有某一個 IO 配置錯誤,或者原來的配置沒有修改正確(比如一個 IO 在原來的硬件適配中是輸入,之后的硬件需要修改成輸出),那么你很難查出來這是什么問題,因為這個時候不僅硬件修改了,軟件也修改了,你需要先定位到底是軟件問題還是硬件問題,所以一個好用的 IO 的配置框架就顯得很有必要了。

有道友會說,不如使用 CubeMx 軟件進行開發吧。

1、這個軟件適用于 ST 單片機,以前還能用,現在,除非你家里有礦,不然誰用的起STM32?基本上都國產化了(雖然有些單片機號稱兼容,但到底還是有些差異的)。2、公司原本的代碼就是使用標準庫,只是因為IO 的變化,你就需要把整個庫換掉嗎?時間上允許嗎?你確定修改后不會出現大問題?3、國產化的芯片可沒有所謂的標準庫和HAL庫供你選擇,每一家都有各自的庫,如果你的產品臨時換方案怎么辦?4、HAL 效率問題。今天魚鷹介紹一個簡單實用的框架,可用于快速增加或修改IO配置,甚至修改底層庫。假設有3個 LED 作為輸出、3 個霍爾傳感器作為輸入:輸入配置代碼:
#defineGPIOx_DefGPIO_TypeDef*#define GPIOMode_Def        GPIOMode_TypeDef
typedef struct{    GPIOx_Def       gpio;     uint16_t        msk;    GPIOMode_Def    pull_up_down;     } bsp_input_pin_def; 
#define  _GPIO_PIN_INPUT(id, pull, gpiox, pinx)   [id].gpio = (GPIOx_Def)gpiox, [id].msk = (1 << pinx), [id].pull_up_down = (GPIOMode_Def)pull#define  GPIO_PIN_INPUT(id, pull, gpiox, pinx)    _GPIO_PIN_INPUT(id, pull, gpiox, pinx)
#define bsp_pin_get_port(gpiox)             ((uint16_t)((GPIO_TypeDef *)gpiox)->IDR)#define bsp_pin_get_value(variable,id)      do{ bsp_pin_get_port(bsp_input_pin[id].gpio) & bsp_input_pin[id].msk ? variable |= (1 << id) : 0;} while(0)

#define BSP_GPIO_PUPD_NONE                                          GPIO_Mode_IN_FLOATING#define BSP_GPIO_PUPD_PULLUP                                        GPIO_Mode_IPU#define BSP_GPIO_PUPD_PULLDOWN                                      GPIO_Mode_IPD

typedef enum{    PIN_INPUT_HALL_0 = 0,  // 輸入 IO 定義    PIN_INPUT_HALL_1,       PIN_INPUT_HALL_2,                        PIN_INPUT_MAX}bsp_pin_input_id_def;
static const bsp_input_pin_def  bsp_input_pin [PIN_INPUT_MAX] = {    GPIO_PIN_INPUT(PIN_INPUT_HALL_0,          BSP_GPIO_PUPD_NONE, GPIOA, 0),    GPIO_PIN_INPUT(PIN_INPUT_HALL_1,          BSP_GPIO_PUPD_NONE, GPIOB, 8),        GPIO_PIN_INPUT(PIN_INPUT_HALL_2,          BSP_GPIO_PUPD_NONE, GPIOE, 9),   };
// 單個 IO 初始化函數  void bsp_pin_init_input(GPIOx_Def gpiox, uint32_t msk, GPIOMode_TypeDef pull_up_down){    uint32_t temp;
    assert_param((msk & 0xffff0000) == 0 && gpiox != 0);
    temp = ((uint32_t) gpiox - (uint32_t) GPIOA) / ( (uint32_t) GPIOB - (uint32_t) GPIOA);
    /* enable the led clock */    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA << temp, ENABLE);
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode  = (GPIOMode_Def)pull_up_down;    GPIO_InitStruct.GPIO_Pin   = msk;    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init((GPIO_TypeDef*)gpiox, &GPIO_InitStruct);}
// 所有 IO 初始化void gpio_input_init(){        bsp_input_pin_def  *info;
    info = (bsp_input_pin_def *)&bsp_input_pin;
    for(int i = 0; i < sizeof(bsp_input_pin)/sizeof(bsp_input_pin[0]); i++)    {        bsp_pin_init_input(info->gpio, info->msk, info->pull_up_down);        info++;    }   }

// 最多支持 32 個 IO 輸入uint32_t bsp_input_all(void){    uint32_t temp = 0;
    bsp_pin_get_value(temp, PIN_INPUT_HALL_0);    bsp_pin_get_value(temp, PIN_INPUT_HALL_1);    bsp_pin_get_value(temp, PIN_INPUT_HALL_2);
    return temp;}

// 讀取單個 IO 狀態uint32_t bsp_input_level(bsp_pin_input_id_def id){    return (bsp_pin_get_port(bsp_input_pin[id].gpio) & bsp_input_pin[id].msk) ? 1 : 0;}
typedef enum{    HW_HAL_LEVEL_ACTIVE = 0, // 可直接修改為 0 或 1,另一個枚舉值自動修改為相反值    HW_HAL_LEVEL_NO_ACTIVE = !HW_HAL_LEVEL_ACTIVE,}hw_input_hal_status_def;
typedef struct  {    hw_input_hal_status_def hal_level0;     uint8_t                 hal_level1;    uint8_t                 hal_level2;}bsp_input_status_def;

bsp_input_status_def bsp_input_status;
int main(void){      USRAT_Init(9600);//必須,進入調試模式后點擊全速運行
    gpio_input_init();
    while(1)    {        uint32_t temp = bsp_input_all();
        bsp_input_status.hal_level0 = (hw_input_hal_status_def)((temp >> PIN_INPUT_HALL_0) & 1);        bsp_input_status.hal_level1 = ((temp >> PIN_INPUT_HALL_1) & 1);        bsp_input_status.hal_level2 = ((temp >> PIN_INPUT_HALL_2) & 1);    }                      }
調試的時候,我們可以很方便的查看每個 IO 的狀態是怎樣的,而不用管 0 或 1 到底代表什么意思:52583768-e23a-11ec-ba43-dac502259ad0.png輸出配置代碼:
#define GPIOx_Def           GPIO_TypeDef*#define GPIOMode_Def        GPIOMode_TypeDef
typedef struct{    GPIOx_Def  gpio;     uint32_t   msk;     uint32_t   init_value; } bsp_output_pin_def; 
#define  _GPIO_PIN_OUT(id, gpiox, pinx, init)                        [id].gpio = gpiox, [id].msk = (1 << pinx), [id].init_value = init#define  GPIO_PIN_OUT(id, gpiox, pinx, init)                         _GPIO_PIN_OUT(id, gpiox, pinx, init)
#define _bsp_pin_output_set(gpiox, pin)                              (gpiox)->BSRR = pin#define bsp_pin_output_set(gpiox, pin)                               _bsp_pin_output_set(gpiox, pin)
#define _bsp_pin_output_clr(gpiox, pin)                              (gpiox)->BRR = pin#define bsp_pin_output_clr(gpiox, pin)                               _bsp_pin_output_clr(gpiox, pin)
typedef enum{    PIN_OUTPUT_LED_G,    PIN_OUTPUT_LED_R,      PIN_OUTPUT_LED_B,    PIN_OUTPUT_MAX}bsp_pin_output_id_def;
static const bsp_output_pin_def  bsp_output_pin [PIN_OUTPUT_MAX] = {    GPIO_PIN_OUT(PIN_OUTPUT_LED_G,          GPIOA,  0, 0),    GPIO_PIN_OUT(PIN_OUTPUT_LED_R,          GPIOF, 15, 0),    GPIO_PIN_OUT(PIN_OUTPUT_LED_B,          GPIOD, 10, 0),};

void bsp_pin_init_output(GPIOx_Def gpiox, uint32_t msk, uint32_t init){    uint32_t temp;
    assert_param((msk & 0xffff0000) == 0 && gpiox != 0);
    temp = ((uint32_t) gpiox - (uint32_t) GPIOA) / ( (uint32_t) GPIOB - (uint32_t) GPIOA);
    /* enable the led clock */    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA << temp, ENABLE);
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode  = (GPIOMode_Def)GPIO_Mode_Out_PP;    GPIO_InitStruct.GPIO_Pin   = msk;    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init((GPIO_TypeDef*)gpiox, &GPIO_InitStruct);
    if(init == 0)    {        bsp_pin_output_clr(gpiox, msk);    }    else    {        bsp_pin_output_set(gpiox, msk);    }}
void bsp_output_init(){    bsp_output_pin_def  *info;
    info = (bsp_output_pin_def *)&bsp_output_pin;    for(int i = 0; i < sizeof(bsp_output_pin)/sizeof(bsp_output_pin[0]); i++)    {        bsp_pin_init_output(info->gpio, info->msk, info->init_value);        info++;    }}
void bsp_output(bsp_pin_output_id_def id, uint32_t value){    assert_param(id < PIN_OUTPUT_MAX);
    if(value == 0)    {        bsp_pin_output_clr(bsp_output_pin[id].gpio, bsp_output_pin[id].msk);    }    else    {        bsp_pin_output_set(bsp_output_pin[id].gpio, bsp_output_pin[id].msk);    }}
int main(void){      USRAT_Init(9600);//必須,進入調試模式后點擊全速運行
    bsp_output_init();
    while(1)    {        bsp_output(PIN_OUTPUT_LED_G, 1);        bsp_output(PIN_OUTPUT_LED_B, 0);        bsp_output(PIN_OUTPUT_LED_R, 1);}}
這個框架有啥好處呢?
1、自動完成 GPIO 的時鐘初始化工作,也就是說你只需要修改引腳即可,不必關心時鐘配置,但對于特殊引腳(比如PB3),還是得另外配置才行。2、應用和底層具體 IO 分離,這樣一旦修改了 IO,應用代碼不需要進行任何修改。3、增加或刪減 IO 變得很簡單,增加 IO時,首先加入對應枚舉,然后就可以添加對應的 IO 了。刪除 IO時,只要屏蔽對應枚舉值和引腳即可。4、參數檢查功能, IO 刪除時,因為屏蔽了對應的枚舉,所以編譯時可以幫你發現問題,而增加 IO 時,它可以幫你在運行時檢查該 IO是否進行配置了,可以防止因為失誤導致的問題。52a3361e-e23a-11ec-ba43-dac502259ad0.png5、更改庫時可以很方便,只需要修改對應的宏即可,目前可以順利在 GD32 和 STM32 庫進行快速更換。6、對于輸入 IO 而言,可以方便的修改有效和無效狀態,防止硬件修改有效電平。對于輸出 IO 而言,可以設定初始 IO 電平狀態。7、代碼簡單高效,盡可能的復用代碼,增加一個 IO 只需要很少的空間。8、缺點就是,只對同種配置的 IO 可以這樣用。 好好看看,或許能學到不少技巧哦。 審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式系統
    +關注

    關注

    41

    文章

    3747

    瀏覽量

    133639
  • 霍爾傳感器
    +關注

    關注

    28

    文章

    797

    瀏覽量

    66241
  • STM32
    +關注

    關注

    2309

    文章

    11162

    瀏覽量

    373464

原文標題:簡單實用IO輸入輸出框架

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    精密軌到軌輸入輸出運算放大器OP484:設計與應用全解析

    精密軌到軌輸入輸出運算放大器 OP184/OP284/OP484:設計與應用全解析 在電子工程師的日常設計工作中,運算放大器是一個至關重要的組件,它的性能優劣直接影響到整個電路的表現。今天,我們就來
    的頭像 發表于 01-29 17:00 ?330次閱讀

    LT1218L:精密軌到軌輸入輸出運算放大器的卓越之選

    LT1218/LT1219:精密軌到軌輸入輸出運算放大器的卓越之選 在電子工程師的日常設計工作中,運算放大器是不可或缺的基礎元件。今天我們要深入探討的是 Linear Technology 公司
    的頭像 發表于 01-28 17:15 ?470次閱讀

    LT1632軌到軌輸入輸出精密運算放大器的深度剖析

    LT1632/LT1633 軌到軌輸入輸出精密運算放大器的深度剖析 在電子工程師的日常設計工作中,運算放大器是不可或缺的基礎元件。今天,我們就來深入探討 Linear Technology 公司
    的頭像 發表于 01-28 10:20 ?201次閱讀

    LT1219:精密軌到軌輸入輸出運算放大器的卓越之選

    LT1218/LT1219:精密軌到軌輸入輸出運算放大器的卓越之選 在電子工程師的日常設計工作中,運算放大器的選擇對于電路性能的優劣起著關鍵作用。今天,我們就來深入探討一下 Linear
    的頭像 發表于 01-27 10:05 ?240次閱讀

    LT1801低功耗軌到軌輸入輸出精密運算放大器詳解

    LT1801/LT1802低功耗軌到軌輸入輸出精密運算放大器詳解 在電子設計領域,運算放大器是一種極為關鍵的基礎元件,其性能優劣直接影響到整個電路的表現。今天我們要深入探討的是LINEAR
    的頭像 發表于 01-26 15:45 ?235次閱讀

    IGBT的原理,輸入輸出和控制信號

    IGBT的原理,輸入輸出和控制信號
    的頭像 發表于 12-06 06:38 ?2920次閱讀

    變頻器的輸入輸出濾波器的作用

    不僅會影響變頻器自身的穩定運行,還可能對電網和其他設備造成污染。為了解決這一問題,變頻器輸入輸出濾波器應運而生,成為保障電力系統純凈度和設備可靠性的關鍵組件。 一、變頻器干擾的產生機理 在理解濾波器作用之前,需要
    的頭像 發表于 11-28 07:35 ?465次閱讀
    變頻器的<b class='flag-5'>輸入輸出</b>濾波器的作用

    一文帶你讀懂“脈沖輸入輸出模塊”

    “脈沖輸入輸出模塊”,正是這位默默無聞的“信號翻譯官”。 一、什么是脈沖輸入輸出模塊? 簡單來說, 脈沖輸入/輸出模塊(Pulse I/O
    的頭像 發表于 11-24 17:10 ?922次閱讀
    一文帶你讀懂“脈沖<b class='flag-5'>輸入輸出</b>模塊”

    如何用FPGA實現4K視頻的輸入輸出與處理

    在游戲、影視和顯示領域,4K 已經成為標配。而今天,我們就來聊聊——如何用 FPGA 實現 4K 視頻的輸入輸出與處理。
    的頭像 發表于 10-15 10:47 ?2126次閱讀
    如何用FPGA實現4K視頻的<b class='flag-5'>輸入輸出</b>與處理

    詳解FPGA的輸入輸出處理

    inout端口DataBus作為輸出的時候值為DataOut,作為輸入時為高阻態。
    的頭像 發表于 10-15 10:42 ?1607次閱讀
    詳解FPGA的<b class='flag-5'>輸入輸出</b>處理

    GraniStudio:IO初始化以及IO資源配置例程

    IO資源配置.gsp文件,點擊打開,完成導入。 2.功能說明 實現連接格拉尼控制器IO塊以及配置輸入輸出IO點。 2.1通過初始化IO算子連
    的頭像 發表于 08-22 17:34 ?937次閱讀
    GraniStudio:<b class='flag-5'>IO</b>初始化以及<b class='flag-5'>IO</b>資源配置例程

    6軸步進電機驅動+STM32F767+485+CAN+網口+12輸入輸出原理圖

    6軸步進電機驅動+STM32F767+485+CAN+網口+12路輸入輸出 原理圖?步進電機驅動方案TMC5160
    發表于 06-27 16:18 ?0次下載

    線性穩壓器IC的輸入輸出電容設計和紋波對策

    。例如,當負載電流(輸出電流)IO為0.6A時,輸入輸出電壓差Vdrop約為0.25V,如果所需的輸出電壓為3.3V,則最小輸入電壓為3.3
    的頭像 發表于 05-24 14:51 ?1489次閱讀
    線性穩壓器IC的<b class='flag-5'>輸入輸出</b>電容設計和紋波對策

    NCA9555 具有16位通用并行I2C總線數輸入輸出GPIO擴展功能

    NCA9555是一款24引腳CMOS器件,提供16位通用并行I2C總線數輸入/輸出GPIO擴展功能。它和ACPI電源開關,傳感器,按鍵,LED和風扇等應用的額外I/O口需求提供了簡單的解決方案
    發表于 05-19 18:02 ?0次下載

    遠程輸入輸出掃描儀說明

    電子發燒友網站提供《遠程輸入輸出掃描儀說明.pdf》資料免費下載
    發表于 03-26 15:06 ?0次下載