返回
STM32延时函数的四大实用方法
见解分享
2023-11-27 00:30:07
导言
STM32单片机以其卓越的性能和广泛的应用而备受推崇。在嵌入式系统开发中,延时函数是不可或缺的组件,可用于精确控制程序执行的节奏。本文深入探讨STM32延时函数的四种常用方法,深入阐述其原理、优缺点,并提供示例代码,为嵌入式开发者提供全面且实用的指南。
1. 循环计数延时法
这种方法是延时函数的传统实现方式,它通过执行一个紧凑的循环,并计数循环次数来实现延时。循环体越小,延时精度越高。然而,它需要消耗大量的CPU资源,并且延时精度受编译器优化水平的影响。
void delay_us(uint32_t us) {
for (uint32_t i = 0; i < us * CYCLES_PER_US; i++) {
// 空循环
}
}
2. SysTick延时法
SysTick定时器是STM32内核中的一个内置定时器,可提供精确的微秒级延时。它通过配置SysTick重新加载值并等待其倒计时完成来实现延时。这种方法开销较小,精度高,但仅限于微秒级延时。
void delay_us(uint32_t us) {
SysTick->LOAD = us * SYSTICK_CLK_US;
SysTick->VAL = 0;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
3. HAL库延时法
STM32 HAL(硬件抽象层)库提供了一个易于使用的延时函数HAL_Delay()。它通过调用底层硬件定时器来实现延时,从而简化了延迟实现,并减少了对寄存器级操作的需求。
void delay_ms(uint32_t ms) {
HAL_Delay(ms);
}
4. DMA传输延时法
这种方法利用DMA(直接内存访问)控制器将一个内存区域中的字节传输到另一个内存区域。通过配置DMA传输长度和传输速率,可以实现精确的延时。它不消耗CPU资源,但实现复杂度较高,并且需要在DMA控制器上占用通道。
void delay_ms(uint32_t ms) {
uint32_t *src, *dst;
DMA_InitTypeDef dma_init;
// 初始化DMA控制器
__HAL_RCC_DMA1_CLK_ENABLE();
dma_init.DMA_Channel = DMA_CHANNEL_1;
dma_init.DMA_PeripheralBaseAddr = (uint32_t)src;
dma_init.DMA_Memory0BaseAddr = (uint32_t)dst;
dma_init.DMA_DIR = DMA_MEMORY_TO_MEMORY;
dma_init.DMA_BufferSize = 1;
dma_init.DMA_PeripheralInc = DMA_PINC_ENABLE;
dma_init.DMA_MemoryInc = DMA_MINC_ENABLE;
dma_init.DMA_PeripheralDataSize = DMA_PDATAALIGN_BYTE;
dma_init.DMA_MemoryDataSize = DMA_MDATAALIGN_BYTE;
dma_init.DMA_Mode = DMA_NORMAL;
dma_init.DMA_Priority = DMA_PRIORITY_LOW;
dma_init.DMA_FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_channel1, &dma_init);
// 启动DMA传输并等待完成
HAL_DMA_Start_IT(&hdma_channel1, (uint32_t)src, (uint32_t)dst, 1);
while (HAL_DMA_GetState(&hdma_channel1) != HAL_DMA_STATE_READY) {}
}
结论
以上四种STM32延时函数各有优劣,开发者可以根据具体应用场景选择最合适的方案。循环计数法简单易用,但效率较低;SysTick定时器精度高,开销较小,但仅限于微秒级延时;HAL库延时函数易于使用,但可能会增加代码尺寸;DMA传输法效率高,但实现复杂度较高。希望本文能为开发者提供有价值的指导,助力其构建高效、精准的嵌入式系统。