在STM32HAL库工程下用SysTick编写一个微秒延时函数
时间: 2024-11-27 16:15:56 浏览: 102
在STM32 HAL库环境下,你可以利用SysTick来编写一个简单的微秒级延时函数。首先,你需要初始化SysTick并设置定时周期。以下是一个基础的示例:
```c
#include "stm32f1xx_hal.h"
// 定义一个全局变量用于存储SysTick的计数值
volatile uint32_t sysTickCount = 0;
void SetSysTickDelay(uint32_t delayInMicroseconds)
{
// 获取SysTick的频率 (对于STM32F103系列通常为1 MHz)
uint32_t tickFrequency = HAL_RCC_GetSysTickFreq();
// 设置目标时间(单位:tick)
uint32_t targetTicks = delayInMicroseconds * tickFrequency / 1000000;
// 开启SysTick中断
__HAL_SYSTICK_CLK_ENABLE();
__HAL_SYSTICK_SETCOUNT(targetTicks);
// 循环等待直到达到目标时间
while (__HAL_SYSTICK_GETCOUNT() < targetTicks);
}
相关问题
stm32 HAL库延时函数delay
### STM32 HAL库延时函数 `HAL_Delay` 的使用方法与实现原理
#### 使用方法
在STM32 HAL库中,`HAL_Delay()` 是用于毫秒级延迟的标准API。此函数接受一个参数——表示等待时间的无符号整型数值(单位为毫秒),并在此期间挂起当前线程。
要调用该函数,需先确保已经初始化了系统的滴答定时器(SYSTICK),通常是在项目启动文件(`main.c`)中的`HAL_InitTick()`被调用之后完成这一操作[^1]。
```c
// Example of using HAL_Delay function.
HAL_Delay(1000); // Delay for 1 second (1000 milliseconds).
```
#### 实现原理
`HAL_Delay()` 函数依赖于Systick定时器来提供精确的时间基准。当程序执行到这个函数时,它会记录下当前时刻,并不断查询直到达到指定数量的周期才返回控制权给后续指令继续运行。具体来说:
- Systick是一个24位向下计数的倒计数定时器;
- 当配置好预设值后,每过一次系统时钟频率对应的周期就减去一;
- 到达零的时候会产生溢出事件通知CPU更新全局变量SysTick->VAL重新加载重装载寄存器里的初值;
- 同时也会触发中断服务例程(ISR)增加由硬件维护的一个递增计数器ms_ticks[]。
因此,通过这种方式可以实现较为精准可靠的软件延时效果。
然而需要注意的是,在某些特定场景比如ISR内部不应该直接调用`HAL_Delay()`因为这可能会造成不可预测的行为甚至死锁现象发生,正如提到过的按键消抖应用案例所示[^3]。
对于更短时间尺度上的微秒级别延迟,则可能需要用到其他机制如基于DWT(Deprecated Watchdog Timer)组件的方法或是利用更高精度的通用TIMx外设来进行编程设计[^2]。
stm32cubemx STM32H7配置SYsTIck 纳秒的延时函数
STM32CubeMX 是一款由 ST Microelectronics 开发的集成设计环境工具,它能自动创建基本的 STM32 微控制器应用,简化了系统配置、内存管理、外设初始化等功能,帮助用户快速启动项目。
### 配置 SYsTIck 和纳秒级延时函数
在 STM32 的微处理器中,`SysTick` 是一种定时器,常用于生成周期性的中断事件,通常用于执行一些周期性任务或计数等操作。要在 STM32CubeMX 中设置 `SysTick` 及其纳秒级延时功能,可以按照以下步骤操作:
#### 通过 STM32CubeMX 配置 `SysTick`
1. **打开 STM32CubeMX 并选择目标 STM32 芯片**(例如 STM32H7)以及相应的系列版本。
2. **在项目窗口中选择 `System`** 来编辑系统部分。在这里,你可以找到 `SysTick` 相关的配置选项。
3. **勾选启用 `SysTick` 定时器**。然后可以选择 `Tick` 时间长度和预分频值,这将影响每秒钟的中断次数。通常,使用默认设置即可满足需求。
4. **配置 `SysTick` 作为周期性的中断源**,这通常已经在默认设置中完成。
5. **保存配置**,完成后,STM32CubeMX 将自动生成必要的代码和配置文件。
#### 实现纳秒级延时函数
虽然 `SysTick` 提供的是毫秒级别的中断,但通过循环等待特定次数的 `SysTick` 中断,我们可以模拟出纳秒级别的时间延迟。下面是一个简单的示例代码段来演示如何使用 `SysTick` 进行纳秒级时间延迟:
```c
#include "stm32h7xx_hal.h"
#include "stm32h7xx_hal_msp.h"
// 假定 SysTick 每次中断间隔大约为 0.001 秒
const uint32_t TICKS_PER_SECOND = 1000;
uint32_t delay_ns = 1; // 延迟时间为 1 纳秒
void SystemClock_Config(void);
void DelayNanoseconds(uint32_t ns);
void __attribute__((interrupt("WWDG")))
WWDG_IRQHandler() {
if (delay_ns > 0) {
delay_ns--;
}
}
int main() {
HAL_Init();
SystemClock_Config();
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOD,
ENABLE); // 初始化 GPIO 引脚
HAL_NVIC_EnableIRQ(WWDG_IRQn); // 启动 WWDG 中断
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 示例 GPIO 控制
while(1) {
DelayNanoseconds(TICKS_PER_SECOND * 1000 * 1000); // 延迟 1 微秒
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
}
return 0;
}
void DelayNanoseconds(uint32_t ns) {
for (; ns > 0; ns--) {
while (HAL_GetTick() % TICKS_PER_SECOND != 0) {
;
}
}
}
```
此代码首先设置了一个无限循环,在循环内部通过 `DelayNanoseconds()` 函数实现纳秒级的延迟。`DelayNanoseconds()` 函数通过检查当前时间是否等于一个完整的毫秒来决定是否递减延迟计数器 `ns`。
####
阅读全文