使用GD32F103 MCU实现LED流水灯与按键控制

[复制链接]
3212|10
 楼主| Wordsworth 发表于 2024-10-13 14:10 | 显示全部楼层 |阅读模式

GD32F103系列是国产MCU中具有较高性价比的一款,采用Cortex-M3内核,主频高达108MHz,同时兼容STM32F103的引脚布局和外设资源。在本篇文章中,我们将介绍如何利用GD32F103实现LED流水灯效果,并通过按键进行控制,熟悉GPIO的基本用法与中断功能。



开发环境及工具
  • MCU型号:GD32F103C8T6
  • 开发工具:Keil uVision 5
  • 编程语言:C语言
  • 烧录工具:GD-Link仿真器
  • 硬件平台:GD32F103最小系统板



实现功能
  • 实现8个LED以流水灯形式循环点亮。
  • 按下按键时,切换LED的流水方向(顺时针或逆时针)。



硬件连接
  • LED:连接在GPIOA的0~7号引脚上。
  • 按键:连接在GPIOB的12号引脚,并配置为上拉输入模式。



代码实现
  1. #include "gd32f10x.h"

  2. // 定义LED和按键的GPIO端口及引脚
  3. #define LED_PORT GPIOA
  4. #define BUTTON_PORT GPIOB
  5. #define BUTTON_PIN GPIO_PIN_12

  6. // 定义全局变量用于控制LED方向
  7. volatile uint8_t led_direction = 1;  // 1: 顺时针, 0: 逆时针

  8. // 初始化GPIO
  9. void gpio_init(void) {
  10.     rcu_periph_clock_enable(RCU_GPIOA);  // 使能GPIOA时钟
  11.     rcu_periph_clock_enable(RCU_GPIOB);  // 使能GPIOB时钟

  12.     // 配置GPIOA的0~7为推挽输出模式
  13.     gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_ALL);
  14.     gpio_bit_reset(LED_PORT, GPIO_PIN_ALL);  // 关闭所有LED

  15.     // 配置GPIOB的12号引脚为输入模式并上拉
  16.     gpio_init(BUTTON_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, BUTTON_PIN);
  17. }

  18. // 初始化按键中断
  19. void exti_init(void) {
  20.     rcu_periph_clock_enable(RCU_AF);  // 使能AF时钟

  21.     gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_12);  
  22.     exti_init(EXTI_12, EXTI_INTERRUPT, EXTI_TRIG_FALLING);  // 设置下降沿触发

  23.     nvic_irq_enable(EXTI10_15_IRQn, 2, 0);  // 使能中断,优先级设为2
  24. }

  25. // 按键中断服务函数,切换LED方向
  26. void EXTI10_15_IRQHandler(void) {
  27.     if (exti_interrupt_flag_get(EXTI_12)) {
  28.         led_direction = !led_direction;  // 切换方向
  29.         exti_interrupt_flag_clear(EXTI_12);  // 清除中断标志
  30.     }
  31. }

  32. // LED流水灯逻辑
  33. void led_run(void) {
  34.     static uint8_t led_pos = 0;
  35.    
  36.     gpio_bit_reset(LED_PORT, GPIO_PIN_ALL);  // 关闭所有LED

  37.     // 根据方向点亮对应的LED
  38.     if (led_direction) {
  39.         gpio_bit_set(LED_PORT, (1 << led_pos));
  40.         led_pos = (led_pos + 1) % 8;  // 顺时针
  41.     } else {
  42.         gpio_bit_set(LED_PORT, (1 << led_pos));
  43.         led_pos = (led_pos == 0) ? 7 : (led_pos - 1);  // 逆时针
  44.     }
  45. }

  46. // 主函数
  47. int main(void) {
  48.     gpio_init();   // 初始化GPIO
  49.     exti_init();   // 初始化外部中断

  50.     while (1) {
  51.         led_run();  // 执行LED流水逻辑
  52.         delay_1ms(200);  // 延时200ms
  53.     }
  54. }

代码讲解
  • GPIO初始化:将LED连接的GPIOA引脚配置为推挽输出模式,按键连接的GPIOB引脚配置为上拉输入模式。
  • 按键中断处理:通过EXTI10_15_IRQHandler()切换LED流水方向,按键按下即触发中断。
  • LED流水逻辑:在led_run()函数中,根据当前方向依次点亮LED,并延时200ms。



功能扩展
  • LED颜色控制:可以增加RGB灯,实现颜色变化的流水效果。
  • PWM调光:通过PWM信号调节LED的亮度,增强视觉效果。
  • 多按键控制:增加多个按键,实现更多模式的切换,如闪烁模式或随机点亮。



小结通过这篇文章,我们学习了如何使用GD32F103 MCU实现LED流水灯和按键控制。该项目不仅让我们掌握了GPIO的使用,还了解了外部中断的配置与应用。这类基础项目对于深入理解MCU的外设资源和开发流程非常有帮助。

公羊子丹 发表于 2024-10-13 14:11 | 显示全部楼层
这个项目正好适合我练手GD32F103,代码也简单易懂。
周半梅 发表于 2024-10-13 14:11 | 显示全部楼层
我把按键换成了触摸模块,效果很酷。
帛灿灿 发表于 2024-10-13 14:11 | 显示全部楼层
有没有人试过把这个代码移植到STM32上?想比较一下。
童雨竹 发表于 2024-10-13 14:12 | 显示全部楼层
加了个蜂鸣器,每次按键的时候会有声音反馈,挺有趣的。
万图 发表于 2024-10-13 14:12 | 显示全部楼层
用这代码做了个小灯饰,放桌面上挺好看的。
Bblythe 发表于 2024-10-13 14:12 | 显示全部楼层
GD32这款芯片真的稳定,频率还比STM32高点。
Pulitzer 发表于 2024-10-13 14:13 | 显示全部楼层
我试了下用PWM调光,LED的效果比单纯亮灭好多了。
Uriah 发表于 2024-10-13 14:14 | 显示全部楼层
有没有人做过多个按键控制不同模式的?求个参考。
Clyde011 发表于 2024-10-13 14:14 | 显示全部楼层
用这个流水灯项目教新手入门还挺合适的,逻辑简单。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

161

主题

6119

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部