
本文共 2657 字,大约阅读时间需要 8 分钟。
systick在STM32F429上的应用方法
前言
systick是Cortex-M内置的一个节拍定时器功能,主要用于实时定时和中断控制。在STM32F429开发中,该功能具有很强的灵活性和便捷性。本文将详细介绍systick的寄存器结构以及在STM32F429上的实现方法。
导出寄存器与功能
systick在HAL库中通过一个结构体表示,其主要包含以下寄存器:
TypeDef SysTick_Type = { uint32_t CTRL; // 控制和状态寄存器 uint32_t LOAD; // 重载值寄存器 uint32_t VAL; // 当前计数值寄存器 uint32_t CALIB; // 校准寄存器};
在STM32F429中,systick的寄存器结构与标准Cortex-M系列相似,但有以下不同时之处:
STK_CTRL寄存器
STK_CTRL是systick的核心控制寄存器,具体功能包括:
- 0:AHB/8时钟
- 1:AHB时钟
STK_LOAD寄存器
STK_LOAD用于设置计数器的重载值,写入该寄存器后,计数器将重新加载指定的值。
STK_VAL寄存器
STK_VAL用于读取当前计数器值, 并清零计数器。
systick初始化与编程
在STM32F429开发中,正点原子使用了时钟窃取法来实现systick定时功能。主要步骤包括以下几个方面:
时钟源设置
systick的时钟源通常设置为AHB时钟,具体实现如下:
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_AHB);
计数器初始化
在HAL库中,通过HAL_InitTick
函数来初始化systick计数器,支持不同的中断优先级。
定时功能实现
正点原子开发的延时函数主要包括delay_us
和delay_ms
两种接口,实现原理如下:
初始化函数:
void delay_init(void) { HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); fac_us = HAL_RCC_GetSysClockFreq() / 1000000;}
微秒延时函数:
void delay_us(uint32_t nus) { uint32_t told = SysTick_VAL; uint32_t ticks = nus * fac_us; while (1) { uint32_t tnow = SysTick_VAL; if (tnow != told) { uint32_t tcnt = 0; if (tnow < told) { tcnt += told - tnow; } else { tcnt += (reload - tnow) + told; } told = tnow; if (tcnt >= ticks) { break; } } }}
毫秒延时函数:
void delay_ms(uint16_t nms) { for (uint16_t i = 0; i < nms; i++) { delay_us(1000); }}
HAL库实现细节
在HAL库中,systick的初始化和管理通过以下函数实现:
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0); return HAL_OK;}
- HAL_SYSTICK_Config函数用于设置systick的计数周期、重载值和时钟源。
- HAL_NVIC_SetPriority函数用于设置systick中断的优先级。
delay.c的优化实现
为了减少全局变量的耦合性,正点原子对delay.c进行了优化,实现了三种不同的写法:
第三种写法优化
对delay_us
函数进行了进一步优化:
void delay_us(uint32_t nus) { uint32_t told = SysTick_VAL; uint32_t fac_us = HAL_RCC_GetSysClockFreq() / 1000000; uint32_t ticks = nus * fac_us; uint32_t tnow, tcnt = 0; uint32_t reload = SysTick_LOAD; while (1) { tnow = SysTick_VAL; if (tnow < told) { tcnt += told - tnow; } else { tcnt += (reload - tnow) + told; } told = tnow; if (tcnt >= ticks) { break; } }}
该实现优化省去了外层循环结构,提高了代码的执行效率。
总结
systick在STM32F429开发中是一个强大的工具,支持多种定时和中断控制功能。通过HAL库和正点原子开发的延时函数,我们可以轻松实现精确的时延控制。在实际开发中,可以根据具体需求选择合适的定时接口,并通过优化代码实现更高效的时间管理。
发表评论
最新留言
关于作者
