us延时会在很多外设驱动的时候用到,但是GD32提供的资料里面没有看到,只有一个ms延时的函数,不过GD32用的和stm32是一样的内核,因此也可以套用stm32嘀嗒定时器的版本,就是直接用stm32的思路来实现,这里直接贴代码:
说明一下实验平台:
- GD32F470ZG
- 立创梁山派开发板
代码如下:
#include "delay.h"
// #define USE_BLOCK
#ifdef USE_BLOCK
/* 和正点原子一样的延时方式,cpu死等,适用于时间比较短的方式 */
void delay_ms(uint32_t ms)
{
SysTick->LOAD = SystemCoreClock / 1000 - 1; // 设置SysTick定时器为1毫秒
SysTick->VAL = 0; // 设置初值为0
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 使能计数器
for (uint16_t i = 0; i < ms; i++) {
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)) {
// 循环等待计数到达目标值
}
}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭计数器
SysTick->VAL = 0; // 时间到了溢出后要记得清空
}
void delay_us(uint32_t us)
{
SysTick->LOAD = SystemCoreClock / 1000000 - 1; // 设置SysTick定时器为1毫秒
SysTick->VAL = 0; // 设置初值为0
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 使能计数器
for (uint16_t i = 0; i < us; i++) {
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)) {
// 循环等待计数到达目标值
}
}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭计数器
SysTick->VAL = 0; // 时间到了溢出后要记得清空
}
#else
/* 下面的方式是systick中断实现的,从逻辑分析仪看到的数据,效果更好一点 */
void delay_us(uint32_t us)
{
uint32_t start_tick = SysTick->VAL;
uint32_t us_tick = us * (SystemCoreClock / 1000000);
while ((start_tick - SysTick->VAL) < us_tick) {
// 等待
}
}
void delay_ms(uint32_t ms)
{
for (uint32_t i = 0; i < ms; i++) {
delay_us(1000);
}
}
#endif // DEBUG
上面提供了两种方式来实现,区别是第一种是忙等的方式,第二种是中断的方式,可以根据自己的需求适当选择。
标签:ms,VAL,CTRL,us,单片机,GD32,SysTick,uint32 From: https://www.cnblogs.com/lx2035/p/17289651.html