STM32 SysTick秒用
2022-08-10 来源:csdn
这里针对的是无操作系统的情况下的使用。之前一直想利用systick既实现记录系统运行时间又能够精确实现微秒延时的功能,如果将SysTick的定时器的定时中断时间设置为1us,这在有些情况下会导致死机的问题。这样的话就无法利用systick来实现us延时函数了。
利用SysTick实现1ms定时中断,us延时函数可以利用SysTick的寄存器来运算得到精确的延时函数,具体实现如下:
头文件:
#ifndef __SYSTICK_H
#define __SYSTICK_H
#ifdef __cplusplus
extern 'C' {
#endif
/* Includes ------------------------------------------------------------------*/
#include 'stm32f10x.h'
#define millis getCurrentMillis
#define micros getCurrentMicros
#define delay delay_ms
void systick_init(void);
void systick_reset(void);
uint32_t getCurrentMillis(void);
uint32_t getCurrentMicros(void);
void delay_ms(uint32_t ms);
void delay_us(uint32_t us);
#ifdef __cplusplus
}
#endif
#endif /*__SYSTICK_H */
源文件:
/* Includes ------------------------------------------------------------------*/
#include 'bsp_systick.h'
__IO uint32_t _ms_tick = 0;
/**
* @brief initialize systick
* @param None
* @retval None
*/
void systick_init(void)
{
_ms_tick = 0;
/* SystemCoreClock / 1000 1ms中断一次 */
if(SysTick_Config(SystemCoreClock / 1000))
{
/*capture error*/
while(1);
}
}
/**
* @brief 获取系统当前的ms计数值
* @param None
* @retval 系统当前时间ms
*/
uint32_t getCurrentMillis(void)
{
return _ms_tick;
}
/**
* @brief 获取系统当前的us计数值
* @param delay time
* @retval 系统当前时间us
*/
uint32_t getCurrentMicros(void)
{
/* Ensure COUNTFLAG is reset by reading SysTick control and status register */
//LL_SYSTICK_IsActiveCounterFlag();
uint32_t m = getCurrentMillis();
const uint32_t tms = SysTick->LOAD + 1;
__IO uint32_t u = tms - SysTick->VAL;
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk)) {
m = getCurrentMillis();
u = tms - SysTick->VAL;
}
return (m * 1000 + (u * 1000) / tms);
}
/**
* @brief 复位系统计数
* @param None
* @retval None
*/
void systick_reset(void)
{
_ms_tick = 0;
}
/**
* @brief delay (ms)
* @param delay time
* @retval None
*/
void delay_ms(uint32_t ms)
{
uint32_t target;
target = millis() + ms;
while(millis() < target);
}
/**
* @brief delay (us)
* @param delay us time
* @retval None
* @attention 延时的us数不应特别大,否则会导致nbTicks在计算时会溢出。
*/
void delay_us(uint32_t us)
{
__IO uint32_t currentTicks = SysTick->VAL;
/* Number of ticks per millisecond */
const uint32_t tickPerMs = SysTick->LOAD + 1;
/* Number of ticks to count */
uint32_t nbTicks = ((us - ((us > 0) ? 1 : 0)) * tickPerMs) / 1000;
/* Number of elapsed ticks */
uint32_t elapsedTicks = 0;
__IO uint32_t oldTicks = currentTicks;
do {
currentTicks = SysTick->VAL;
elapsedTicks += (oldTicks < currentTicks) ? tickPerMs + oldTicks - currentTicks :
oldTicks - currentTicks;
oldTicks = currentTicks;
} while (nbTicks > elapsedTicks);
}
/**
* @brief SYSTICK中断服务函数
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
_ms_tick++;
}