GD32精确延时和时间戳

本文介绍了一种使用低频率Systick中断实现的高CPU效率计时方案,包括毫秒和微秒延时功能,以及系统时间戳的获取和应用,适用于精确的时间测量和日志记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前网上很多都是利用systick频繁产生中断进行计数,然后实现延时。我写的这写接口,systick产生中断的频率很低,cpu效率很高。而且同时实现了毫秒延时,微秒延时,以及系统时间戳,系统时间戳可以用于测量时间,日志打印等功能

 platform_systick.h

#ifndef __PLATFORM_SYSTICK_H__
#define __PLATFORM_SYSTICK_H__

#include <stdint.h>

uint32_t get_systick_us(void);
uint32_t get_systick_ms(void);

void delay_ms(uint32_t ms);
void delay_us(uint32_t us);
void systick_deinit(void);
/*
 * Call by Systick interrupt server
 */
void systick_handler(void);

#endif

 platform_systick.c

/*
 * Copyright (C) 2020, 2021  huohongpeng
 * Author: huohongpeng <1045338804@qq.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Change logs:
 * Date        Author       Notes
 * 2020-10-29  huohongpeng   First add
 * 2021-11-28  huohongpeng   fix bug [systick_ms, systick_us update can't synchronization with SysTick->VAL update]
 */
#include "platform_systick.h"
#include <gd32f30x.h>

/*
 * Systick select external clock source
 * value is 0.5s clock count number
 * User overwrite the macro define value
 */
#define SYSTICK_EXT_CLOCK_500MS_CNT (120000000/8/2)

volatile static uint32_t systick_ms = 0;
volatile static uint32_t systick_us = 0;
volatile static uint8_t is_init = 0;

static void systick_init(void)
{
	__disable_irq();
	is_init = 1;
	SysTick->LOAD  = SYSTICK_EXT_CLOCK_500MS_CNT; 
	SysTick->VAL   = SYSTICK_EXT_CLOCK_500MS_CNT;
	SysTick->CTRL  = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
	__enable_irq();
}

void systick_deinit(void)
{
	__disable_irq();
	is_init = 0;
	SysTick->CTRL  &= (~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk));
	__enable_irq();
}

void delay_us(uint32_t us)
{
	if (!is_init) systick_init();

	uint32_t end_count = 0, current = 0;

	current = get_systick_us();
	end_count = current + us;

	if (end_count == current) {
		return;
	} else if (end_count > current) {
		while (get_systick_us() < end_count);
	} else {
		while (get_systick_us() >= current);
		while (get_systick_us() < end_count);
	}
}

void delay_ms(uint32_t ms)
{
	if(!is_init) systick_init();

	uint32_t end_count = 0, current = 0;

	current = get_systick_ms();
	end_count = current + ms;

	if (end_count == current) {
		return;
	} else if (end_count > current) {
		while (get_systick_ms() < end_count);
	} else {
		while (get_systick_ms() >= current);
		while (get_systick_ms() < end_count);
	}
}

/*
 * Max 4294967295(us)=4294967(us)=4294(s)=71(min)
 */
uint32_t get_systick_us(void)
{
	if (!is_init) systick_init();

	uint32_t _systick_us, _val;

	do {
		_systick_us = systick_us;
		_val = SysTick->VAL;
	} while (_systick_us != systick_us);

#if 0
	/*
	 * 64bit, low efficiency 
	 */
	uint64_t tick = (SYSTICK_EXT_CLOCK_500MS_CNT - _val); 
	uint32_t tick_us =(tick * 1000 * 500) / SYSTICK_EXT_CLOCK_500MS_CNT;
#else
	/*
	 * 32bit, high efficiency 
	 */
	uint32_t tick = (SYSTICK_EXT_CLOCK_500MS_CNT - _val);
	uint32_t tick_us =(tick * 200) / (SYSTICK_EXT_CLOCK_500MS_CNT / 2500);
#endif

	return (tick_us + _systick_us);
}

/*
 * Max 4294967295(ms)=4294967(s)=71582(min)=1193(hour)=49(day)
 */
uint32_t get_systick_ms(void)
{
	if (!is_init) systick_init();

	uint32_t _systick_ms, _val;

	do {
		_systick_ms = systick_ms;
		_val = SysTick->VAL;
	} while (_systick_ms != systick_ms);

	uint32_t tick = (SYSTICK_EXT_CLOCK_500MS_CNT - _val);
	uint32_t tick_ms = tick / (SYSTICK_EXT_CLOCK_500MS_CNT / 500);
	tick_ms = tick_ms + _systick_ms;

	return tick_ms ;
}

/*
 * Call by Systick interrupt server
 */
void systick_handler(void)
{
	systick_us += 500 * 1000;
	systick_ms += 500;
}


void SysTick_Handler(void)
{
	systick_handler();
}

 

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值