GD32单片机设置us级延时
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
上面提供了两种方式来实现,区别是第一种是忙等的方式,第二种是中断的方式,可以根据自己的需求适当选择。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?