基于GD32进行编写测试的PIN操作

编程语言及工具

106人已加入

描述

前段时间写了面向对象的推文,算是简单对面向对象进行介绍,现在单独出个系列来深入学习面向对象,例程基于GD32进行编写测试。不知道各位配置GPIO是不是还在用老套路,这篇推文将使用面向对象来配置GPIO,直接就可以对MCU的GPIO进行配置;

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


/*  私有函数 ----------------------------------------------------------------- */
/**
  * @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  将引脚名称转换为MCU相关引脚数据结构
  * @param  name    给定的引脚名称
  * @param  data    引脚数据输出
  * @retval None.
  */
static void _translate_pin_name(const char *name, eio_pin_data_t *data)
{
    /* 检测名称 */
    _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'))));
    /* 配置时钟 */
    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)
{
    /* 使能外设时钟 */
    _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);
        /* 复位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);
        /* 复位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);
        /* 复位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);
        /* 复位GPIO引脚 */
        gpio_bit_reset(me->data.gpio_x, me->data.pin);
    }
    else if (mode == PIN_MODE_OUT_OD)
    {
        /* 配置GPIO端口:开漏输出 */ 
        gpio_init(me->data.gpio_x, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, me->data.pin);
        /* 复位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);
        /* 复位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开漏输出 */ 
        gpio_init(me->data.gpio_x, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, me->data.pin);
        /* 复位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);
        /* 复位GPIO引脚 */
        gpio_bit_reset(me->data.gpio_x, me->data.pin);
        /* 拉低GPIO输出 */
        gpio_bit_write(me->data.gpio_x, me->data.pin, RESET);
    }
    /* 更新引脚状态 */
    eio_pin_get_status(me);
}


/**
  * @brief  EIO引脚状态获取功能
  * @param  me      this指针
  * @retval 引脚的状态
  */
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引脚状态开启功能
  * @param  me      this指针
  * @param  status  输入引脚状态
  * @retval 无
  */
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);
        /* 更新引脚状态 */
        eio_pin_get_status(me);
    }
}
main.c
#include "gd32f10x.h"
#include "hal_log.h"
#include "hal_printf.h"
#include "eio_pin.h"


// 实例化对象
eio_pin_t pin_led;
eio_pin_t pin_key;


// 主循环
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
");
    }
  }
}通过eio_pin文件就可以对mcu的gpio进行配置,通过实例不同的对象绑定相关信息,即可完成gpio的常规配置,非常方便应用层的调用。

编辑:黄飞

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分