打印
[应用方案]

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

[复制链接]
113|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
GPIO, HC, IO, LED, gp
代码的功能是 控制 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 上高效运行!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

64

主题

773

帖子

1

粉丝