问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

stm32中Delay()函数延时的时间是怎么计算的

发布网友 发布时间:2022-05-05 06:35

我来回答

4个回答

热心网友 时间:2023-10-13 05:52

单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时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--;

热心网友 时间:2023-10-13 05:52

单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时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位段名称类型复位值描述

                                16COUNTFLAGR0如果在上次读本寄存器后systick已为0,则该位为1,若 

                                读该位自动清零

                                2CLKSOURCERW00:外部时钟源 1:内部时钟

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

                                0ENABLERW0systick定时器使能位


                                   

                              SysTick-> LOAD位段名称类型复位值描述

                                23:0RELOADRW0减到0时被重新装载的值


                              SysTick-> VAL位段名称类型复位值描述

                                23:0CURRENTRW0读取时返回当前倒计数的值,写则清零,同时还会清除在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; //清空计数器

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

热心网友 时间:2023-10-13 05:53

首先取决于你的时钟频率选定为多少。
以24位的SysTick定时器为例,在3.5版本的库函数(该版本简化了对该计时器的配置函数)中,调用函数 SystemInit(); 初始化SysTick计时器为STM32主时钟的8分频,假设主频达到72MHz
则此时计时器的频率为9MHz,即1秒可 向下记数 9000000(9M)次。
f=9MHz,所以周期为T=1/f,即1/9000000。
再调用SysTick_Config(SystemCoreClock / X) (X表示一个数,填入多少就能获得 1/X 秒数)
delay中调用这些便可实现精确计时。
例如
void Delay(vu32 count)
{ 全局变量A = count };
然后再在stm32f10x_it.c 文件中的定义
void SysTick_Handler(void)
{
if(全局变量!=0)
全局变量--;

}
就可以实现计时了。
回答感觉够详细的话就采纳吧~

热心网友 时间:2023-10-13 05:53

以SysTick的初值是720为例,系统时钟为72m。SysTick记720个数产生一次中断。这样算也就是1秒产生100000次中断(1次10us)。当Delay(x)中x大于0时会将x传给一个全局的变量使他在每发生一次中断之后自减1.系统卡在等待这个变量变为零的死循环上直到这个全局来量变为零。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
为什么来大姨妈胸会胀 少儿学什么舞蹈 青年学什么舞蹈好 成年人学什么舞蹈 福州企业最低工资标准 2013年厦门的底薪是多少 生产要素的需求有哪些性质 生产要素的需求有何特点? 什么是生产要素需求 微观经济学要素需求什么是条件要素需求?它和要素需求有什么不同?_百度... ASCO电磁阀的技术参数 asco电磁阀8340G1与8340A1有什么区别? 介绍ASCO电磁阀安装使用需要注意什么 ASCO电磁阀是美国的什么牌子? 求歌曲忧郁的心情 野狼乐队亲爱的我想你歌词大意 在你心里,17岁的爱情是怎样的? 求几首像山人乐队的香格里拉那样轻松快乐的歌,最好是国内的独立乐队 MTV最新排行榜有哪些新歌 你QQ多少?我也非常喜欢摇滚!比如声音碎片!汪峰!许巍!还有野狼乐队,但是重金属比较喜欢在烦闷的时候 谁知道移情别恋( 爱爱)唱的歌词? 《好姑娘》(野狼乐队)的歌词 野狼乐队是个怎样的乐队 孩子早恋后被家长发现该怎样教育呢? 有什么软件可以在电脑上弹钢琴?是用键盘操作的那种。 电脑键盘弹钢琴 华为p20怎么关闭开机 免费的电脑键盘弹钢琴软件 电脑键盘弹钢琴的问题 求一款用电脑键盘弹钢琴的软件,无插件,好下载 4.TTL门电路的传输时延时间如何界定 PPT动画中的自定义的延迟时间具体怎么算的? 延时时间计算 大佬们麻烦问一下,这个是定义的延时时间吗,那delay2000大概是怎么算呢? 在java中如何定义延迟时间和是否提示发音两个属性? 怎样利用跑步机减肥? 怎样利用跑步机有效减肥? 产品经理 (市场营销方向)有前途吗 有人能说说产品经理和销售经理的区别吗 产品经理和销售代表哪个更有前途?请详细说说啊谢谢啦。医药行业的。还有这两个职位的薪资待遇有没有区别 女性肾阳虚原因?7 有没有大厨知道鸡翅要怎么煎啊(&#180;;︵;`)我鸡翅外面都糊了里面还没熟? 如何只删除QQ群接收的图片,而好友会话的图片不会删除! 在设置里的清理空间是把所有的图片全删除 QQ怎样只删除群接收的图片、截图,而不删除好友的截图、图片??? 如何删除QQ2009群聊天记录包括图片?但保留好友聊天记录.高手来 奥尔良鸡翅炸几分钟 为什么时间短了里面不熟 时间久了外面太老 QQ群聊天图片保存在哪个文件夹? QQ好友图片记录保存哪个文件夹?想删除QQ群的聊天记录图片,保留QQ好友的 qq能否只清理群里接受的图片 组织结构的主要形式是什么? 百臻生态农业