自学内容网 自学内容网

梁山派-GD32F470ZGT6,GD32F4xx_Firmware_Library_V3.2.0.7z,串口输出,打印两次

结论:延时时间太短,复位两次

问题描述

在这里插入图片描述
打印两次,如图 👆

问题查找

找了半天,我用别人的代码,就打印一次,然后,一行一行复制,排查问题
结果,代码都一样,还是输出两次

后来,试着试着,会不会是标准库的问题?
结果将别人的标准库,全复制过去,结果:打印一次,好了 !!!
经排查,是 Firmware/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c 文件

我的版本:GD32F4xx_Firmware_Library_V3.2.0.7z

之前

#define RCU_MODIFY      {volatile uint32_t i; \
                         RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; \
                         for(i=0;i<50000;i++); \
                         RCU_CFG0 |= RCU_AHB_CKSYS_DIV4; \
                         for(i=0;i<50000;i++);}
                         
void SystemInit (void)
{
    /* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
#endif
    /* Reset the RCU clock configuration to the default reset state */
    /* Set IRC16MEN bit */
    RCU_CTL |= RCU_CTL_IRC16MEN;

    RCU_MODIFY

现在

#define RCU_MODIFY(__delay)     do{                                     \
                                    volatile uint32_t i;                \
                                    if(0 != __delay){                   \
                                        RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; \
                                        for(i=0; i<__delay; i++){       \
                                        }                               \
                                        RCU_CFG0 |= RCU_AHB_CKSYS_DIV4; \
                                        for(i=0; i<__delay; i++){       \
                                        }                               \
                                    }                                   \
                                }while(0)
void SystemInit (void)
{
    /* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
#endif
    /* Reset the RCU clock configuration to the default reset state */
    /* Set IRC16MEN bit */
    RCU_CTL |= RCU_CTL_IRC16MEN;
    while(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){
    }
    RCU_MODIFY(0x50);

可以看到,之前是 50000,后来改成 0x50,延时时间变小

分析代码

启动文件,经过复位,进入 SystemInit

在这里插入图片描述

之后,会进入 RCU_MODIFY(0x50);,里面有
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;

在这里插入图片描述
BITS(4, 7):((0xFFFFFFFF UL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end))))
= ((0xFFFFFFFFUL << (4)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(7))))
= ((0x FFFF FFFFUL << (4)) & (0xFFFF FFFF UL >> (24)))
= 0x 0000F FFFF FFF0 & 0x0000 00FF
= 0xF0=1111 0000

RCU_AHB_CKSYS_DIV2:8 << 4 = 80 & 0xF0 = 1000 0000 & 1111 0000 = 1000 0000 = 128(2^7)
RCU_AHB_CKSYS_DIV4:9 << 4 = 90 & 0xF0 = 1001 0000 & 1111 0000 = 1001 0000 = 144(2^7 + 2^4 = 128 + 16 = 144)
第八位 和 第五位

在这里插入图片描述

为什么延迟时间减少会导致复位问题?

  • 原始延迟(50000次):这是一个较长的延迟时间,通常足够让时钟稳定下来。
    • 虽然延迟较长,但可以确保系统在时钟切换后,能够稳定地等待,并防止不稳定状态导致的复位
  • 减少延迟(0x50次):减少延迟时间后,时钟切换后没有等待足够的时间来让硬件稳定。这种过快的切换可能导致系统在时钟尚未完全切换和稳定时就开始进行其他操作,触发了复位机制。

原文地址:https://blog.csdn.net/qq_30763385/article/details/144355540

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!