STM32F4XX - 系统定时器(SysTick)设置

SysTick: cortex_m4 核心内置的系统定时器(系统定时器,又名系统嘀嗒定时器). 定时器的设置需要参考cortex_m4的技术文档。

附上时钟树一张:

上面图中可以看出时钟HSE经过PLL倍频后得到PLLCLK,SYSCLK可以选择使用HSI、HSE或者PLLCLK作为系统时钟(SYSCLK,设置方式可见系统时钟设置章节)。AHB的时钟通过对SYSCLK分频后得到(一般分频系数设置为1,即使用SYSCLK时钟)。AHB时钟后又经过分频得到APBX的时钟(程序中可设置为2和4等),存储器、DMA以及cortex_m4系统定时器的时钟(可设置为1和8).以上设置都可以根据实际情况进行。

下面结合实际代码进行说明:

bash 复制代码
void delay_init(u8 SYSCLK)
{
        u32 reload;
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); 
        fac_us=SYSCLK;                                                  //不论是否使用OS,fac_us都需要使用
        reload=SYSCLK;                                                  //每秒钟的计数次数 单位为M         
        reload*=1000000/configTICK_RATE_HZ;             //根据configTICK_RATE_HZ设定溢出时间
                                                                                        //reload为24位寄存>器,最大值:16777216,在168M下,约合0.0998s左右  
        fac_ms=1000/configTICK_RATE_HZ;                 //代表OS可以延时的最少单位          
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断
        SysTick->LOAD=reload;                                   //每1/configTICK_RATE_HZ断一次  
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK     
}  

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);

SYSCLK = 168;
这个是设置HCLK作为系统滴答的时钟,可选择SysTick_CLKSource_HCLK或者SysTick_CLKSource_HCLK_Div8。
系统时钟章节我们计算了HCLK时钟为168MHz。所以延时1us,需要168个节拍时钟周期,所以设置us影响因子为168。比如需要延时3us,那么需要计数的节拍数为3*168 个。
fac_us=SYSCLK;

fac_ms=1000/configTICK_RATE_HZ; //代表OS可以延时的最少单位
因为我们使用了rtos系统,系统使用的滴答频率是1000Hz,我们延时可以使用系统的延时接口,所以设置ms影响因子为1.
//不论是否使用OS,fac_us都需要使用

reload=SYSCLK; //每秒钟的计数次数 单位为M

reload*=1000000/configTICK_RATE_HZ; //根据configTICK_RATE_HZ设定溢出时间
这个是装载到计数器的计数值。因为1us需要168个节拍,所以这里直接将reload值设定为能够计数到1ms的值,也就是168000.(个人觉得这个值设定多少不重要)

上面是系统定时器SysTick的初始化及其影响因子的确定。下面将对延时函数做具体的分析说明。

bash 复制代码
//延时nus
//nus:要延时的us数.     
//nus:0~204522252(最大值即2^32/fac_us@fac_us=168)                                                                          
void delay_us(u32 nus)
{               
        u32 ticks;
        u32 told,tnow,tcnt=0;
        u32 reload=SysTick->LOAD;                               //LOAD的值               
        ticks=nus*fac_us;                                               //需要的节拍数 
        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;                   //时间超过/等于要延迟的时间,则退出.
                }  
        };                                                                              
}  

上面是us的延时函数,根据影响因子计算出需要的节拍数(ticks=nus*fac_us;),比如需要延时3us,那么需要节拍数3x168个。不断地从计数器中取值,累加并跟需要的节拍数3x168相比较,如果超过节拍数,则表示延时达到并退出。

bash 复制代码
void delay_ms(u32 nms)
{       
        if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
        {               
                if(nms>=fac_ms)                                         //延时的时间大于OS的最少时间周期 
                { 
                        vTaskDelay(nms/fac_ms);                 //FreeRTOS延时
                }
                nms%=fac_ms;                                            //OS已经无法提供这么小的延时了,采用
普通方式延时    
        }
        delay_us((u32)(nms*1000));                              //普通方式延时
}

ms的延时相对更简单了,先使用实时系统的延时函数vTaskDelay进行ms的延时,然后再使用us的函数接口进行us的延时处理.

相关推荐
wenchm10 分钟前
细说STM32F407单片机通过IIC读写EEPROM 24C02
stm32·单片机·嵌入式硬件
1101 110121 分钟前
STM32-笔记14-排队控制系统
笔记·stm32·嵌入式硬件
最后一个bug2 小时前
rt-linux中使用mlockall与free的差异
linux·c语言·arm开发·单片机·嵌入式硬件·算法
musir12 小时前
寄存器控制LED灯亮
单片机
JaneZJW3 小时前
Proteus仿真——《51单片机AD和DA转换器的设计》
单片机·嵌入式硬件·51单片机·proteus
NEWEVA__zzera225 小时前
利用光耦来隔离485芯片与串口引脚,实现自动收发485电路
单片机·嵌入式硬件
m0_748240545 小时前
STM32第十一课:STM32-基于标准库的42步进电机的简单IO控制(附电机教程,看到即赚到)
stm32·单片机·嵌入式硬件
温柔的男孩像海洋丶5 小时前
vscode的keil assistant 中搜索不到全局变量
ide·vscode·单片机
沐欣工作室_lvyiyi6 小时前
基于单片机的多功能智能小车(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·单片机毕业设计
鸿喵小仙女6 小时前
C# WPF读写STM32/GD32单片机Flash数据
stm32·单片机·c#·wpf