本文将学习关于GD32F4xx的GPIO库函数学习
打开gd43f4xx_gpio.h往下滑动可看见有关gpio的函数
/* function declarations */
/* reset GPIO port */ //复位整个GPIOx
void gpio_deinit(uint32_t gpio_periph);
/* set GPIO mode */ //gpio模式设置
void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin);
/* set GPIO output type and speed */ //gpio初始化配置
void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin);
/* set GPIO pin bit */ //BSRR寄存器的原子置位改变为高电平
void gpio_bit_set(uint32_t gpio_periph, uint32_t pin);
/* reset GPIO pin bit */ //BSRR寄存器的原子置位改变为低电平
void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin);
/* write data to the specified GPIO pin */ //通过bit_value的值来写入高低电平
void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value);
/* write data to the specified GPIO port */ //一次性直接通过ODR写入十六位,改变GPIOx的值
void gpio_port_write(uint32_t gpio_periph, uint16_t data);
/* get GPIO pin input status */ //得到GPIO的状态
FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin);
/* get GPIO port input status */ //得到整个GPIOx的状态
uint16_t gpio_input_port_get(uint32_t gpio_periph);
/* get GPIO pin output status */ //得到输出模式的GPIO状态
FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin);
/* get GPIO port output status */ //得到输出模式的GPIOx状态
uint16_t gpio_output_port_get(uint32_t gpio_periph);
/* set GPIO alternate function */ //复用设置
void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin);
/* lock GPIO pin bit */ //对GPIO进行配置锁定(复位可改变)
void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin);
/* toggle GPIO pin status */ //翻转电平
void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin);
/* toggle GPIO port status */ //翻转整个GPIOx的电平
void gpio_port_toggle(uint32_t gpio_periph);
注:(ODR为Output Data Register 即输出数据寄存器 )
(BSRR寄存器的原子置位:是指通过单条指令对特定位置1或清0)
这些函数接下来将会一一做解释
先提前对函数的输入参数做出解释
gpio_periph:端口组
/* GPIOx(x=A,B,C,D,E,F,G,H,I) definitions */
#define GPIOA (GPIO_BASE + 0x00000000U)
#define GPIOB (GPIO_BASE + 0x00000400U)
#define GPIOC (GPIO_BASE + 0x00000800U)
#define GPIOD (GPIO_BASE + 0x00000C00U)
#define GPIOE (GPIO_BASE + 0x00001000U)
#define GPIOF (GPIO_BASE + 0x00001400U)
#define GPIOG (GPIO_BASE + 0x00001800U)
#define GPIOH (GPIO_BASE + 0x00001C00U)
#define GPIOI (GPIO_BASE + 0x00002000U)
mode:选择模式
/* output mode definitions */
#define CTL_CLTR(regval) (BITS(0,1) & ((uint32_t)(regval) << 0))
#define GPIO_MODE_INPUT CTL_CLTR(0) /*!< input mode */
#define GPIO_MODE_OUTPUT CTL_CLTR(1) /*!< output mode */
#define GPIO_MODE_AF CTL_CLTR(2) /*!< alternate function mode*/
#define GPIO_MODE_ANALOG CTL_CLTR(3) /*!< analog mode */
GPIO_MODE_INPUT 输入模式
GPIO_MODE_OUTPUT 输出模式
GPIO_MODE_AF 引脚复用模式(外设引脚复用)
GPIO_MODE_ANALOG 模拟模式(ADC,DAC数模转换功能)
pull_up_down:上下拉设置
/* pull-up/ pull-down definitions */
#define PUD_PUPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0))
#define GPIO_PUPD_NONE PUD_PUPD(0) /*!< floating mode, no pull-up and pull-down resistors */
#define GPIO_PUPD_PULLUP PUD_PUPD(1) /*!< with pull-up resistor */
#define GPIO_PUPD_PULLDOWN PUD_PUPD(2) /*!< with pull-down resistor*/
分别是浮空,上拉,下拉
pin:引脚选择
/* GPIO pin definitions */
#define GPIO_PIN_0 BIT(0) /*!< GPIO pin 0 */
#define GPIO_PIN_1 BIT(1) /*!< GPIO pin 1 */
#define GPIO_PIN_2 BIT(2) /*!< GPIO pin 2 */
#define GPIO_PIN_3 BIT(3) /*!< GPIO pin 3 */
#define GPIO_PIN_4 BIT(4) /*!< GPIO pin 4 */
#define GPIO_PIN_5 BIT(5) /*!< GPIO pin 5 */
#define GPIO_PIN_6 BIT(6) /*!< GPIO pin 6 */
#define GPIO_PIN_7 BIT(7) /*!< GPIO pin 7 */
#define GPIO_PIN_8 BIT(8) /*!< GPIO pin 8 */
#define GPIO_PIN_9 BIT(9) /*!< GPIO pin 9 */
#define GPIO_PIN_10 BIT(10) /*!< GPIO pin 10 */
#define GPIO_PIN_11 BIT(11) /*!< GPIO pin 11 */
#define GPIO_PIN_12 BIT(12) /*!< GPIO pin 12 */
#define GPIO_PIN_13 BIT(13) /*!< GPIO pin 13 */
#define GPIO_PIN_14 BIT(14) /*!< GPIO pin 14 */
#define GPIO_PIN_15 BIT(15) /*!< GPIO pin 15 */
#define GPIO_PIN_ALL BITS(0,15) /*!< GPIO pin all */
otype:输出类型
/* GPIO output type */
#define GPIO_OTYPE_PP ((uint8_t)(0x00U)) /*!< push pull mode */
#define GPIO_OTYPE_OD ((uint8_t)(0x01U)) /*!< open drain mode */
GPIO_OTYPE_PP:推挽输出
GPIO_OTYPE_OD:开漏输出
speed:io口速度
/* GPIO output max speed value */
#define GPIO_OSPEED_2MHZ GPIO_OSPEED_LEVEL0 /*!< output max speed 2MHz */
#define GPIO_OSPEED_25MHZ GPIO_OSPEED_LEVEL1 /*!< output max speed 25MHz */
#define GPIO_OSPEED_50MHZ GPIO_OSPEED_LEVEL2 /*!< output max speed 50MHz */
#define GPIO_OSPEED_MAX GPIO_OSPEED_LEVEL3 /*!< GPIO very high output speed, max speed more than 50MHz */
注意这里必须要说明:根据GD32数据手册
在设置io口频率的时候不是一味的选择50MHz
慢速开关,低频led,继电器等,应选择GPIO_OSPEED_2MHZ
UART/I2C/低速SPI等外设,应选择GPIO_OSPEED_25MHZ
高速SPI,FSMC、ETH、DCMI,应选择GPIO_OSPEED_50MHZ
bit_value:数值
SET/RESET or 1/0 即可
data:十六进制数值,是用来写入ODR
ok,参数大致介绍完毕接下来开始学习函数使用
1. gpio_deinit
void gpio_deinit(uint32_t gpio_periph);
内部就是对输入参数GPIOx
rcu_periph_reset_enable(RCU_GPIOARST);的作用就是将GPIO“拉回复位值”,就相当于做了一次硬件复位,让所有寄存器都恢复到上电的初始状态
gpio_deinit(GPIOA); //复位所有GPIOA的io口
2. gpio_mode_set
void gpio_mode_set(uint32_t gpio_periph, //端口组
uint32_t mode, //选择模式
uint32_t pull_up_down, //上下拉选择
uint32_t pin); //PIN脚
仅配置引脚方向
配置引脚的速度和什么方式输出为下面这个函数gpio_output_options_set();
3. gpio_output_options_set
void gpio_output_options_set(uint32_t gpio_periph, //端口组
uint8_t otype, //推挽开漏输出
uint32_t speed, //引脚速度
uint32_t pin); //PIN脚
这个函数是用来设置关于引脚的详细配置包括是否是开漏推挽输出和引脚速度
按照一般情况来说这个函数和上一个函数是搭配使用eg:
//将B15引脚设置为输出模式,浮空
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_5);
//将B15引脚设置为推挽输出,速度为50MHZ
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
4. gpio_bit_set
void gpio_bit_set(uint32_t gpio_periph, //端口组
uint32_t pin); //PIN脚
这个函数的作用是将某个引脚设置为高电平
这是不可被CPU打断的
他在机器中经过编译后只会生成一条指令
他是操作寄存器进行原子置位
相较于后续功能相同函数gpio_bit_write();代码体积更小更快
(原子置位:“一口气将某个位置为1,中间不可被中断,DMA等其他操作打断”)
gpio_bit_set(GPIOB,GPIO_PIN_15); //将B15设置为高电平
同时gpio_bit_reset();也是同理,只是将电平设置为低电平,就不过多赘述
5. gpio_bit_write
void gpio_bit_write(uint32_t gpio_periph, //端口组
uint32_t pin, //PIN脚
bit_status bit_value); //数值0/1
这就不是原子置位
同样也是写入gpio的高低电平(可打断)
gpio_bit_write(GPIOB,GPIO_PIN_15,1); //将B15设置为高电平
6. gpio_port_write
void gpio_port_write(uint32_t gpio_periph, //端口组
uint16_t data); //十六进制数据
同样这是对整个端口组进行写入高低电平
gpio_port_write(GPIOB,0x00ff);//二进制:0000 0000 1111 1111,
//所以PB0~PB7为高电平,PB8~PB15为低电平
7. gpio_input_bit_get
FlagStatus gpio_input_bit_get(uint32_t gpio_periph, //端口组
uint32_t pin); //PIN脚
这个函数功能是读取单个输入引脚的状态
gpio_input_bit_get(GPIOB,GPIO_PIN_15); //读取PB15引脚的状态
8. uint16_t gpio_input_port_get
uint16_t gpio_input_port_get(uint32_t gpio_periph);//端口组
这个函数的功能是读取整个端口组的电平状态,返回值是一个uint16的值
uint16_t temp;
temp=gpio_input_port_get(GPIOB); //读取整个B端口的高低电平值,并且储存在temp
9. gpio_output_bit_get
FlagStatus gpio_output_bit_get(uint32_t gpio_periph, //端口组
uint32_t pin); //PIN脚
这个函数的作用是回读到io口的状态(回读ODR寄存器)
例如这个io口设置的是output输出模式,就可以回读到之前的看看自己写的是1还是0
查看枚举可得知返回值是RESET(0)和SET(1)
注意:回读的是ODR寄存器,外设硬件原因改变的高低电平是读不到的
if(gpio_output_bit_get(GPIOB15,GPIO_PIN_15)==1)//判断PB15是否是高电平
10. gpio_output_port_get
uint16_t gpio_output_port_get(uint32_t gpio_periph);//端口组
同样这个函数是回读整个端口组的电平状态,就不过多赘述
11. gpio_af_set
void gpio_af_set(uint32_t gpio_periph, //端口组
uint32_t alt_func_num, //复用引脚
uint32_t pin); //PIN脚
这个函数是对引脚复用设置的函数,使用的前提的在前面gpio_mode_set();设置的时候要选择复用模式,否则无效
关于复用外设引脚时改选择哪个AF引脚,需要翻阅数据手册才能得知,我将会放在文章的最后
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9); // PA9复用为USART0_TX
12. gpio_pin_lock
void gpio_pin_lock(uint32_t gpio_periph, //端口组
uint32_t pin); //PIN脚
这个函数是用来对IO口“上锁”,使用这个函数后,之后的函数操作是不能对其IO口进行任何操作,只有重新上电(RET)才能改变IO口
13. gpio_bit_toggle
gpio_port_toggle
void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin);
void gpio_port_toggle(uint32_t gpio_periph);
这两个函数都是IO作翻转,只是前者是单个IO口翻转,后者为整个端口组翻转,这里就不作示例了
AF引脚复用选择图
添加完毕