iar stm32_STM32延时函数的四种方法

关注、星标公众,不错过精彩内容02be5b7c8b699c7766044e94cd18eb5f.png

单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us()和毫秒级delay_ms()。本文基于STM32F207介绍4种不同方式实现的延时函数。d16958190950ed865867862eb44b79ee.gif普通延时这种延时方式应该是大家在51单片机时候,接触最早的延时函数。这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,在某些编译器下,代码会被优化,导致精度较低,用于一般的延时,对精度不敏感的应用场景中。
//微秒级的延时void delay_us(uint32_t delay_us){      volatile unsigned int num;  volatile unsigned int t;    for (num = 0; num < delay_us; num++)  {    t = 11;    while (t != 0)    {      t--;    }  }}//毫秒级的延时void delay_ms(uint16_t delay_ms){      volatile unsigned int num;  for (num = 0; num < delay_ms; num++)  {    delay_us(1000);  }}
上述工程源码仓库:https://github.com/strongercjd/STM32F207VCT6/tree/master/02-Template(提示:公众号不支持外链接,请复制链接到浏览器下载)d16958190950ed865867862eb44b79ee.gif定时器中断

定时器具有很高的精度,我们可以配置定时器中断,比如配置1ms中断一次,然后间接判断进入中断的次数达到精确延时的目的。这种方式精度可以得到保证,但是系统一直在中断,不利于在其他中断中调用此延时函数,有些高精度的应用场景不适合,比如其他外设正在输出,不允许任何中断打断的情况。

STM32任何定时器都可以实现,下面我们以SysTick 定时器为例介绍:

初始化SysTick 定时器:
/* 配置SysTick为1ms */RCC_GetClocksFreq(&RCC_Clocks);SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);

中断服务函数:

void SysTick_Handler(void){  TimingDelay_Decrement();}void TimingDelay_Decrement(void){  if (TimingDelay != 0x00)  {     TimingDelay--;  }}

延时函数:

void Delay(__IO uint32_t nTime){  TimingDelay = nTime;  while(TimingDelay != 0);}
上述工程源码仓库:https://github.com/strongercjd/STM32F207VCT6/tree/master/02-Template(提示:公众号不支持外链接,请复制链接到浏览器下载)d16958190950ed865867862eb44b79ee.gif查询定时器

为了解决定时器频繁中断的问题,我们可以使用定时器,但是不使能中断,使用查询的方式去延时,这样既能解决频繁中断问题,又能保证精度。

STM32任何定时器都可以实现,下面我们以SysTick 定时器为例介绍。

STM32的CM3内核的处理器,内部包含了一个SysTick定时器,SysTick是一个24位的倒计数定时器,当计到0时,将从RELOAD寄存器中自动重装载定时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。

SYSTICK的时钟固定为HCLK时钟的1/8,在这里我们选用内部时钟源120M,所以SYSTICK的时钟为(120/8)M,即SYSTICK定时器以(120/8)M的频率递减。SysTick 主要包含CTRL、LOAD、VAL、CALIB 等4 个寄存器。

▼CTRL:控制和状态寄存器

4175d639fd291163981f2a2807165074.png

▼LOAD:自动重装载除值寄存器

a9a3c73542ee08fe00db143746bc2c61.png

▼VAL:当前值寄存器

8bffcd09f5b22506171a28bfe0cc2dd5.png

▼CALIB:校准值寄存器

使用不到,不再介绍

代码

void delay_us(uint32_t nus){  uint32_t temp;  SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000000/8*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(uint16_t nms){  uint32_t temp;  SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000/8*nms;  SysTick->VAL=0X00;//清空计数器  SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源  do  {    temp=SysTick->CTRL;//读取当前倒计数值  }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达  SysTick->CTRL=0x00; //关闭计数器  SysTick->VAL =0X00; //清空计数器}
上述工程源码仓库:https://github.com/strongercjd/STM32F207VCT6/tree/master/04-Delay

(提示:公众号不支持外链接,请复制链接到浏览器下载)

d16958190950ed865867862eb44b79ee.gif汇编指令

如果系统硬件资源紧张,或者没有额外的定时器提供,又不想方法1的普通延时,可以使用汇编指令的方式进行延时,不会被编译优化且延时准确。

STM32F207在IAR环境下

/*! *  @brief   软件延时  *  @param  ulCount:延时时钟数 *  @return none *  @note   ulCount每增加1,该函数增加3个时钟 */void SysCtlDelay(unsigned long ulCount){    __asm("    subs    r0, #1\n"          "    bne.n   SysCtlDelay\n"          "    bx      lr");}
这3个时钟指的是CPU时钟,也就是系统时钟。120MHZ,也就是说1s有120M的时钟,一个时钟也就是1/120us,也就是周期是1/120us。3个时钟,因为执行了3条指令。使用这种方式整理ms和us接口,在Keil和IAR环境下都测试通过。
/*120Mhz时钟时,当ulCount为1时,函数耗时3个时钟,延时=3*1/120us=1/40us*//*SystemCoreClock=120000000us级延时,延时n微秒SysCtlDelay(n*(SystemCoreClock/3000000));ms级延时,延时n毫秒SysCtlDelay(n*(SystemCoreClock/3000));m级延时,延时n秒SysCtlDelay(n*(SystemCoreClock/3));*/#if defined   (__CC_ARM) /*!< ARM Compiler */__asm voidSysCtlDelay(unsigned long ulCount){    subs    r0, #1;    bne     SysCtlDelay;    bx      lr;}#elif defined ( __ICCARM__ ) /*!< IAR Compiler */voidSysCtlDelay(unsigned long ulCount){    __asm("    subs    r0, #1\n"       "    bne.n   SysCtlDelay\n"       "    bx      lr");}#elif defined (__GNUC__) /*!< GNU Compiler */void __attribute__((naked))SysCtlDelay(unsigned long ulCount){    __asm("    subs    r0, #1\n"       "    bne     SysCtlDelay\n"       "    bx      lr");}#elif defined  (__TASKING__) /*!< TASKING Compiler */                           /*无*/#endif /* __CC_ARM */

上述工程源码仓库:https://github.com/strongercjd/STM32F207VCT6/tree/master/03-ASM

(提示:公众号不支持外链接,请复制链接到浏览器下载)

注释

理论上:汇编方式的延时也是不准确的,有可能被其他中断打断,最好使用us和ms级别的延时,采用for循环延时的函数也是如此。采用定时器延时理论上也可能不准确的,定时器延时是准确的,但是可能在判断语句的时候,比如if语句,判断延时是否到了的时候,就在判断的时候,被中断打断执行其他代码,返回时已经过了一小段时间。不过汇编方式和定时器方式,只是理论上不准确,在实际项目中,这两种方式的精度已经足够高了。

b56bfb4623916b1acb4872c1ff4e760b.gif37a346cf24241e721ee1e46860a8ec11.gif

设计一款兼容ST207和GD207的开发板

MCU心脏-晶振

晶振原理解析

复位电路设计

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用pm2启动node文件_PM2 是什么

目录 pm2是什么特点示例说明配置文件常用命令背景 由于需要在容器云新增一个测试环境&#xff0c;改了代码相关的配置后&#xff0c;进行部署。发现服务一直启动不了。在和运维一起排查问题&#xff0c;他看到pm2的一些信息&#xff0c; 问我pm2是不是阻塞了&#xff0c;并不是…

CP/M世界上第一个微机操作系统

CP/M世界上第一个微机操作系统 微软宣布2014年4月8日将不再对Windows XP系统进行更新&#xff0c;宣告这个存活了13年的史上寿命最长的微机操作系统基本上寿终正寝。很多人都知道这是个脱胎于DOS的系统&#xff0c;也潜意识中认为DOS是微机操作系统的鼻祖。不过&#xff0c;这大…

安卓 usb音量调节_戴尔推出面向Teams和Zoom视频通话的USB-C免提适配器

COVID-19 大流行期间&#xff0c;许多企业将会议安排在了线上举办。为方便通过 Microsoft Teams 和 Zoom 之类云视讯平台进行沟通的笔记本电脑用户&#xff0c;戴尔特地推出了新款 USB-C 音频适配器。作为一款两用配件&#xff0c;MH3021P 不仅可以作为有线通话的免提适配器(集…

word表格美化技巧:如何统一改变表格的样式

在Word中插入的表格默认都是黑边白底&#xff0c;看上去非常的单调。比如这样&#xff1a; 很多小伙伴都是在新建表格并且填完数据之后&#xff0c;应用表格样式&#xff0c;来提升档次&#xff0c;如下&#xff1a; 但是&#xff0c;每次新建表格后再选择应用【表格样式】&…

banner信息是什么_我的设计成长笔记—第10篇(banner)

Banner2019年5月9日这里是我的设计成长笔记—————————————————Banner为什么单独拿出来聊因为我有差不多一年的时间都在做这个在我的成长过程中&#xff0c;banner是过渡从平面/美工到UI设计的一个过程。在这个过程中&#xff0c;我对设计的理解分成了三个部分第…

后台原理_电气控制原理动图22张,超赞!

今天从低压电器、电动机及控制线路、传感器及控制原理三部分来分享22张超赞的原理动图。低压电器部分1按钮开关2闸刀开关3行程开关4交流接触器5热继电器6时间继电器7速度继电器电动机及控制线路1异步电动机2直流电动机3步进电动机4永磁电机5正反转控制6自动往返控制7顺序控制8多…

[word技巧]把标题、图表题注编号由“一.1”改为“1.1“

一、问题描述 写作中文报告时&#xff0c;有时会要求一级标题用类似”第一章”的中文编号&#xff0c;二级标题用1.1这类编号&#xff0c;图表题注用“表1.1”的编号。此时&#xff0c;由于一级标题用的是中文数字&#xff08;如“一”&#xff09;作为序号&#xff0c;因此wor…

excel中怎样用公式获取表单控件_挑战高手:用不到 100 行代码,在前端实现 Excel 全部功能...

(点击图片获取专属你的开发工具)SpreadJS是一款基于 HTML5 的纯前端表格控件&#xff0c;兼容 450 种以上的 Excel 公式&#xff0c;具备“高性能、跨平台、与 Excel 高度兼容”的产品特性广受世界各地名企追捧。接下来让我们看看其具有哪些独特优势吧&#xff01;四大优势&…

vissim免修改时间工具_App闪退怎么办?免越狱如何安装未签名的App?

由于最近苹果大规模的封签名&#xff0c;导致在第三方渠道下载的软件都出现闪退没法使用的现象。目前的替代方法就是使用电脑端 Cydia Impactor 来给 App 进行自签&#xff0c;虽然相对比较麻烦&#xff0c;但这也是目前针对企业签名无法使用的唯一解决方法。下面以安装 FilzaE…

word表格美化技巧:如何统一改变表格的样式2+续表制作

一、表格样式 开始-样式-新建样式-样式类型&#xff1a;表格。 单独设置标题行&#xff0c;汇总行等格式即可。表格样式会显示在-设计-样式-表格样式中。 问题&#xff1a;汇总行无效。 即可。 二、续表 直接复制表格及题注到下一页&#xff0c;然后下下面表格的题注修改为…

excel条件格式详解

1、基于公式返回的逻辑值去判断&#xff0c;True则执行条件格式&#xff0c;FALSE不执行。 2、基于区域第一个单元格的公式&#xff0c;依次根据单元格引用方式判断区域内公式是否成立。 函数&#xff1a; 使用条件格式&#xff1a; 函数&#xff1a; 条件格式&#xff1a; 函…

ccf a类会议_CCF推荐 | 人工智能领域顶级会议:截稿日期批量速递

以下为已公布截稿日期的CCF推荐&#xff0c;人工智能领域会议&#xff0c;按照时间排序。个别会议因为没有公布截稿信息而不在所列时间线内。录取率信息为网络上可获得的最近年份数据&#xff0c;不一定是上一年的&#xff0c;文中尽量选择同时带有投稿量的数据年份供大家参考.…

python递归调用详解_Python递归调用自己的函数

原博文 2019-11-16 10:36 − def fact(x): if x 1: return 1 else: return x * fact(x-1) ...0191 相关推荐 2019-09-28 21:13 − Python python是一种跨平台的计算机程序设计语言&#xff0c;是一种面向对象的动态类型语言。 最初被设计用于编写自动化脚本(shell)&#xff0c…

vue跳转到外部链接_前端实战项目:Vue.js实现外卖平台webapp,饿了么项目的翻版...

链接&#xff1a;https://github.com/ljianshu/mt-app适合没有经验的朋友。项目涉及到技术栈&#xff1a;vue全家桶&#xff1a;Vue、Vue-router、Vue-cli等 组件化&#xff1a;单Vue文件 模块化&#xff1a;ES6 Module 第三方模块&#xff1a;better-scroll axios等 基础开发环…

令xtu3service开机时立即启动_Mac开机时可以使用的快捷键 苹果电脑快捷键使用介绍...

大家都知道所有电脑在开机时&#xff0c;按住一些按键可以访问一些功能&#xff0c;当然Mac电脑也不例外。苹果电脑通过在开机启动时按住一个或多个按键可以访问一些Mac功能和工具。如果各位用户使用这些开机键组合键中的任何一个&#xff0c;可在按下电源按钮后&#xff0c;重…

word 插入图片显示不全

word插入图片显示不全&#xff1a; 解决方案&#xff1a; 选中图片-段落-行距-选择单倍、或者多倍行距都可以。即可。

操作系统-进程同步与互斥易混点

解惑1&#xff1a; 为使多个进程能互斥的访问某临界资源&#xff0c;只须为该资源设置 一个互斥信号量 mutex&#xff0c;初值为 1&#xff08;代表临界资源只有一个&#xff09; mutex初值为1.取值范围为[-1,0,1] 当mutex1时&#xff0c;表示两个进程皆未进入需要互斥访问的…

linux降低eigen3版本_玩转 Windows 自带的 Linux 子系统 (图文指南)

涉及到计算机科学离不开 Linux 系统&#xff0c;当然&#xff0c;也离不开Windows。但是&#xff0c;二者从操作到核心的不同&#xff0c;貌似让鱼和熊掌不可兼得。但是&#xff01;微软已经拿出了一款让鱼和熊掌兼得的方案 WSL &#xff08;Windows Subsystem for Linux&#…

处理死锁的四种方法

前面讲过预防死锁是通过破坏死锁的四个必要条件&#xff0c;所以就有四个预防死锁的方法吗&#xff1f;错&#xff01;只有三种&#xff0c;因为互斥条件是必须的&#xff0c;不仅不能改变&#xff0c;还应该加以保证。因此只能破坏后三个条件。 一、破坏请求和保持条件 方法…