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 22:22:50 浏览: 114
这是一段使用 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,同时要求当前系统滴答计数值不能变化。
通过这种方式,函数可以实现微秒级的延时功能,可以用于需要精确控制时间的应用场合,比如驱动液晶显示屏、按键扫描等。
相关问题
void delay_us(uint32_t nus)
这是一个函数声明,用于实现微秒级别的延时,函数的实现可能类似于下面的代码:
```c
void delay_us(uint32_t nus)
{
uint32_t ticks = nus * (SystemCoreClock / 1000000);
volatile uint32_t start = DWT->CYCCNT;
while (DWT->CYCCNT - start < ticks);
}
```
其中,`SystemCoreClock` 是系统时钟频率,`DWT->CYCCNT` 是一个用于计时的寄存器。函数的实现思路是利用这个计时寄存器计算出需要延时的时钟周期数,然后在一个循环中等待这些时钟周期过去。由于这个循环中只有一条指令,因此可以认为它是一个非常精确的延时函数。
void Delay_ms(uint32_t nCount) { SysTick->LOAD = 72*nCount; SysTick->VAL = 0x00; SysTick->CTRL = 0x01; while((SysTick->CTRL & 0x01) && (!(SysTick->CTRL & (1<<16)))); SysTick->CTRL = 0x00; SysTick->VAL = 0X00; }
这段代码是用于实现延时的函数,输入参数nCount是延时的毫秒数。具体实现是通过STM32的SysTick定时器来实现的。首先将延时的毫秒数乘以72,得到SysTick定时器的重装值,然后将SysTick定时器的VAL寄存器清零,将CTRL寄存器的第0位设置为1,启动SysTick定时器。在SysTick定时器运行期间,程序会一直进入while循环中,等待SysTick定时器的COUNTFLAG标志位被置位并且CTRL寄存器的第16位清零,表示定时器已经定时完成。最后将CTRL寄存器清零,将VAL寄存器清零,结束延时函数的执行。
阅读全文