【记录】实现delay

1. 实现方法

处理器有一个24位的系统定时器,SysTick。该定时器向下计数。计数到0后,重新从STK_LOAD寄存器中重载计数值,继续向下计数。使用SysTick的优点是,不用占用中断和定时器资源。

2. 相关寄存器

STK_CTRL:
0-bit,计数器使能位;
1-bit,选择时钟源
16-bit,计数到0后,该标志位被置1

STK_LOAD
计数值重载寄存器,当计数值计数到0后,将从该寄存器中重新加载计数值。

STK_VAL
保存当前计数值

这里写图片描述

#include "delay.h"

static u8 fac_us = 0;
static u16 fac_ms = 0;

void delay_init(u8 sys_clock)
{
    SysTick->CTRL &= ~(1<<2);  //external clock
    fac_us = sys_clock/8;       //AHB/8
    fac_ms = (u16)fac_us*1000;
}

//n < 2^24/fac_us
//sys_clock = 168MHz, fac_us=21MHz, 2^24/fac_us=798915
void delay_us(u32 n)
{
    u32 temp;
    SysTick->LOAD = n*fac_us;       //connter
    SysTick->VAL = 0;               //clear current value
    SysTick->CTRL = 0x01;           //start timer

    do
    {
        temp = SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16))); //16-bit will be set 0 when current value is 0

    SysTick->CTRL = 0x00;   //stop timer
    SysTick->VAL = 0x00;    //clear current value
}

//@sys_clock=168MHz, n < 798
void delay_ms(u16 n)
{
    u32 temp;
    SysTick->LOAD = (u32)n*fac_ms;
    SysTick->VAL = 0x00;
    SysTick->CTRL = 0x01;

    do
    {
        temp = SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16))); //16-bit will be set 0 when current value is 0

    SysTick->CTRL = 0x00;   //stop timer
    SysTick->VAL = 0x00;    //clear current value
}

实现更长的延时(超过798.915ms)。方法是多次调用上面实现的delay_ms。如果需要延时5s。5000ms>798.915ms,所以无法使用delay_ms。按照delay_long_ms的方法,每一个repeat可以延时540ms,repeat=5000/540=9, remain = 5000%540=140。对于用户而言,直接调用

delay_long_ms(5000);

程序中使用540的原因。理论上这个数值越接近798.915越好,但是我们要注意,798915这个值是按照系统时钟168MHz下计算出来的。

2^24*8/clock

而有些时候,系统可以工作在248MHz频率下,超频使用。此时2^24*8/248=541200。考虑到驱动的兼容性,选择540作为单次最大延时时间。

void delay_long_ms(u16 n)
{
    u8 repeat = n / 540;
    u16 remain = n % 540;

    while(repeat)
    {
        delay_ms(540);
        repeat--;
    }
    if(remain)  delay_ms(remain);
}

参考

STM32F3与 F4 系列 Cortex M4 内核编程手册
STM32F4 开发指南(寄存器版)
STM32F4xxx中文参考手册

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值