结合国际经验 发表于 2025-3-30 01:33

控制 HC32F10x 开发板上的 GPIOB 5 号引脚,模拟 LED 闪烁

代码的功能是 控制 HC32F10x 开发板上的 GPIOB 5 号引脚,模拟 LED 闪烁,每 1.5 秒切换一次状态。以下是代码的优化和问题分析:

代码优化与问题分析
1. delay(u16 n) 函数的低效性
delay 使用 双层 for 循环 来进行延时,这种方式不精确,并且受编译器优化影响,可能会导致时间不稳定。

下面将使用 SysTick 定时器 进行精准延时,而不是 for 循环。

SysTick 延时实现(精准 1ms 计时)
#include "hc32f10x.h"

void SysTick_DelayMs(uint32_t ms) {
    SysTick->LOAD = SystemCoreClock / 1000 - 1;// 1ms
    SysTick->VAL= 0;                           // 清空计数器
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;

    while (ms--) {
      while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); // 等待计数结束
    }

    SysTick->CTRL = 0;// 关闭 SysTick
}
使用方式

c
复制
编辑
SysTick_DelayMs(1500);// 延时 1500ms


结合国际经验 发表于 2025-3-30 01:34

GPIO_Configuration 初始化建议
你的 GPIO_Configuration 已经正确配置了 GPIOB_Pin_5 为 推挽输出,这点没问题。

但 GPIO 复用设置(AFIO)并不需要在这里启用,除非要修改 JTAG/SWD(但这部分被注释掉了)。

推荐初始化后默认设定 GPIO 为高电平(LED 默认熄灭)。

结合国际经验 发表于 2025-3-30 01:34

优化后代码

c
复制
编辑
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET); // 默认关闭 LED(假设低电平点亮)
}

结合国际经验 发表于 2025-3-30 01:34

优化后完整代码
c
复制
编辑
#include "hc32f10x.h"

void SysTick_DelayMs(uint32_t ms);
void RCC_Configuration(void);
void GPIO_Configuration(void);

int main(void)
{
    RCC_Configuration();
    GPIO_Configuration();

    while (1)
    {
      GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_RESET); // 低电平点亮
      SysTick_DelayMs(1500); // 延时 1500ms

      GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET); // 高电平熄灭
      SysTick_DelayMs(1500); // 延时 1500ms
    }
}

void SysTick_DelayMs(uint32_t ms)
{
    SysTick->LOAD = SystemCoreClock / 1000 - 1;// 1ms
    SysTick->VAL= 0;                           // 清空计数器
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;

    while (ms--) {
      while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); // 等待计数结束
    }

    SysTick->CTRL = 0;// 关闭 SysTick
}

void RCC_Configuration(void)
{
    RCC_HSEConfig(RCC_HSE_ON);
    while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
   
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
}

void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET); // 默认关闭 LED
}
优化后的改进点
✅ 使用 SysTick 定时器进行精准延时,避免 for 循环误差
✅ RCC 配置改进,确保系统时钟正确初始化
✅ GPIO 初始化时默认设定高电平,防止 LED 乱闪
✅ 减少不必要的 AFIO 时钟启用,优化功耗

结论
这样优化后,代码运行更加稳定、功耗更低、时钟管理更精准,适合在 HC32F10x 上高效运行!
页: [1]
查看完整版本: 控制 HC32F10x 开发板上的 GPIOB 5 号引脚,模拟 LED 闪烁