最近在学习HAL库,由于工作需要,甲方所要求的单片机只能通过MXcube生成HAL库程序,进度要求必须紧急上手,所以博主并没有系统的学习HAL,直接从标准库转HAL库,因此遇到一些移植上的小问题,比如这里的delay问题。
用过标准库的老铁们都知道,某知名团队(避免打广告,大家都知道是谁)在标准库的基础上,编写了一个delay文件,包括delay.c和delay.h中,这里面有1ms的延迟delay_ms()和1us延迟函数delay_us(),用起来可以说是肥肠方便!博主在习惯使用这两个函数之后,由于快速转入hal库,发现使用MXcube生成工程文件中,只弱定义了一个HAL_DELAY()函数,这个函数的功能是延迟1个ms,对于延迟1个us无能为力。于是博主开始了持续3个小时的折腾,终于解决了这个问题。留下这篇文章给有兴趣的老铁们避坑。
首先,楼主第一想到的肯定是修改库函数修改底层代码,众所周知,delay函数实际上就是系统“滴答”时钟实现的,因此更改“滴答”时钟配置,理论上很容易的嘛,最多就是动一动寄存器不就行了?于是找到配置“滴答”时钟的语句HAL_SYSTICK_Config(SystemCoreClock / 100000),这里的100000可以理解成分频系数,等于1时就是1秒钟中断,1000就是延迟1ms中断,等于1000000就是1us中断,不用想,楼主直接改成1000000!大功告成!!!
事实证明博主天真了。上述做法不可取。因为MXcube生成的工程文件,在其他外设上大量使用了HAL_DELAY()函数来实现1ms级的延迟,一旦修改底层代码,且不论你修改得对不对,其他外设一定会因此受干扰,整个程序是根本跑不起来的。所以想通过修改“滴答”时钟底层配置的方法貌似不可取;
楼主码到这,已经快下班了,中间还有一段很长的调试过程想撸出来分享,但是时间不允许了,容我赶紧先把修改方法发出来,省得我自己都忘了,下次有空的时候继续补充自己的修改经验。
步骤1:首先找到stm32f1xx_hal.c文件,在里面找到弱定义的HAL_Delay();即__weak void HAL_Delay(uint32_t Delay),在这个函数的下面增加一条自己编写的函数,可以直接复制过去:
void delay_us(uint32_t Delay){
uint32_t startval,tickn,delays,wait;
startval = SysTick->VAL;
tickn = HAL_GetTick();
//sysc = 72000; //SystemCoreClock / (1000U / uwTickFreq);
delays =Delay * 72; //sysc / 1000 * udelay;
if(delays > startval)
{
while(HAL_GetTick() == tickn)
{
}
wait = 72000 + startval - delays;
while(wait < SysTick->VAL)
{
}
}
else
{
wait = startval - delays;
while(wait < SysTick->VAL && HAL_GetTick() == tickn)
{
}
}
}
步骤2:在stm32f1xx_hal.h中记得声明一下这个函数。
步骤3:如有其他问题,按照编译器的提示简单修改就好了
先到这了,下班!!!!!!!!!!!!