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;//时间超过/等于要延迟的时间,则退出.
        }  
    };                                         
}

 

posted @ 2020-12-02 18:29  cczyd  阅读(189)  评论(0编辑  收藏  举报