前段時(shí)間寫了面向?qū)ο蟮耐莆?,算是?jiǎn)單對(duì)面向?qū)ο筮M(jìn)行介紹,現(xiàn)在單獨(dú)出個(gè)系列來(lái)深入學(xué)習(xí)面向?qū)ο?,例程基?a target="_blank">GD32進(jìn)行編寫測(cè)試。不知道各位配置GPIO是不是還在用老套路,這篇推文將使用面向?qū)ο髞?lái)配置GPIO,直接就可以對(duì)MCU的GPIO進(jìn)行配置;
eio_pin.h
#ifndef EIO_PIN_H #define EIO_PIN_H /* includes ----------------------------------------------------------------- */ #include#include "gd32f10x.h" #ifdef __cplusplus extern "C" { #endif /* 公共定義 ------------------------------------------------------------------ */ enum pin_mode { /* GPIO mode enum */ PIN_MODE_AIN = 0, PIN_MODE_IN_FLOATING, PIN_MODE_IPD, PIN_MODE_IPU, PIN_MODE_OUT_OD, PIN_MODE_OUT_PP, PIN_MODE_AF_OD, PIN_MODE_AF_PP, PIN_MODE_MAX }; /* 公共類型定義 -------------------------------------------------------------- */ typedef struct eio_pin_data { uint32_t gpio_x; uint32_t pin; } eio_pin_data_t; // 定義類 typedef struct eio_pin { /* 私有的 */ eio_pin_data_t data; enum pin_mode mode; uint8_t status; } eio_pin_t; void eio_pin_init(eio_pin_t * const me, const char *name, enum pin_mode mode); uint8_t eio_pin_get_status(eio_pin_t * const me); void eio_pin_set_status(eio_pin_t * const me, uint8_t status); #ifdef __cplusplus } #endif #endif /* ----------------------------- end of file -------------------------------- */
eio_pin.c
#include "eio_pin.h"
/* 私有變量 ------------------------------------------------------------------ */
static const uint32_t gpio_table[] =
{
GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG,
};
/* 私有函數(shù) ----------------------------------------------------------------- */
/**
* @brief 檢查給定的引腳名稱是否有效
* @param name 給定的引腳名稱
* @retval None.
*/
static uint8_t _check_pin_name_valid(const char *name)
{
uint8_t ret = TRUE;
uint8_t pin_number;
if (!(strlen(name) == 4 && (name[1] == '.')))
{
ret = FALSE;
goto exit;
}
if (!((name[0] < 'A' && name[0] > 'G') &&
(name[2] < '0' && name[2] > '1') &&
(name[3] < '0' && name[3] > '9')))
{
ret = FALSE;
goto exit;
}
pin_number = (name[2] - '0') * 10 + (name[3] - '0');
if (pin_number >= 16)
{
ret = FALSE;
goto exit;
}
exit:
return ret;
}
/**
* @brief 將引腳名稱轉(zhuǎn)換為MCU相關(guān)引腳數(shù)據(jù)結(jié)構(gòu)
* @param name 給定的引腳名稱
* @param data 引腳數(shù)據(jù)輸出
* @retval None.
*/
static void _translate_pin_name(const char *name, eio_pin_data_t *data)
{
/* 檢測(cè)名稱 */
_check_pin_name_valid(name);
/* 解析端口 */
data->gpio_x = gpio_table[name[0] - 'A'];
/* 解析引腳 */
data->pin = (1 << ((uint8_t)((name[2] - '0') * 10 + (name[3] - '0'))));
/* 配置時(shí)鐘 */
if (name[0] == 'A')
{
rcu_periph_clock_enable(RCU_GPIOA);
}
else if (name[0] == 'B')
{
rcu_periph_clock_enable(RCU_GPIOB);
}
else if (name[0] == 'C')
{
rcu_periph_clock_enable(RCU_GPIOC);
}
else if (name[0] == 'D')
{
rcu_periph_clock_enable(RCU_GPIOD);
}
else if (name[0] == 'E')
{
rcu_periph_clock_enable(RCU_GPIOE);
}
else if (name[0] == 'F')
{
rcu_periph_clock_enable(RCU_GPIOF);
}
else if (name[0] == 'G')
{
rcu_periph_clock_enable(RCU_GPIOG);
}
}
/**
* @brief EIO引腳初始化
* @param me this指針
* @param name 引腳名字, 就像“A.01”或“B.14”等等.
* @param mode 引腳模式.
* @retval None
*/
void eio_pin_init(eio_pin_t * const me, const char *name, enum pin_mode mode)
{
/* 使能外設(shè)時(shí)鐘 */
_translate_pin_name(name, &me->data);
/* 模式賦值 */
me->mode = mode;
/* 配置GPIO引腳 */
if (mode == PIN_MODE_AIN)
{
/* 配置GPIO端口:模擬輸入 */
gpio_init(me->data.gpio_x, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, me->data.pin);
/* 復(fù)位GPIO引腳 */
gpio_bit_reset(me->data.gpio_x, me->data.pin);
}
else if (mode == PIN_MODE_IN_FLOATING)
{
/* 配置GPIO端口:浮空輸入 */
gpio_init(me->data.gpio_x, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, me->data.pin);
/* 復(fù)位GPIO引腳 */
gpio_bit_reset(me->data.gpio_x, me->data.pin);
}
else if (mode == PIN_MODE_IPD)
{
/* 配置GPIO端口:下拉輸入 */
gpio_init(me->data.gpio_x, GPIO_MODE_IPD, GPIO_OSPEED_50MHZ, me->data.pin);
/* 復(fù)位GPIO引腳 */
gpio_bit_reset(me->data.gpio_x, me->data.pin);
}
else if (mode == PIN_MODE_IPU)
{
/* 配置GPIO端口:上拉輸入 */
gpio_init(me->data.gpio_x, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, me->data.pin);
/* 復(fù)位GPIO引腳 */
gpio_bit_reset(me->data.gpio_x, me->data.pin);
}
else if (mode == PIN_MODE_OUT_OD)
{
/* 配置GPIO端口:開(kāi)漏輸出 */
gpio_init(me->data.gpio_x, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, me->data.pin);
/* 復(fù)位GPIO引腳 */
gpio_bit_reset(me->data.gpio_x, me->data.pin);
/* 拉低GPIO輸出 */
gpio_bit_write(me->data.gpio_x, me->data.pin, RESET);
}
else if (mode == PIN_MODE_OUT_PP)
{
/* 配置GPIO端口:推挽輸出 */
gpio_init(me->data.gpio_x, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, me->data.pin);
/* 復(fù)位GPIO引腳 */
gpio_bit_reset(me->data.gpio_x, me->data.pin);
/* 拉低GPIO輸出 */
gpio_bit_write(me->data.gpio_x, me->data.pin, RESET);
}
else if (mode == PIN_MODE_AF_OD)
{
/* 配置GPIO端口:AFIO開(kāi)漏輸出 */
gpio_init(me->data.gpio_x, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, me->data.pin);
/* 復(fù)位GPIO引腳 */
gpio_bit_reset(me->data.gpio_x, me->data.pin);
/* 拉低GPIO輸出 */
gpio_bit_write(me->data.gpio_x, me->data.pin, RESET);
}
else if (mode == PIN_MODE_AF_PP)
{
/* 配置GPIO端口:AFIO推挽輸出 */
gpio_init(me->data.gpio_x, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, me->data.pin);
/* 復(fù)位GPIO引腳 */
gpio_bit_reset(me->data.gpio_x, me->data.pin);
/* 拉低GPIO輸出 */
gpio_bit_write(me->data.gpio_x, me->data.pin, RESET);
}
/* 更新引腳狀態(tài) */
eio_pin_get_status(me);
}
/**
* @brief EIO引腳狀態(tài)獲取功能
* @param me this指針
* @retval 引腳的狀態(tài)
*/
uint8_t eio_pin_get_status(eio_pin_t * const me)
{
uint8_t status = gpio_input_bit_get(me->data.gpio_x, me->data.pin);
me->status = (status == SET) ? TRUE : FALSE;
return me->status;
}
/**
* @brief EIO引腳狀態(tài)開(kāi)啟功能
* @param me this指針
* @param status 輸入引腳狀態(tài)
* @retval 無(wú)
*/
void eio_pin_set_status(eio_pin_t * const me, uint8_t status)
{
if (status != me->status)
{
gpio_bit_write(me->data.gpio_x, me->data.pin, status ? SET : RESET);
/* 更新引腳狀態(tài) */
eio_pin_get_status(me);
}
}
main.c
#include "gd32f10x.h" #include "hal_log.h" #include "hal_printf.h" #include "eio_pin.h" // 實(shí)例化對(duì)象 eio_pin_t pin_led; eio_pin_t pin_key; // 主循環(huán) int main(void) { hal_log_init(); eio_pin_init(&pin_led, "E.02", PIN_MODE_OUT_PP); eio_pin_init(&pin_key, "E.03", PIN_MODE_IN_FLOATING); while (1) { eio_pin_set_status(&pin_led, 0); if( eio_pin_get_status(&pin_key) ) { printfk(USART0,"h "); }else{ printfk(USART0,"l "); } } }通過(guò)eio_pin文件就可以對(duì)mcu的gpio進(jìn)行配置,通過(guò)實(shí)例不同的對(duì)象綁定相關(guān)信息,即可完成gpio的常規(guī)配置,非常方便應(yīng)用層的調(diào)用。
編輯:黃飛
?
電子發(fā)燒友App



















評(píng)論