刚开始学习STM32,在使用STM32CubeIDE,以STM32F103为基础开学。安装了STM32Cube_FW_F1_V1.8.0,这两天把STM32F1 HAL的基础部分看完了,对于HAL_Delay()这个功能有一些疑虑: 该函数是基于Systick计数器实现的,把Systick计数器组态为每1ms自动重载一次,同时启动中断程序,给32位无符号全局参数uwTick累加1,也就是说uwTick相当于每1ms会自动+1,在HAL_Delay()函数中等待从调用它开始到目前uwTick增加的数,来实现以ms位单位的延时,具体函数如下: __weak void HAL_Delay(uint32_t Delay) { uint32_t tickstart = HAL_GetTick(); uint32_t wait = Delay; /* Add a freq to guarantee minimum wait */ if (wait < HAL_MAX_DELAY) { wait += (uint32_t)(uwTickFreq); } while ((HAL_GetTick() - tickstart) < wait) { } } 但是程序里没有对uwTick做上溢回零后的处理和保护,那么当在上溢发生前启动延时,而且上溢前延时还没有达到,而发生了上溢则uwTick又从零来时累计了,那么该延时就不会完成,就可能会触发看门狗而其他重启了。 举例来说:无符号32位数最大值位4,294,967,296(不到一点50天),当uwTick累计到接近最大值的时候,比如说差1ms时启动了延时5ms,那么按照上面的函数就永远都无法跳出while循环了。 而一般来说,在功能测试期间,很少会让系统连续跑超过50天进行测试,而即使有超过50天的连续测试,如果没有在上面的极端情况发生,也很少有机会发现这个bug,但是这种可能性还是存在的,如果使用的延时功能够多,那么在系统投入实际运行后,这种问题一定会发生。 建议在delay函数里做一点修正:只要判断uwTick是否有上溢,在做相应的保护就可以了。 由于我是做工业控制系统的,所以对于系统连续运行性能要求比较高,所以在此提出一点疑虑和建议。当然了对于民用或者一些对于连续运行要求不高的场合,这种问题就无所谓了。 |
今天特意测试了一下HAL_Delay,当uwTick发生上溢后从0开始计数后,由于是使用的无符号数,所以小数字-大数字,会变成一个更大的数,所以结果肯定大于等待值,系统不至于重启,只是延时时间会变得不准确而已。 |
其实应该理解为符号数,这样完全不用考虑溢出问题,1-0xffffffff=1-(-1)=2; |
复习一下计算机组成原理就明白了 |
【MCU实战经验】+ STM32F103ZET6开发板DIY(附件包含原理图PCB文件)
STM32F103系列的怎么加密呀
启航开发板(STM32F103VET6)的原理图
AN2586_STM32F10xxx硬件开发:使用入门
冗余双CAN现场总线STM32F105开发板KeilC++源程序
STM32F107VCT6金龙开发板实验例程下载地址
stm32f103 驱动Lis3mdl三轴传感器代码
STM32F103 CAN测试代码
【开发工具】STM32神舟II号开发板(STM32F103VCT6)详细介绍&全面资料
Keil STM32F103仿真产生波形