历史上的今天

今天是:2024年09月11日(星期三)

正在发生

2018年09月11日 | STM32延时函数的四种方法

发布者:ananan一二三四五 来源: eefocus关键字:STM32  延时函数 手机看文章 扫描二维码
随时随地手机看文章

单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。


1.普通延时法


(1)普通延时法1


这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要下一番功夫。下面的代码是在网上搜到的,经测试延时比较精准。


//粗延时函数,微秒

void delay_us(u16 time)

{    

   u16 i=0;  

   while(time--)

   {

      i=10;  //自己定义

      while(i--) ;    

   }

}

//毫秒级的延时

void delay_ms(u16 time)

{    

   u16 i=0;  

   while(time--)

   {

      i=12000;  //自己定义

      while(i--) ;    

   }

}

(2)普通延时法2


void delay(u16 num)

{

  u16 i,j;

  for(i=0;i

    for(j=0;j<0x800;j++);

}

2.SysTick 定时器延时


CM3 内核的处理器,内部包含了一个SysTick 定时器,SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。SysTick 在STM32的参考手册里面介绍的很简单,其详细介绍,请参阅《Cortex-M3 权威指南》。


 这里面也有两种方式实现:


(1)中断方式 如下,定义延时时间time_delay,SysTick_Config()定义中断时间段,在中断中递减time_delay,从而实现延时。


volatile unsigned long time_delay; // 延时时间,注意定义为全局变量

//延时n_ms

void delay_ms(volatile unsigned long nms)

{

    //SYSTICK分频--1ms的系统时钟中断

    if (SysTick_Config(SystemFrequency/1000))

    {

   

        while (1);

    }

    time_delay=nms;//读取定时时间

    while(time_delay);

    SysTick->CTRL=0x00; //关闭计数器

    SysTick->VAL =0X00; //清空计数器

}

//延时nus

void delay_us(volatile unsigned long nus)

{

 //SYSTICK分频--1us的系统时钟中断

    if (SysTick_Config(SystemFrequency/1000000))

    {

   

        while (1);

    }

    time_delay=nus;//读取定时时间

    while(time_delay);

    SysTick->CTRL=0x00; //关闭计数器

    SysTick->VAL =0X00; //清空计数器

}

 

    //在中断中将time_delay递减。实现延时

 

void SysTick_Handler(void)

{

    if(time_delay)

        time_delay--;

}

(2)非中断方式


主要仿照原子的《STM32不完全手册》。SYSTICK 的时钟固定为HCLK 时钟的1/8,在这里我们选用内部时钟源72M,所以SYSTICK的时钟为9M,即SYSTICK定时器以9M的频率递减。SysTick 主要包含CTRL、LOAD、VAL、CALIB 等4 个寄存器。


CTRL: SysTick控制和状态寄存器

LOAD: SysTick重装载值寄存器

VAL:    SysTick当前值寄存器

CALIB:SysTick校准值寄存器


对这几个寄存器的操作被封装到core_cm3.h中:

SysTick->CTRL

位段

名称

类型

复位值

描述

16

COUNTFLAG

R

0

如果在上次读本寄存器后systick已为0,则该位为1,若 读该位自动清零

2

CLKSOURCE

RW

0

0:外部时钟源 1:内部时钟

1

TICKINT

RW

0

0:减到0无动作;1:减到0产生systick异常请求

0

ENABLE

RW

0

systick定时器使能位

 

SysTick-> LOAD

位段

名称

类型

复位值

描述

23:0

RELOAD

RW

0

减到0时被重新装载的值

SysTick-> VAL

位段

名称

类型

复位值

描述

23:0

CURRENT

RW

0

读取时返回当前倒计数的值,写则清零,同时还会清除在systick控制及状态寄存器中的COUNTFLAG标志

SysTick-> CALIB 不常用,在这里我们也用不到,故不介绍了。

程序如下,相当于查询法。

//仿原子延时,不进入systic中断

void delay_us(u32 nus)

{

 u32 temp;

 SysTick->LOAD = 9*nus;

 SysTick->VAL=0X00;//清空计数器

 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源

 do

 {

  temp=SysTick->CTRL;//读取当前倒计数值

 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达

     SysTick->CTRL=0x00; //关闭计数器

    SysTick->VAL =0X00; //清空计数器

}

void delay_ms(u16 nms)

{

 u32 temp;

 SysTick->LOAD = 9000*nms;

 SysTick->VAL=0X00;//清空计数器

 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源

 do

 {

  temp=SysTick->CTRL;//读取当前倒计数值

 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达

    SysTick->CTRL=0x00; //关闭计数器

    SysTick->VAL =0X00; //清空计数器

}

三种方式各有利弊,第一种方式容易理解,但不太精准。第二种方式采用库函数,编写简单,由于中断的存在,不利于在其他中断中调用此延时函数。第三种方式直接操作寄存器,看起来比较繁琐,其实也不难,同时克服了以上两种方式的缺点,个人感觉比较好用。


关键字:STM32  延时函数 引用地址:STM32延时函数的四种方法

上一篇:STM32F030控制蜂鸣器
下一篇:STM32外部中断与各通道对应关系

推荐阅读

据外媒报道,沃尔沃正在研发一款概念车,其座舱体验与航空旅行较为类似。沃尔沃在其官网对360C概念车型做了如下描述:“想象下您需要在清晨赶到临近城市参加一场早会,这时您面临两种选择:从当地机场搭乘短途航班前往亦或是搭乘完全自动驾驶电动车出行方案,将您直接送达会议目的地,无需经历机场的签到、排队等待、航班延误、安检、及其他航空出行所需的...
SPI点亮OLED屏运行程序时发送几十次的数据总是会有看门狗的复位,后来发现程序每次都死在了while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)这里,查阅资料后发现是SPI有FIFO端口,参考SPI/I2S调试总结//用SPI1往OLED屏中写一个bituint8_t SPI1_WriteByte(uint8_t byte){while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == ...
Fluke 114、 116和117数字万用表 (DMM)的性能设计可使电气测量变得更安全、方便、更可靠。本产品应用文章主要介绍什么是双阻抗和电压检测,以及当万用表采用此类功能时对我们有哪些帮助。对于标准电气测量,一般使用高阻抗仪表较好,除非有杂散电压存在。有关阻抗的基本知识今天,市面上销售的绝大多数测量工业、电气、电子系统的数字式万用表输入回路...
智东西(公众号:zhidxcom)作者 | 健恩编辑 | 云鹏智东西9月11日报道,昨天,世界机器人大会再次在北京亦庄拉开帷幕,智东西记者一大早便跨越整个北京城来到这里打探这场大会的最新消息。世界机器人大会自2015年开始举办,迄今为止已成功举办过5次。它不仅是国内一年一度规模最大的机器人产业顶级展会,也是国内机器人产业风向的集中展示。智东西了解...

史海拾趣

问答坊 | AI 解惑

Protel99布线 自动分配Net

就是布线时,Place-Line工具应该自动根据说连接的Pad的net来分配这跟Line的Net 但是我画出来的线的Net属性均为空。应该怎么设置? [ 本帖最后由 hamiltoncai 于 2009-1-6 09:54 编辑 ]…

查看全部问答∨

请高人详细讲解一下这个电路的工作原理

我对继电器不熟,请高人详细讲解一下这个电路的工作原理,还有这个继电器的选用我也不熟悉。谢谢了!在线等,急,急!!…

查看全部问答∨

请教 并口JTAG仿真器问题.

现在手里有两个并口JTAG仿真器.一个是不隔离的, 一个是隔离式的. 已经在Bios里把LPT模式选为EPP/ECP模式. 现在我的目标板电源为3.3V, 并口JTAG2.6V. 我想加上两路电源在线仿真, 结果老是出错. 因为只用JTAG2.6V电源, 目标板的AD模块基准电压385为 ...…

查看全部问答∨

LM339的工作电压如何设定

本人是个菜鸟,在做循迹小车,用到了LM339,不知道它的工作电压如何设定,恳请各位大虾出手相助,谢谢了!…

查看全部问答∨

Keil C51的问题

想下个Keil C51工具吧,到了官网上还得填一系列的信息。 还可以从哪里下啊。 从其他地方下载过两个,结果都被骗了。 现在只能求助论坛里的坛友们了。…

查看全部问答∨

什么是伺服系统,伺服系统的应用案例

  什么是伺服系统?它的科学的定义有两个。一是实现输出变量精确地跟随或复现输入变量的控制系统;二是包含功率放大和反馈,使得输出变量的值紧密地响应输入量值的一种自动控制系统。我们来举个例子来进一步说明:伺服电动机、机械减速或耦合机构、 ...…

查看全部问答∨

数字式加速度传感器与MSP430的接口设计与应用

利用ADXL345三轴加速度传感器设计的一种可以检测运动物体瞬时的加速度可应用于检测运动物体的运动加速度; 基于MSP430的软件设计的IIC的一种数字式的加速度传感器可以很好的利用在检测物体的。 下面是我对ADXL345做的一些应用笔记,希望对大家有 ...…

查看全部问答∨

【学习心得-DLP一】初识DLP

DLP这个名词是早就听说来,现在火热的微投里面基本都是这个,但是具体的技术细节还是这次听在线课堂听到。看到里面的一面面小镜子,不由想起当年的研究生面试,正是说到来这种mems的显示技术,为什么亮度不好。当时拍拍脑袋说镜子翻转的时候各个像 ...…

查看全部问答∨

华为FPGA设计全套

很实用的资料 \0\0\0eeworldpostqq…

查看全部问答∨

错误151

开发板和仿真器在ccs3.3上可以连接 而用ccs4.2.2debug的时候会报错error151 说是仿真器无法连接 不知道怎么回事 希望高手指点 如下 Error connecting to the target: (Error -151 @ 0x0) This utility failed to open the adapter for a custom ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved