GD32F103RCT6/GD32F303RCT6(3.2)GPIO外设使用-实验编程

  本文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发

向上代码兼容GD32F450ZGT6中使用

后续项目主要在下面该专栏中发布:

https://blog.csdn.net/qq_62316532/category_12608431.html?spm=1001.2014.3001.5482

感兴趣的点个关注收藏一下吧!

电机驱动开发可以跳转:

GD32F103RCT6/GD32F303RCT6-实战项目-无刷电机驱动(1)_gd32f103rct6例程-CSDN博客

BMS电源系统开发可以跳转:

暂未放链接

DCDC-双向BUCK-BOOST实战链接:

GD32实战篇-双向数控BUCK-BOOST-BUCK降压理论基础-CSDN博客

GD32实战篇-双向数控BUCK-BOOST-BOOST升压理论基础-CSDN博客

 向上代码兼容GD32F303RCT6中使用

本项目配套开发板:

基于GD32F103RCT6国产GD32平台,以下教程编写基于该开发板

554dfe07a3d841b2a1c710f6d6721ec6.png

本小结为GPIO外设使用的实验章程,在此小结我们会带大家手把手写几个常见的程序

跑马灯实验

实现开发板上两个LED灯实现跑马灯的效果。

LED硬件电路如下:

61b535e3adab41c4bd21b640fa1b4d6e.png

acc68d61e2e14a629caa02061c7c92cd.png

根据硬件电路图知,四个LED灯对应的IO引脚分别为PB3PB4PD2PC12。当四个引脚为低电平时,二极管导通;当四个引脚为高电平时,二极管截止,因此对这两个IO引脚设置高低电平变化即可。

这里我们不需要使用四个,我们只需要使用PB3PB4就行

在前一小结我们说过:

在复位期间或复位之后,备用功能并未激活,所有GPIO端口都被配置成输入浮空模式,这种输入模式禁用上拉(PU)/下拉(PD)电阻。但是复位后,串行线调试端口(JTAG/Serial-Wired Debug pins)为输入PU/PD模式:

PA15:JTDI为上拉模式;

PA14:JTCK / SWCLK为下拉模式;

PA13:JTMS / SWDIO为上拉模式;

PB4:NJTRST为上拉模式;

PB3:JTDO为浮空模式。

所以我们需要先对PB3PB4进行重映射

//管脚复用时钟使能

rcu_periph_clock_enable(RCU_AF);
//PB4和PB3管脚默认是NJTRST,要当GPIO,需要重映射

gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE)

接下来我们就可以开始编写代码了!

需要按步骤进行以下操作:



1.使能 GPIO 端口时钟

2.初始化 GPIO 目标引脚为推挽输出

3.控制 GPIO 引脚输出高、低电平

//GPIOB时钟使能

rcu_periph_clock_enable(RCU_GPIOB);

//PB4配置成输出

gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);



写法一:



//引脚输出低电平

gpio_bit_reset(GPIOB, GPIO_PIN_3);



//引脚输出高电平

gpio_bit_set(GPIOB, GPIO_PIN_3);



//引脚输出低电平

gpio_bit_reset(GPIOB, GPIO_PIN_4);



//引脚输出高电平

gpio_bit_set(GPIOB, GPIO_PIN_4);





写法二:

//引脚输出低电平

gpio_bit_write(GPIOB, GPIO_PIN_3, RESET);

//引脚输出高电平

gpio_bit_write(GPIOB, GPIO_PIN_3, SET);

//引脚输出低电平

gpio_bit_write(GPIOB, GPIO_PIN_4, RESET);

//引脚输出高电平

gpio_bit_write(GPIOB, GPIO_PIN_4, SET);

代码如下:

f23a2ef3aa34464b98f204f021ff2f62.png

编译下载:

发现灯怎么常亮?

其实并不是灯常亮,只是PB3和PB4翻转太快了,人眼捕捉不到,那么我们需要加上一个延时函数,放慢他翻转的进程

好让我们观察到。

因为本节还没有学到滴答定时器,所以采用阻塞延时的方式:

//简单的延时函数

void Delay(__IO uint32_t nCount)

{

for(; nCount != 0; nCount--);

}

更改完以后的主函数:

3271c46e4c1b400eb24840478d937735.png

编译烧录!

d4b049c75c744213b03b4af556836987.jpeg

两个灯轮流闪烁,实验成功!

蜂鸣器实验

实现开发板上蜂鸣器发声,并用一个指示灯LED0指示蜂鸣器正在发声。

蜂鸣器硬件电路如下:

d0f8e174699646529ec9cc5851ec4642.png

d69b9115cce04da0aac04e284f71950f.png

根据硬件电路图可知,当 PC13 输出高电平的时候,蜂鸣器将发声, 当 PC13输出低电平的时候,蜂鸣器停止发声。因此对该IO引脚设置高低电平变化即可。

需要按步骤进行以下操作:



1.使能 GPIO 端口时钟

2.初始化 GPIO 目标引脚为推挽输出

3.控制 GPIO 引脚输出高、低电平



代码如下:


//GPIOB时钟使能

rcu_periph_clock_enable(RCU_GPIOC);

//PC12配置成输出

gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);



//引脚输出高电平

gpio_bit_set(GPIOC, GPIO_PIN_13);

Delay(0xfffff);

//引脚输出低电平

gpio_bit_reset(GPIOC, GPIO_PIN_13);

Delay(0xfffff);

72269cbe38f04828b4965a81d7d3af60.png

编译烧录!

发现蜂鸣器正常工作

实验成功!

按键输入实验

使用开发板上三个按键控制三LED灯亮灭。

按键硬件电路如下:

173d1e60626343dea7001501329f3cc9.png

如果硬件上已外部上拉或下拉,则选择浮空输入模式。

如果硬件外部没有上拉,则选择内部上拉模式。

PB5PB6PB7为低电平时,按键按下才有效。并且外部都没有上拉电阻,所以,需要在内部设置上拉。

因为在硬件上实现了硬件消抖,所以我们软件就不需要再设置消抖了。

关于为什么要按键消抖:

抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。这是一个很重要的时间参数,在很多场合都要用到。按键稳定闭合时间的长短则是由操作人员的按键动作决定的,一般为零点几秒至数秒。为确保CPU对键的一次闭合仅作一次处理,必须去除键抖动。在键闭合稳定时读取键的状态,并且必须判别到键释放稳定后再作处理。

9f66a37cce2d4ad69b9a02d120314237.png

需要按步骤进行以下操作:

1.使能 GPIO 端口时钟

2.初始化 GPIO 目标引脚为输入模式(由于硬件电路没有外部上拉电阻,这里使用内部上拉输入)

3.检测按键的状态

//GPIOB时钟使能

rcu_periph_clock_enable(RCU_GPIOB);

//PB5配置成上拉输入

gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_5);

//PB6配置成上拉输入

gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_6);



//PB7配置成上拉输入

gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_7);



//读取引脚电平

gpio_input_bit_get(GPIOB, GPIO_PIN_5);

//读取引脚电平

gpio_input_bit_get(GPIOB, GPIO_PIN_6);

//读取引脚电平

gpio_input_bit_get(GPIOB, GPIO_PIN_7);

这一次实验开始我们将会分模块文件进行!

建立文件夹在放在外设文件夹中:

a68f4a9ab7194ace8ba556149fdbc8fe.png

新建bsp_key文件夹,用来放置按键相关函数

6ee9017fc5ce4d66b4067ab3c94c3e9c.png

新建bsp_key.c和bsp_key.h分别放置按键代码源文件和头文件

d1d07c16ceb745a381b66e5981e9cdb0.png

同理新建bsp_led.c和bsp_key.h分别放置LED代码源文件和头文件

5d16cfef06a5440b9010717eded76525.png

dc2b9798dd164408b318fc6e1dfbdd38.jpeg

在编译器中包含

7c271685594946b5bfd18db070b2b665.png

将代码加入组别

4164140b4a8f451ca913dfcf4d1ab665.png

编译发现0个错误0个警告再继续:

a48db3b1dbe04a838217f341c6eed9af.png

文件结构建好以后,接下来就让我们正式编写代码!

先在两个.h文件中加入预编译指令(这里以bsp_key.c为例):

头:(这里以bsp_key.c为例)

4aa8bba5782041fbb97ca2793d654b1c.png

尾:(这里以bsp_key.c为例)

39183b830d5648a3be95c8898f11c184.png

在.h中放入库函数头文件(这里以bsp_key.c为例)

64ed95bf48ac4fd68c515a7208df3473.png

因为GPIO输入的函数包含在该库函数中,所以我们需要引用该函数!

为了方便后期的代码移植,随时更换引脚,这里采用宏定义的方式对每个变量进行单独代替

4e15b6161d7349e8af6dae0e9ae8e2b9.png

对按键宏进行定义

5821767e5a0e4b5da151734a7230a586.png

完成一会我们就可以去编写.c源文件了

首先需要在.c开头加入需要使用到的头文件和各自的.h文件(这里以bsp_key.c为例):

7fcc440e6cda4db68684e3b01a1ffeb2.png

然后是按键初始化函数

void Key_GPIO_Init(void)

{

// GPIO时钟使能

rcu_periph_clock_enable(KEY1_GPIO_CLK);

// 配置为内部上拉输入模式

gpio_init(KEY1_GPIO_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY1_GPIO_PIN);

}



然后是按键按下检测函数

uint8_t Key_Scan(uint32_t gpio_periph, uint32_t pin)

{

/*检测是否有按键按下 */

if(gpio_input_bit_get(gpio_periph, pin) == KEY_ON)

{

/*等待按键释放 */

while(gpio_input_bit_get(gpio_periph, pin) == KEY_ON);

return KEY_ON;

}

else

return KEY_OFF;

}

到此完成bsp_key.c的代码编写。

注意:函数在.c编写完后需要在其对应的.h文件中对函数进行声明,不然就无法在外部调用该函数!

5397ab18deb048a8b6543edfbbe7479a.png

完成bsp_key.c以及bsp_key.h的编写以后,让我们继续编写bsp_led.c以及bsp_led.h

首先是.h文件的编写:

预编译指令:

头:

d5d1d95eb8424d89b3bf80ea483c36c3.png

尾:

04cbd52e09ce4a7fb206fea569f427d5.png

然后是头文件调用:因为GPIO输出的函数包含在该库函数中,所以我们需要引用该函数!

065af94f11e04c30a25f9db41f0b9aed.png

为了方便后期的代码移植,随时更换引脚,这里采用宏定义的方式对每个变量进行单独代替

/* 定义LED连接的GPIO端口, 用户只需要修改下面的代码即可改变控制的LED引脚 */

#define LED_1_GPIO_PORT GPIOB /* GPIO端口 */

#define LED_1_GPIO_CLK RCU_GPIOB /* GPIO端口时钟 */

#define LED_1_GPIO_PIN GPIO_PIN_3



#define LED_2_GPIO_PORT GPIOB /* GPIO端口 */

#define LED_2_GPIO_CLK RCU_GPIOB        /* GPIO端口时钟 */

#define LED_2_GPIO_PIN GPIO_PIN_4



#define LED_3_GPIO_PORT GPIOC /* GPIO端口 */

#define LED_3_GPIO_CLK RCU_GPIOC /* GPIO端口时钟 */

#define LED_3_GPIO_PIN GPIO_PIN_12



#define LED_4_GPIO_PORT GPIOD /* GPIO端口 */

#define LED_4_GPIO_CLK RCU_GPIOD /* GPIO端口时钟 */

#define LED_4_GPIO_PIN GPIO_PIN_2

对寄存器编写,定义直接控制I/O口的宏

/* 定义控制IO的宏 */

#define LED1_ON gpio_bit_set(LED_1_GPIO_PORT,LED_1_GPIO_PIN)

#define LED1_OFF gpio_bit_reset(LED_1_GPIO_PORT,LED_1_GPIO_PIN)

#define LED1_TOG \

do{ \

if(gpio_output_bit_get(LED_1_GPIO_PORT,LED_1_GPIO_PIN)) \

gpio_bit_reset(LED_1_GPIO_PORT,LED_1_GPIO_PIN); \

else \

gpio_bit_set(LED_1_GPIO_PORT,LED_1_GPIO_PIN); \

}while(0)



#define LED2_ON gpio_bit_set(LED_2_GPIO_PORT,LED_2_GPIO_PIN)

#define LED2_OFF gpio_bit_reset(LED_2_GPIO_PORT,LED_2_GPIO_PIN)

#define LED2_TOG \

do{ \

if(gpio_output_bit_get(LED_2_GPIO_PORT,LED_2_GPIO_PIN)) \

gpio_bit_reset(LED_2_GPIO_PORT,LED_2_GPIO_PIN); \

else \

gpio_bit_set(LED_2_GPIO_PORT,LED_2_GPIO_PIN); \

}while(0)



#define LED3_ON gpio_bit_set(LED_3_GPIO_PORT,LED_3_GPIO_PIN)

#define LED3_OFF gpio_bit_reset(LED_3_GPIO_PORT,LED_3_GPIO_PIN)

#define LED3_TOG \

do{ \

if(gpio_output_bit_get(LED_3_GPIO_PORT,LED_3_GPIO_PIN)) \

gpio_bit_reset(LED_3_GPIO_PORT,LED_3_GPIO_PIN); \

else \

gpio_bit_set(LED_3_GPIO_PORT,LED_3_GPIO_PIN); \

}while(0)



#define LED4_ON gpio_bit_set(LED_4_GPIO_PORT,LED_4_GPIO_PIN)

#define LED4_OFF gpio_bit_reset(LED_4_GPIO_PORT,LED_4_GPIO_PIN)

#define LED4_TOG \

do{ \

if(gpio_output_bit_get(LED_4_GPIO_PORT,LED_4_GPIO_PIN)) \

gpio_bit_reset(LED_4_GPIO_PORT,LED_4_GPIO_PIN); \

else \

gpio_bit_set(LED_4_GPIO_PORT,LED_4_GPIO_PIN); \

}while(0)

定义完毕后,就可以直接调用以上函数对LED进行操作

写完bsp_led.h以后,我们转入bsp_led.c的源代码编写:

3f3b3881d21f48b1943fd2661481bfa0.png

//管脚复用时钟使能

rcu_periph_clock_enable(RCU_AF);

//PB4管脚默认是NJTRST,要当GPIO,需要重映射

gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);

// GPIO时钟使能

rcu_periph_clock_enable(LED1_GPIO_CLK);

rcu_periph_clock_enable(LED2_GPIO_CLK);

rcu_periph_clock_enable(LED3_GPIO_CLK);

rcu_periph_clock_enable(LED4_GPIO_CLK);

// 配置为推挽输出模式

gpio_init(LED1_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED1_GPIO_PIN);

gpio_init(LED2_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED2_GPIO_PIN);

gpio_init(LED3_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED3_GPIO_PIN);

gpio_init(LED4_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED4_GPIO_PIN);

// 初始化引脚为高电平

gpio_bit_set(LED1_GPIO_PORT, LED1_GPIO_PIN);

gpio_bit_set(LED2_GPIO_PORT, LED2_GPIO_PIN);

gpio_bit_set(LED3_GPIO_PORT, LED3_GPIO_PIN);

gpio_bit_set(LED4_GPIO_PORT, LED4_GPIO_PIN);

到此完成bsp_led.c的代码编写。

注意:函数在.c编写完后需要在其对应的.h文件中对函数进行声明,不然就无法在外部调用该函数!

12add39719ae4ab6953628960a76b516.png

以上完成代码编写

现在开始编写主函数:

先在头文件里面包含实验所需要的声明.h

0d2e476589824054923e49b5b97847ea.png

6fb26f912fea4071b2b4ff38eeb0dadf.png

实验发现三个按键成功控制各个LED,实验完成!

群号:621154399

有问题欢迎大家加入我们一起交流,这个群是开源性技术交流群。

stm32l431rct6的例程可以通过使用CUBEMX和HAL库来进行编写。首先,可以使用CUBEMX来生成基本的项目框架和初始化代码。通过输入或选择所需的主芯片型号(在这种情况下为STM32L431RCT6),然后选择对应的引脚和外设配置。接着,使用CUBEMX生成的代码结构来编写具体的功能代码。在这个例子中,如果想使用串口2,可以查看原理图,了解STM32L431RCT6的引脚连接关系。例如,串口2的引脚为PA2(USART2_TX)和PA3(USART2_RX)。可以根据这些信息来设置引脚并编写相应的串口通信代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [1.基础例程+STM32L431RCT6+LED闪烁实验.rar](https://download.csdn.net/download/qq_40873229/12318926)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [(实测可用)STM32CubeMX教程-STM32L431RCT6开发板研究串口通信(RS485)](https://blog.csdn.net/zhej2014/article/details/124539061)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不及你的温柔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值