历史上的今天
今天是:2025年04月23日(星期三)
2018年04月23日 | STM32 延时函数解析
2018-04-23 来源:eefocus
一、函数原型
STM32官方提供的函数库中,可以找到类似于 HAL_Delay() 这样的函数。这个函数的就是通过使用定时器,达到一个较为精确的时间延迟,提供给用户调用。
这个函数一般包含在类似于 stm32f4xx_hal.c 这样的函数中。函数原型如下:
__weak void HAL_Delay(__IO uint32_t Delay)
{
uint32_t tickstart = 0U;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{
}
}
输入参数为需要延时的时间,单位为毫秒(ms)。其中调用的 HAL_GetTick() 函数为获取计数值 uwTick,该计数值在中段服务函数中进行加一操作。
__weak uint32_t HAL_GetTick(void)
{
return uwTick;
}
在中断服务函数如下:
void SysTick_Handler(void)
{
uwTick++;
}
该中断服务函数为系统定时器SysTick的中断响应。而该定时器的初始化函数 HAL_InitTick() 是在 stm32f4xx_hal.c文件里定义,并在 HAL_Init() 函数中被调用。
查看其初始化函数 HAl_InitTick() ,内容如下:
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
/*Configure the SysTick to have interrupt in 1ms time basis*/
HAL_SYSTICK_Config(SystemCoreClock/1000U);
/*Configure the SysTick IRQ priority */
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0U);
/* Return function status */
return HAL_OK;
}
这个函数首先是为该定时器设置中断产生的周期,例如当前情况下为1ms,也就是没一毫秒都要产生一次中断。其次是为该定时器设置中断优先级。
二、函数说明
用户在使用延时时,直接调用函数 HAl_Delay(time),填入需要延时的时长,单位为毫秒,例如填入5000,则代表延迟5秒,这段时间MCU会产生5000次中断,进5000次中断服务函数对计数值进行加一操作。
延时函数的核心语句为 while循环,如下:
while((HAL_GetTick() - tickstart) < Delay)
{
}
这个函数在条件满足时会一直循环,但是由于循环体为空,所以实际上循环是不产生任何操作的,直到循环不满足,也就是计数值在不断加一操作后的值减去开始延迟时值已经大于延时值时。此时条件不满足,循环结束,程序继续向下执行。
关于上面这个while循环,还可以用采用for循环写的版本,如下:
for( ;(HAL_GetTick() - tickstart) < Delay; );
即仅使用for循环的一个条件,这段代码等同于如下代码:
for(;;)
{
if((HAL_GetTick() - tickstart) > Delay)
break;
}
三、更多说明
1、关于 SysTick 定时器,数据手册的说明如下:
2、关于for和while循环的效率说明
史海拾趣
|
摘要: 本文介绍了一种基于32位高性能处理器的视觉精密测量系统的软硬件设计。图像传感器采集的条码图像通过精密定位算法得到绝对位移值,由以太网接口实现高速图像采集。该系统适用于高精度定位的各种位移测量。 关键词: ARM;嵌入式系统;视觉 ...… 查看全部问答> |
|
NXL LPC系列ARM IIC总线下读写AT24Cxx的总结 最近应用到NXP LPC系列的ARM IIC总线进行读写AT24Cxx EEPROM,总是出现一下错误,经过查阅资料才发现,原来本人范的全是最基本的错误,感觉很惭愧,现在把容易出错的地方进行总结,希望网友遇到这样的问题时 ...… 查看全部问答> |
|
最近在思考一个问题,就是有关SD卡升级的。 我看到过三星发布2442下的SD卡升级,但有个缺陷是只支持FAT格式的小容量卡,而且,在EBOOT里面去读写卡的block、sector,简直有点复杂。 我在想,如果是FAT32格式的(现在基本上都是FAT32格式了)SD卡能 ...… 查看全部问答> |
|
int tmp,i,j; int receiv,send=0x30; *ULCON0=0x03; *UCON0=0x09; *UBRDIV0=0x280; ...… 查看全部问答> |
|
从原理上来说..如果用FSMC驱动彩屏..就是把它当作一个外部的存储器件来操作. 1)只有16bit数据线是不是代表每像素就是16bit的?2)需要LCD内带控制器的屏才可以..这样选型范围应该会缩小很多.而且会贵这种屏一般上批量的话能做到多少钱一片. ...… 查看全部问答> |
|
用的是103F的片子,想把TIM1设置成翻转输出比较模式,但端口不会发生翻转 配置程序如下: GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_FAST); TIM1->CR1 &= 0xFE; // stop TIM1 TIM1->PSCRH = 0; TIM1->PSCRL = 0; ...… 查看全部问答> |




