哈哈哈哈哈操欧洲电影,久草网在线,亚洲久久熟女熟妇视频,麻豆精品色,久久福利在线视频,日韩中文字幕的,淫乱毛视频一区,亚洲成人一二三,中文人妻日韩精品电影

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

給大家分享一個(gè)非常簡(jiǎn)單的IO輸入輸出框架

FPGA之家 ? 來(lái)源:魚(yú)鷹談單片機(jī) ? 作者:魚(yú)鷹談單片機(jī) ? 2021-07-23 10:45 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

在一個(gè)嵌入式系統(tǒng)中,可能存在許多輸入或輸出的IO口,輸入有霍爾傳感器、紅外對(duì)管等,輸出有LED、電源控制開(kāi)關(guān)等。

如果說(shuō)硬件可以一次成型,那么隨便一份代碼都可以完成IO的配置工作,但研發(fā)階段的產(chǎn)品,硬件各種修改是難免的,每一次 IO 的修改,對(duì)于底層開(kāi)發(fā)人員來(lái)說(shuō),可能都是一次挑戰(zhàn)。

因?yàn)橐坏┯心骋粋€(gè) IO 配置錯(cuò)誤,或者原來(lái)的配置沒(méi)有修改正確(比如一個(gè) IO 在原來(lái)的硬件適配中是輸入,之后的硬件需要修改成輸出),那么你很難查出來(lái)這是什么問(wèn)題,因?yàn)檫@個(gè)時(shí)候不僅硬件修改了,軟件也修改了,你需要先定位到底是軟件問(wèn)題還是硬件問(wèn)題,所以一個(gè)好用的 IO 的配置框架就顯得很有必要了。

有道友會(huì)說(shuō),不如使用 CubeMx 軟件進(jìn)行開(kāi)發(fā)吧。

1、這個(gè)軟件適用于 ST 單片機(jī),以前還能用,現(xiàn)在,除非你家里有礦,不然誰(shuí)用的起STM32?基本上都國(guó)產(chǎn)化了(雖然有些單片機(jī)號(hào)稱(chēng)兼容,但到底還是有些差異的)。

2、公司原本的代碼就是使用標(biāo)準(zhǔn)庫(kù),只是因?yàn)镮O 的變化,你就需要把整個(gè)庫(kù)換掉嗎?時(shí)間上允許嗎?你確定修改后不會(huì)出現(xiàn)大問(wèn)題?

3、國(guó)產(chǎn)化的芯片可沒(méi)有所謂的標(biāo)準(zhǔn)庫(kù)和HAL庫(kù)供你選擇,每一家都有各自的庫(kù),如果你的產(chǎn)品臨時(shí)換方案怎么辦?

4、HAL 效率問(wèn)題。

今天魚(yú)鷹介紹一個(gè)簡(jiǎn)單實(shí)用的框架,可用于快速增加或修改IO配置,甚至修改底層庫(kù)。

假設(shè)有3個(gè) LED 作為輸出、3 個(gè)霍爾傳感器作為輸入:

輸入配置代碼:

#define GPIOx_Def GPIO_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), };

// 單個(gè) IO 初始化函數(shù) 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 個(gè) 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;}

// 讀取單個(gè) IO 狀態(tài)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,另一個(gè)枚舉值自動(dòng)修改為相反值 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);//必須,進(jìn)入調(diào)試模式后點(diǎn)擊全速運(yùn)行

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); } }

調(diào)試的時(shí)候,我們可以很方便的查看每個(gè) IO 的狀態(tài)是怎樣的,而不用管 0 或 1 到底代表什么意思:

輸出配置代碼:

#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);//必須,進(jìn)入調(diào)試模式后點(diǎn)擊全速運(yùn)行

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); } }

這個(gè)框架有啥好處呢?

1、自動(dòng)完成 GPIO 的時(shí)鐘初始化工作,也就是說(shuō)你只需要修改引腳即可,不必關(guān)心時(shí)鐘配置,但對(duì)于特殊引腳(比如PB3),還是得另外配置才行。

2、應(yīng)用和底層具體 IO 分離,這樣一旦修改了 IO,應(yīng)用代碼不需要進(jìn)行任何修改。

3、增加或刪減 IO 變得很簡(jiǎn)單,增加 IO時(shí),首先加入對(duì)應(yīng)枚舉,然后就可以添加對(duì)應(yīng)的 IO 了。刪除 IO時(shí),只要屏蔽對(duì)應(yīng)枚舉值和引腳即可。

4、參數(shù)檢查功能, IO 刪除時(shí),因?yàn)槠帘瘟藢?duì)應(yīng)的枚舉,所以編譯時(shí)可以幫你發(fā)現(xiàn)問(wèn)題,而增加 IO 時(shí),它可以幫你在運(yùn)行時(shí)檢查該 IO是否進(jìn)行配置了,可以防止因?yàn)槭д`導(dǎo)致的問(wèn)題。

a82570d2-e10c-11eb-9e57-12bb97331649.png

5、更改庫(kù)時(shí)可以很方便,只需要修改對(duì)應(yīng)的宏即可,目前可以順利在 GD32 和 STM32 庫(kù)進(jìn)行快速更換。

6、對(duì)于輸入 IO 而言,可以方便的修改有效和無(wú)效狀態(tài),防止硬件修改有效電平。對(duì)于輸出 IO 而言,可以設(shè)定初始 IO 電平狀態(tài)。

7、代碼簡(jiǎn)單高效,盡可能的復(fù)用代碼,增加一個(gè) IO 只需要很少的空間。

8、缺點(diǎn)就是,只對(duì)同種配置的 IO 可以這樣用。

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴

原文標(biāo)題:簡(jiǎn)單實(shí)用IO輸入輸出框架

文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何基于現(xiàn)場(chǎng)需求選配PLC本地/遠(yuǎn)程IO?

    很多剛接觸工控的朋友,常常會(huì)被“本地IO”和“遠(yuǎn)程IO”這兩個(gè)概念搞混。 它們到底有什么區(qū)別?在實(shí)際項(xiàng)目中又該如何選擇?今天我們就來(lái)次性說(shuō)清楚。 什么是
    的頭像 發(fā)表于 03-30 17:15 ?472次閱讀
    如何基于現(xiàn)場(chǎng)需求選配PLC本地/遠(yuǎn)程<b class='flag-5'>IO</b>?

    AD74115:?jiǎn)瓮ǖ儡浖膳渲?b class='flag-5'>輸入輸出設(shè)備的深度解析

    的解決方案。本文將對(duì)AD74115進(jìn)行詳細(xì)剖析,探討其特性、工作原理、應(yīng)用場(chǎng)景以及相關(guān)注意事項(xiàng)。 文件下載: AD74115.pdf 、AD74115的特性亮點(diǎn) 1. 多功能可配置性 AD74115具有單通道軟件可配置輸入輸出功能,
    的頭像 發(fā)表于 03-25 15:45 ?179次閱讀

    西門(mén)子模擬量輸入輸出具體的應(yīng)用

    西門(mén)子模擬量輸入輸出在工業(yè)自動(dòng)化和控制系統(tǒng)中有著廣泛的應(yīng)用,以下是對(duì)其具體應(yīng)用的些詳細(xì)闡述。
    的頭像 發(fā)表于 03-12 16:54 ?278次閱讀
    西門(mén)子模擬量<b class='flag-5'>輸入輸出</b>具體的應(yīng)用

    SGM8431-1單運(yùn)放:高輸出電流與軌到軌輸入輸出的卓越之選

    SGM8431-1單運(yùn)放:高輸出電流與軌到軌輸入輸出的卓越之選 在電子設(shè)計(jì)領(lǐng)域,運(yùn)算放大器作為種基礎(chǔ)且關(guān)鍵的器件,其性能的優(yōu)劣直接影響著整個(gè)電路的表現(xiàn)。今天我們要深入探討的SGM8431 - 1單
    的頭像 發(fā)表于 03-11 16:15 ?147次閱讀

    SGM8710 | 低功耗、高性能的軌到軌輸入輸出比較器

    SGM8710 | 低功耗、高性能的軌到軌輸入輸出比較器 在電子設(shè)計(jì)領(lǐng)域,為了滿足不斷增長(zhǎng)的低功耗和高性能需求,工程師們直在尋找合適的器件。SGM8710作為款單通道軌到軌輸入輸出
    的頭像 發(fā)表于 03-10 15:50 ?231次閱讀

    精密軌到軌輸入輸出運(yùn)算放大器OP484:設(shè)計(jì)與應(yīng)用全解析

    精密軌到軌輸入輸出運(yùn)算放大器 OP184/OP284/OP484:設(shè)計(jì)與應(yīng)用全解析 在電子工程師的日常設(shè)計(jì)工作中,運(yùn)算放大器是個(gè)至關(guān)重要的組件,它的性能優(yōu)劣直接影響到整個(gè)電路的表現(xiàn)。今天,我們就來(lái)
    的頭像 發(fā)表于 01-29 17:00 ?477次閱讀

    LT1218L:精密軌到軌輸入輸出運(yùn)算放大器的卓越之選

    的 LT1218/LT1219 精密軌到軌輸入輸出運(yùn)算放大器,它在眾多方面展現(xiàn)出了出色的性能,能夠滿足多種應(yīng)用場(chǎng)景的需求。 文件下載: LT1218L.pdf 、關(guān)鍵特性剖析 1. 軌到軌輸入輸出
    的頭像 發(fā)表于 01-28 17:15 ?680次閱讀

    LT1219:精密軌到軌輸入輸出運(yùn)算放大器的卓越之選

    LT1218/LT1219:精密軌到軌輸入輸出運(yùn)算放大器的卓越之選 在電子工程師的日常設(shè)計(jì)工作中,運(yùn)算放大器的選擇對(duì)于電路性能的優(yōu)劣起著關(guān)鍵作用。今天,我們就來(lái)深入探討下 Linear
    的頭像 發(fā)表于 01-27 10:05 ?326次閱讀

    IGBT的原理,輸入輸出和控制信號(hào)

    IGBT的原理,輸入輸出和控制信號(hào)
    的頭像 發(fā)表于 12-06 06:38 ?3146次閱讀

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

    “脈沖輸入輸出模塊”,正是這位默默無(wú)聞的“信號(hào)翻譯官”。 、什么是脈沖輸入輸出模塊? 簡(jiǎn)單來(lái)說(shuō), 脈沖輸入/
    的頭像 發(fā)表于 11-24 17:10 ?1183次閱讀
    <b class='flag-5'>一</b>文帶你讀懂“脈沖<b class='flag-5'>輸入輸出</b>模塊”

    GPIO輸入輸出調(diào)用方法的理解與分享

    Nuclei Studio中為GPIO的調(diào)用定義了七個(gè)函數(shù)。 與GPIO輸入輸出的直接有關(guān)的是: GPIO_TypeDef *gpio可以選擇為GPIOA
    發(fā)表于 10-29 06:24

    如何用FPGA實(shí)現(xiàn)4K視頻的輸入輸出與處理

    在游戲、影視和顯示領(lǐng)域,4K 已經(jīng)成為標(biāo)配。而今天,我們就來(lái)聊聊——如何用 FPGA 實(shí)現(xiàn) 4K 視頻的輸入輸出與處理。
    的頭像 發(fā)表于 10-15 10:47 ?2376次閱讀
    如何用FPGA實(shí)現(xiàn)4K視頻的<b class='flag-5'>輸入輸出</b>與處理

    詳解FPGA的輸入輸出處理

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

    個(gè)模塊通吃DI/DO/AI/AO!無(wú)線IO的萬(wàn)能信號(hào)采集方案

    無(wú)線IO通訊模塊是種特殊的輸入輸出(I/O)設(shè)備,它采用無(wú)線通訊技術(shù)實(shí)現(xiàn)I/O信號(hào)的傳輸。以下是對(duì)無(wú)線IO通訊模塊的詳細(xì)介紹: 、定義與
    的頭像 發(fā)表于 07-22 10:15 ?728次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>個(gè)</b>模塊通吃DI/DO/AI/AO!無(wú)線<b class='flag-5'>IO</b>的萬(wàn)能信號(hào)采集方案

    線性穩(wěn)壓器IC的輸入輸出電容設(shè)計(jì)和紋波對(duì)策

    。例如,當(dāng)負(fù)載電流(輸出電流)IO為0.6A時(shí),輸入輸出電壓差Vdrop約為0.25V,如果所需的輸出電壓為3.3V,則最小輸入電壓為3.3
    的頭像 發(fā)表于 05-24 14:51 ?1693次閱讀
    線性穩(wěn)壓器IC的<b class='flag-5'>輸入輸出</b>電容設(shè)計(jì)和紋波對(duì)策
    清丰县| 铜陵市| 金沙县| 嘉义市| 阿拉尔市| 布尔津县| 密山市| 沙河市| 新和县| 内江市| 禹城市| 滦平县| 噶尔县| 舞阳县| 泊头市| 叙永县| 遂昌县| 博乐市| 株洲县| 定州市| 钦州市| 枣强县| 大新县| 阿拉善左旗| 包头市| 潼关县| 延寿县| 小金县| 锡林浩特市| 通道| 郓城县| 台中县| 义马市| 安塞县| 柳河县| 大埔县| 墨玉县| 方山县| 南城县| 福泉市| 西贡区|