通過陣列和列舉簡化GPIO操作編碼

2022-06-20 17:03:14 字數 2657 閱讀 1947

在工作中,經常遇到大量使用gpio作為數字量輸入輸出來控制裝置或採集狀態,每次定義操作不同的gpio針腳既麻煩又容易出錯,於是就想要簡化操作過程。對於數字量輸入來說就是採集對應針腳的狀態;而輸出則是根據邏輯關係置位或復位對應得針腳。

為了使用方便,我們按可復用和經常變化的部分叫軟體的實現劃分為2個部分。相對固定的部分我們封裝成操作函式供呼叫,對於經常變化的部分(如硬體配置等)我們另外實現,並呼叫前面封裝的函式實現功能。

現在我們只要實現了通用性較好的函式封裝,剩下就是呼叫來實現具體控制的問題。那麼怎麼封裝這些函式呢?

我們首先定義兩個列舉型別分別定義如下:

//

定義數字量輸出通道列舉型別,規定通道的範圍

typedef enum

digitaloutput;

//定義數字量輸入通道列舉型別,規定通道的範圍

typedef enum

digitalinput;

數字量輸入輸出的列舉主要是為了方便操作和識別,通道數量出現變化時只需要增加列舉兩種的通道定義即可。此處數字量輸入輸出均定義了5個通道。列舉量的最後乙個成員代表了通道的數量,在列舉全部通道時能夠很好的避免超出範圍的錯誤。

同時還要定義如下的結構體,用於定義需要操作gpio目標。

//

定義用於針腳操作的目標針腳型別

typedef struct

targetpin;

有了上述的定義則可以實現前面設想的操作了,接下來我們還需要定義兩個數字量輸入輸出通道的targetpin型別的陣列,用於存放想要操作的目標通道,和前面列舉兩種定義的通道一致,此處也是5個通道。

//

定義di通道的全部目標針腳陣列

targetpin dipin=,,

,,};

//定義do通道的全部目標針腳陣列

targetpin dopin=,,

,,};

有了以上2個陣列就可以在避免在操作過程中大量使用條件分支語句(switch或if語句),簡化編碼和避免在增加通道時號要修改函式的情況。現在如果通道數量出現變化則只需要修改列舉量和陣列的值就可。或者操作的管腳出現變化則只需要修改陣列的值就可以了。而不需要去修改函式體,而且函式體的編碼也非常簡單。

對數字量輸出的操作如下,在操作全部通道時,以列舉變數作為迴圈變數,以列舉的最後定義的數量來控制,並以列舉量的取值作為陣列下標,有效避免出現超出範圍的錯誤,同時在通道數量和通道對應的具體針腳發生變化時,無需修改函式。

//

操作全部繼電器do通道

//輸入引數targetpin *dopin為要操作的do通道列表

//輸入引數bool *commands欲寫給do通道的值列表

void operationallrelaychannel(targetpin *dopin,bool *commands)}//

操作單個繼電器do通道

//輸入引數targetpin dopin為要操作的do通道

//輸入引數bool command欲寫給do通道的值

void

operationsinglerelaychannel(targetpin dopin,bool command)

else

}

對數字量輸入的操作函式的編寫採用與數字量輸出相同的思路。對於列舉之所以可以用作陣列下標,是因為列舉沒被指定值時,總是從0開始向上累加,正好與陣列下標是一致的。這要做還有乙個好處是,通道與具體的gpio引腳是由targetpin陣列的賦值順序決定的,修改非常方便。

//

獲取全部di量狀態輸入值

//輸入引數targetpin *dipin為需要讀取的di通道列表

//輸入引數bool *result為讀取的通道值返回列表

void getalldistatusinput(targetpin *dipin,bool *result)}//

獲取單個di量狀態輸入值

//輸入引數targetpin dipin是需要讀取的di通道

//返回值為讀取的通道值

bool getsingledistatusinput(targetpin dipin)

通過以上的編碼操作di、do已經很方便了,但在操作單個do通道的函式中還有乙個if…else語句給人的感覺比較不太好。因為操作簡單就是置位和復位,所以我們定義乙個指向函式的指標陣列,如下:

/*

定義操作gpio管腳的函式指標

*/void (*operationgpiobits)(gpio_typedef *gpiox, uint16_t gpio_pin)=;

有了這個指向函式的指標陣列我們可以將上面的操作單個do通道的函式簡化為如下:

//

操作單個繼電器do通道

//輸入引數targetpin dopin為要操作的do通道

//輸入引數bool command欲寫給do通道的值

void

operationsinglerelaychannel(targetpin dopin,bool command)

其中command是乙個布林變數取值為0和1,正好與指向函式的指標陣列對應,實現在command取不同值時,呼叫復位或置位函式。

以上**在iar ewarm和stm32f103vet平台測試正確。

通過陣列和列舉簡化GPIO操作編碼

在工作中,經常遇到大量使用gpio作為數字量輸入輸出來控制裝置或採集狀態,每次定義操作不同的gpio針腳既麻煩又容易出錯,於是就想要簡化操作過程。對於數字量輸入來說就是採集對應針腳的狀態 而輸出則是根據邏輯關係置位或復位對應得針腳。為了使用方便,我們按可復用和經常變化的部分叫軟體的實現劃分為2個部分...

通過陣列的形式傳遞引數

用到陣列的形式傳遞引數的一般都是批量新增,批量刪除 還有就是批量判斷條件 首先宣告個全域性變數陣列 如下圖然後宣告乙個建構函式 如下圖 建構函式的作用主要是建立字段接收資料 因為最終靠字段的對應來傳遞資料 所以建構函式的建立是必需的 之後迴圈遍歷你需要傳遞的批量內容存入建構函式的字段中再記錄到陣列中...

js通過陣列內容來獲取陣列下標

這是乙個通過已知陣列裡面的某個內容,然後要通過這個內容來刪除這個陣列,是通過迴圈來把陣列的下標找到,然後再拿去刪除 第一種方法是自己寫的,可以把同樣的也找出來 var arr 1 1,2 12,3 23,5 6,45 陣列 var k 12 要查詢陣列的內容 var c 通過內容來獲取的陣列的下標 ...