void delay_us(uint16_t udelay) { uint32_t startval,tickn,delays,wait; startval = SysTick->VAL; tickn = HAL_GetTick(); //sysc = 72000; //SystemCoreClock / (1000U / uwTickFreq); delays =udelay * SYSCLK; //sysc / 1000 * udelay; if(delays > startval) { while(HAL_GetTick() == tickn) { } wait = SYSCLK*1000 + startval - delays; while(wait < SysTick->VAL) { } } else { wait = startval - delays; while(wait < SysTick->VAL && HAL_GetTick() == tickn) {
时间: 2024-04-27 15:22:50 浏览: 120
这是一段使用 SysTick 定时器实现微秒级延时的函数代码。该函数的参数为需要延时的微秒数 udelay。在函数内部,首先通过 SysTick->VAL 获取 SysTick 定时器的当前计数值 startval,然后通过 HAL_GetTick() 获取当前的系统滴答计数值 tickn。
接下来,根据系统时钟频率 SYSCLK 和需要延时的微秒数 udelay,计算出需要延时的 SysTick 计数值 delays。如果 delays 大于 startval,则需要先等待到下一个系统滴答计数值,然后计算出需要等待的 SysTick 计数值 wait,最后通过 while 循环等待 SysTick 计数器减至 wait。如果 delays 小于等于 startval,则直接计算出需要等待的 SysTick 计数值 wait,并通过 while 循环等待 SysTick 计数器减至 wait,同时要求当前系统滴答计数值不能变化。
通过这种方式,函数可以实现微秒级的延时功能,可以用于需要精确控制时间的应用场合,比如驱动液晶显示屏、按键扫描等。
相关问题
HAL库delay_us
HAL库中提供了一个函数可以用于微秒级的延时,即`HAL_Delay`函数。但是,该函数的最小延时是1毫秒,因此如果需要微秒级的延时,可以使用以下方法:
```c
void delay_us(uint16_t us)
{
uint32_t ticks = us * (SystemCoreClock / 1000000);
__IO uint32_t tmp;
tmp = SysTick->CTRL; //清空SysTick计数器的值
SysTick->LOAD = ticks; //设置SysTick计数器的初始值
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //使能SysTick计数器
do {
tmp = SysTick->CTRL;
} while ((tmp & SysTick_CTRL_COUNTFLAG_Msk) == 0); //等待计数器溢出
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭SysTick计数器
SysTick->VAL = 0x00; //清空SysTick计数器的值
}
```
该函数的原理是使用系统时钟频率计算出需要延时的时钟周期数,然后通过SysTick计数器进行计数,并等待计数器溢出。注意,在使用该函数时,需要先使能SysTick计数器。
gd32的MCU 采用SYSTICK 进行delay 产生us的精度延迟函数,请给出代码
以下是一个使用SysTick的延迟函数代码示例,可以产生微秒级别的延迟:
```c
#include "gd32f10x.h"
static __IO uint32_t timing_delay;
void SysTick_Handler(void)
{
if (timing_delay != 0x00)
{
timing_delay--;
}
}
void delay_us(uint32_t us)
{
timing_delay = us;
SysTick_Config(SystemCoreClock / 1000000); // 配置 SysTick 为 1us 中断
while (timing_delay != 0);
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭 SysTick
}
```
使用方法如下:
```c
delay_us(1000); // 延迟 1000us = 1ms
```
阅读全文