STM32延时函数详解及使用方法

目录

前言

一、

1.for/while循环延时

2.汇编延时

3.SYSTICK定时器延时

SYSTICK相关寄存器

总结


前言

        延时函数是嵌入式中最常用到的测试手段,发现有许多方式可以达到延时的目的,所以这里做一点小总结。


一、

1.for/while循环延时

代码如下:

#define SystemCoreClock  (26000000U) //时钟频率26M

void delay(int time)
{
    for (int i = 0; i < time; i--);
}

时间公式:延时 = time * 2 * 机器周期 * 指令周期 *(1/26M)

链接:*2的原因

2.汇编延时

代码如下:

/*汇编延时*/
#define SystemCoreClock  (26000000U) //时钟频率26M

__asm void
SysCtlDelay(unsigned long ulCount)
{
    subs    r0,#1;
    bne     SysCtlDelay;
    bx      lr;
}

//us级延时,延时n微秒
SysCtlDelay(n*(SystemCoreClock/(3*1000000))) 

SystemCoreClock: 为单片机时钟频率,使用时需要更改。(一般System_CMSDK_CMx.h里已经设置好了)

SysCtlDelay:ulCount = n*(SystemCoreClock/(3*1000000))

        SystemCoreClock/(3*1000000)是因为SysCtlDelay内有3条指令,公式结果为1us。

3.SYSTICK定时器延时

代码如下:

/*SYSTICK定时器延时*/

#define SystemCoreClock     (26000000U) //这里是系统时钟,需要根据芯片进行修改
#define MS_DELAY            (1000U)
#define US_DELAY            (1000000U)

void delay_ms(uint8_t ms)    //ms延时函数
{
    /* systick delay ms*/
    SysTick->CTRL = (1 << 2);         
    SysTick->LOAD = SystemCoreClock / MS_DELAY * ms;
    SysTick->VAL = 0;
    SysTick->CTRL = (1 << 2) | (1 << 0);
    while ((SysTick->CTRL & (1 << 16)) == 0);
    SysTick->CTRL = (1 << 2);
}

SYSTICK相关寄存器

SysTick控制和状态寄存器(STK_CTRL)

        一般用来控制systick定时器的开关,使用时需要根据相应的芯片更改相应的位操作。 

CTRL寄存器
寄存器 作用
16 COUNFLAG 定时器倒计数到0时,该为由硬件自动置1
2 CLKSOURCE 选择时钟分频:1:AHB   0:AHB/(8 or 2)
1 TICKINT 定时器异常请求使能:0:不产生中断,1:产生中断
0 TICKINT 使能计数器 0:失能,1:使能

SysTick自动重装载值寄存器(STK_LOAD)

        计数器初始值,自定义,需要自己计算,公式一般如上所示。LOAD的值决定一个时钟频率内产生的中断次数,中断次数为MS_DELAY。

        范围一般为:0x00000001~0x00FFFFFF。

SysTick当前值值寄存器(STK_VAL)

        每次从LOAD中获取值,直到为0。

相比起前两种,定时器的延时更准确,但是,由于是系统时钟控制,记得使用前保证系统时钟的频率准确。


总结

        前两种时钟是CPU时钟,后一个为系统时钟,一般情况下CPU时钟是等于系统时钟的,但当系统时钟出错时,两者便不相等了。写这篇BLOG的目的是在工作中凑巧碰到了需要测量时钟是否准确的情况,所以写了下来分享给其他需要的伙伴。

        PS:本人第一篇BLOG                                         2023/06/10  —-BeMi·Aino

物联沃分享整理
物联沃-IOTWORD物联网 » STM32延时函数详解及使用方法

发表评论