GD32精确延时和时间戳

目前网上很多都是利用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();
}

版权声明:本文为CSDN博主「霍宏鹏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huohongpeng/article/details/114448446

生成海报
点赞 0

霍宏鹏

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

GD32F103基础教程—外部中断实验(八)

一、教程简介 本章主要是讲解GPIO输入实验,通过按键触发外部中断,控制LED2闪烁。 二、实验流程 1、工程配置 外部中断触发实验工程配置方法与第五章的配置方法一致,具体请查看第五章教程&#xff0c

GD32单片机介绍——兆易创新

目录 2.1 兆易创新GigaDevice 2.1.1发展历史 2.1.2市场表现 2.2 GD32单片机 2.2.1 官方资料 2.2.2 选型手册 2.1 兆易创新GigaDevice GD32单片机是指由国内芯片公司兆易创新

GD32F130之GPIO

简介 最多可支持 55 个通用 I/O 引脚(GPIO),分别为 PA0 ~ PA15,PB0 ~ PB15,PC0 ~ PC15, PD2,P