历史上的今天
返回首页

历史上的今天

今天是:2025年07月20日(星期日)

2018年07月20日 | STM32延时函数的三种方法

2018-07-20 来源:eefocus

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

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.SysTick 定时器延时

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

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

a.中断方式

 如下,定义延时时间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--;
}

b.非中断方式

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

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; //清空计数器
}

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


推荐阅读

史海拾趣

Agere System(LSI Logic)公司的发展小趣事

Agere Systems(后来被LSI Logic收购)是一家在半导体行业具有重要影响力的公司之一。以下是该公司发展的五个相关故事:

  1. 公司成立和发展:Agere Systems成立于2000年,是由Lucent Technologies的微电子部门分拆而成。公司总部位于美国新泽西州的默里斯敦市。Agere Systems专注于开发半导体解决方案,包括通信芯片、存储芯片和无线网络技术。通过不断的技术创新和市场拓展,Agere Systems在短时间内成为半导体行业的领军企业之一。

  2. 无线通信技术:Agere Systems在无线通信技术方面取得了重大突破,推动了移动通信产业的发展。该公司开发了一系列的基带处理器和射频芯片,用于手机和其他移动设备中的无线通信。这些技术的应用使得移动通信设备具有更高的性能、更低的功耗和更广泛的覆盖范围,促进了全球移动通信市场的快速增长。

  3. 存储解决方案:除了在通信领域取得成功外,Agere Systems还致力于开发先进的存储解决方案。该公司生产的存储芯片和控制器广泛应用于硬盘驱动器、固态硬盘和存储系统中,为数据存储和处理提供了关键的技术支持。Agere Systems的存储产品以其高速、高效和可靠性而闻名,成为许多数据中心和企业用户的首选。

  4. 公司并购与重组:在Agere Systems发展的过程中,该公司进行了多次并购和重组以加强自身实力和市场竞争力。2007年,LSI Logic公司宣布收购Agere Systems,将两家公司的技术和资源整合在一起,共同致力于推动半导体行业的发展。通过这一合并,LSI Logic扩大了其在存储和通信领域的市场份额,进一步巩固了在全球半导体市场的领导地位。

  5. 技术创新与发展:Agere Systems始终把技术创新作为公司发展的核心驱动力。该公司投入大量资源用于研发,并与全球各地的科研机构和合作伙伴进行紧密合作。Agere Systems持续推出高性能、低功耗的芯片产品,并不断改进现有产品的性能和功能,以满足客户不断增长的需求。通过持续的技术创新和产品优化,Agere Systems在半导体行业保持了竞争优势,并为客户提供了更加先进和可靠的解决方案。

埃派克森微电子(Apexone)公司的发展小趣事

在埃派克森微电子的发展过程中,著名投资机构多尔基金和华登国际的风险投资起到了重要的推动作用。这些投资不仅为公司提供了资金支持,还带来了宝贵的市场资源和管理经验。借助这些资源,埃派克森加快了国际化步伐,积极拓展海外市场,与全球范围内的客户和合作伙伴建立了紧密的合作关系。

AiT Semiconductor Inc公司的发展小趣事

AiT公司的创立源自一群对半导体技术充满热情的工程师。他们看到了半导体行业巨大的市场潜力和技术挑战,决心成立一家公司,专注于半导体产品的研发和生产。在创立初期,公司面临资金短缺、市场竞争激烈等诸多困难,但凭借着对技术的执着追求和不懈努力,他们成功开发出了一系列高性能、高品质的半导体产品,逐渐在市场中站稳脚跟。

Ericsson Power Modules公司的发展小趣事

在追求经济效益的同时,Ericsson Power Modules也注重环保和可持续发展。公司积极采用环保材料和绿色生产工艺,降低生产过程中的能耗和排放。此外,Ericsson Power Modules还积极参与环保公益活动,推动电子行业的绿色发展。这种环保意识和行动体现了Ericsson Power Modules对社会的责任感和对可持续发展的承诺。

Hongfa公司的发展小趣事

宏发公司始终坚持“以质取胜”的发展战略。早在1988年,公司就确立了“以市场为导向,以质取胜”的经营方针。为了保证产品质量,宏发不仅制定了严格的生产流程规则,还在国内行业中建成了设备最先进的实验室,并获得了世界三大认证机构的认证。这种对质量的执着追求,使得宏发的产品在国际市场上获得了高度认可,也为公司的长远发展奠定了坚实的基础。

DPA Components International公司的发展小趣事

作为一家具有社会责任感的企业,DPA Components International公司始终关注社会公益事业。公司积极参与各种公益活动,如扶贫助学、环保行动等,为社会做出了积极贡献。此外,DPA还关注行业发展和社会进步,积极参与行业交流和合作,推动整个电子行业的健康发展。通过担当社会责任,DPA不仅提升了企业的社会形象,也为社会的进步和发展做出了积极贡献。

问答坊 | AI 解惑

分布式温度控制

    有谁能提供有关基于MS-51的分布式温度控制有关资料,谢谢了!!!!!   急用!急用!!!!!!!!!!!!!!!!…

查看全部问答>

双向手灯

如果你有在漆黑一片的环境中走路的经历,一定会知道,只有一个手电筒虽然要比没有手电好得多,但是也并不见得能让你行走的步伐加快多少。因为,单个的手电筒只能照亮一个方向,而我们不仅要看清前面的路还要同时兼顾脚下,所以,如果只有一个手电筒 ...…

查看全部问答>

如何判断翻盖手机打开还是合上

没找到api。是否可以根据电源的状态判断。但是不知道手机翻盖和合上哪些电源状态不同…

查看全部问答>

window ce 6.0 矩阵键盘驱动

如何自己写成键盘的单体的流驱动,有两个问题没有解决 ,请问各位大侠: (1)键盘驱动 改如何将扫描的键盘值发送到GWES? 是通过那个函数发送过去的啊? (2)GWES可以加载流驱动到GWES吗?如果可以 如何让GWES加载?如果不行 应该怎么处理? …

查看全部问答>

如何确保WinCE的稳定性

如题: 如何确报WinCE的稳定性 如果在运行过程中,出现意外死机等不正常现象,如何处理... …

查看全部问答>

最近论坛好象有问题

不稳定,资源不能上传,有时出上传界面时,用户名竟然不是自己的!!而且哪个资源也没有上传成功,虽然提示是成功了,可以搜不到资源.更离谱的是竟然计时出负值,晕啊 预计剩余时间: 剩余 -955 秒 文件名:14095955345.rar (7.64MB/185.12KB) 正在上传 14 ...…

查看全部问答>

i.mx25 ADC

i.MX25是freescale的ARM9处理器,400MHZ主频,DDR2控制器,是针对工业市场设计的,和TI的AM18xx类似,和atmel的也类似。这个用来做工业产品是很好的这是个应用笔记,说的是ADC模块…

查看全部问答>

请教:怎样把FPGA的数据送给Matlab画图

请教:怎样把FPGA的数据送给Matlab画图…

查看全部问答>

晶振清洗问题

本帖最后由 jameswangsynnex 于 2015-3-3 19:57 编辑 请问晶振可以清洗吗 用什么清洗液体不会损害晶振 …

查看全部问答>

STM32用查询检测按键来控制LED亮灭

我正在学STM32,在用查询检测按键的按下来控制LED的亮灭,但是实际的现象却是有时按下按键好几下都没有反应,有时按下去后一下子就亮又灭了。完全找不到哪里的原因。这是我的工程,请各位帮忙看下哪有错。…

查看全部问答>