【STM32】的延时函数

文章详细介绍了嵌入式系统中常用的三种延时方法,包括基于for/while循环的延时,使用汇编语言实现的延时,以及利用SYSTICK定时器进行精确延时。每种方法都提供了代码示例,并解析了其工作原理和时间计算公式。SYSTICK定时器延时被认为更为准确,但依赖于系统时钟的准确性。
摘要由CSDN通过智能技术生成

目录

前言

一、

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

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
引用\[1\]和引用\[2\]提供了一种使用中断方式实现延时的方法。在这种方法中,首先需要定义一个全局变量time_delay来表示延时的时间。然后使用SysTick_Config()函数来定义中断的时间段,通过中断中递减time_delay来实现延时。具体的延时函数包括delay_ms()和delay_us(),分别用于延时指定的毫秒数和微秒数。在中断处理函数SysTick_Handler()中,如果time_delay不为0,则将其递减。最后,在延时结束后,需要关闭计数器和清空计数器的值。 所以,如果你想在STM32中实现延时函数delay,你可以使用中断方式来实现。具体的代码可以参考引用\[2\]中的示例代码。 #### 引用[.reference_title] - *1* [STM32延时函数的四种方法](https://blog.csdn.net/huaweibiancheng3/article/details/124956486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32延时函数的三种方法](https://blog.csdn.net/u010312937/article/details/103855115)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [STM32延时函数的四种方法:普通延时(2种)、SysTick 定时器延时(2种)](https://blog.csdn.net/weibo1230123/article/details/81136564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值