systick cubMax 初始化问题探索
下图所示就是输入给systick的时钟了,要实现毫秒级别的延时用systick实现
时钟树配置及其基础配置
通过调试观察,systick timer 会在HAL_Init()函数之后被初始化,会出现的结果如下图所示
通过对照发现:systick选择的是内核时钟(FCLK)
查阅发现:
所以说其实真正的systick时钟源是:
函数探索:
通过调试发现:执行HAL_Init()
本次配置实际时钟主频是72MHz,观察RELOAD数值为0x3E7F为16MHZ的主频,通过查阅SystemCoreClock的确也是,但是这样就不正确:
之后接着执行:SystemClock_Config():
时钟主频被赋值正确,同时RELOAD数值也被改变为71999,也就是说SystemClock_Confif()会对systick做第二次初始化,同时也是正确的初始化。
所以systick真正的配置是在SystemClock_Config()中的如下标红语句中
也就是说我们即使设置8分频也不影响systick寄存器的配置
实验如下:
配置并没有改变.所以可以证明System Tick TImer的确是在用FCLK时钟
当我们强制在寄存器框中设置为使用外部时钟源,如下图:取消勾选CLCKSOURCE,小灯频率变得很慢,应该就是为原来的1/8
要在cubMax上直接改为使用外部时钟还有待探索。
基于systick的延时函数HAL_Delay
要做成us的还需要自己写,只能以读的方式来做:
void delay_us(uint32_t nus) { uint32_t ticks; uint32_t told,tnow,tcnt=0; uint32_t reload=SysTick->LOAD; //LOAD的值 ticks=nus*72; //需要的节拍数,72M的systemCore系统时钟,则填入72 tcnt=0; told=SysTick->VAL; //刚进入时的计数器值 while(1) { tnow=SysTick->VAL; if(tnow!=told) { if(tnow<told)tcnt+=told-tnow;//这里注意一下SYSTICK是一个递减的计数器就可以了. else tcnt+=reload-tnow+told; told=tnow; if(tcnt>=ticks)break;//时间超过/等于要延迟的时间,则退出. } }; }