泉州优化seo网站关键词优化,美工培训中心,腾讯 微商 网站 建设,甘南网站建设公司今天遇到个很奇怪的问题, 不知道为什么, 单片机运行一会之后, 系统就没反应了, 经过调试发现, 系统卡在HAL_Delay()中了. 之前也遇到过这个问题后来把HAL_Delay 去掉了. 然后发现不行, 还是得有它.不然发串口数据发的太快会乱掉. 得慢点发.
然后调试到HAL_Delay()方法的内部发…今天遇到个很奇怪的问题, 不知道为什么, 单片机运行一会之后, 系统就没反应了, 经过调试发现, 系统卡在HAL_Delay()中了. 之前也遇到过这个问题后来把HAL_Delay 去掉了. 然后发现不行, 还是得有它.不然发串口数据发的太快会乱掉. 得慢点发.
然后调试到HAL_Delay()方法的内部发现 HAL_GetTick( )函数一直返回
__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函数里while ((HAL_GetTick() - tickstart) wait){}
}
再跟踪发现 HAL_GetTick() - tickstart 永远等于0 这就很奇怪了. 于是再深入看一下HAL_GetTick()函数. 代码如下
__weak uint32_t HAL_GetTick(void)
{return uwTick;
}也就是说, uwTick 不再更新了. 数值永远是某个固定数值. 那uwTick 到底是怎么更新的呢? 最后发现 在这里更新的.
__weak void HAL_IncTick(void)
{ uwTick uwTickFreq;
}调试发现 uwTickFreq 0 也就是说, uwTick 不再增加了. 所以导致外层的while死循环了. 那么uwTickFreq又是什么时候变成0的呢? 我跟踪了很久也没有拦截到uwTickFreq 是什么时候更新的. keil工具也拦截不到是什么时候更新的. 最后索性, 给uwTickFreq 一个默认值. 只要发现 uwTickFreq 为0了. 就给它个默认值., 然后就把代码改成了下面这样的函数. 由于源代码函数是__weak 的, 也就是说, 可以被覆盖的. 于是我在自己的main.c 文件代码中重新写了一下. 如下:
void HAL_IncTick(void)
{if(uwTickFreq0){uwTickFreq HAL_TICK_FREQ_DEFAULT;}uwTick uwTickFreq;
}
如果不在乎延迟时间的精准度, 可以考虑.写成下面的这种, 更快一点
void HAL_IncTick(void)
{ uwTick HAL_TICK_FREQ_DEFAULT;
} 后来经过调试, 我猜测是因为定时器的停止和开启导致的. 具体中间的原因就不再深入细究了. 有时间精力的朋友可以再追踪下去. 找到原因欢迎分享.
我用的是STM32F103C8T6 , 其中的定时器TIM3用来驱动ADC的采样频率. 在循环中不停的停止和开启Tim3. 我估计是因为这个原因导致的. uwTickFreq 重新计算.
而且我这里做了自动计算Tim3的自动重载计数值. 估计是跟它有关. 具体的不再深入探究了. 延迟时间就写死吧…