用的复旦微的单片机,读取d18b20温度用到了sysTick的延时函数。
后来加其他功能时勾选了微库,结果d18b20就读不出数来了。用逻辑分析仪观测了下,读18b20的过程明显比之前的程序长了。
一开始以为是其他中断影响了,最后发现是微库的问题。
那么,微库为什么会影响stsTick?
离线
https://zhuanlan.zhihu.com/p/1951087973048259773
根据这边文章,M0单片机没有除法器,执行除法需要时间。
/*** @brief us级延时函数(阻塞模式)
* @param count 计数周期
* @note 延时函数最大值受限于SysTick重载值寄存器的最大值0xFFFFFF(16777216)
* @note 该函数为weak函数,用户可选择其他定时器重新定义实现该函数
* @retval 无
*/__weak void std_delayus(uint32_t count)
{
count = STD_DELAY_US * count;
count = count > 16777216 ? 16777216 : count;
SysTick->LOAD = count - 1;
SysTick->VAL = 0;
while(!((SysTick->CTRL >> 16) & 0x1));
}
#defineSTD_DELAY_US(SystemCoreClock/1000000)
/**<STD中用于计时的基础值,与计时周期有关*/但是,我用的单片机,自带库里的延时函数,用到的是右移操作,而不是除法,为什么也会造成不准?
__WEAK void FL_DelayUs(uint32_t count)
{
count = FL_DELAY_US * count;
count = count > 16777216 ? 16777216 : count;
SysTick->LOAD = count - 1;
SysTick->VAL = 0;
while(!((SysTick->CTRL >> 16) & 0x1));
}---------------------------
晕,发现了:
#define FL_DELAY_US (SystemCoreClock/1000000)最近编辑记录 Gentlepig (2026-07-25 13:54:15)
离线
用perf_counter就可以解决问题了
离线
最后定位到是SystemCoreClock/1000000 这个除法运算导致的,使用微库后会让除法运算执行的更慢。
上面提到MicroLIB虽然减少code size,但是有些函数会执行的更慢,这次遇到的问题恰恰就对应这一条。这其实对应的用时间换空间的概念,对于某些运算,>MicroLIB执行时间变长了,换回的好处是空间占用更小。实际使用中需要在空间和时间上做一定的取舍。
ARM Cortex-M0+没有硬件除法器,除法是相对复杂的操作,相比加法、减法和乘法,需要更多的CPU周期才能完成。
没明白,为什么使用微库会增加除法运算的时间。
之所以使用微库,就是为了使用printf重定向串口这个功能。貌似不勾选微库,体积更小吧?
离线