gd32 定时器时钟_基于GD32单片机定时器的软件定时器实现-可移植

1 概述

在单片机系统中,会有几个硬件定时器。在程序需要延时或者定时功能的时候需要使用定时器,但是在整个单片机里面定时器的数量是有限的。不可能每一个功能都去使用一个硬件定时器。对于时间要求不是很严格的场合,可以多个应用层功能共享使用一个定时器。所以这篇文章是基于一个硬件定时器写的一个软件定时器框架,可以移植到任何带有32位,16位,8位定时器的单片机中。本程序在GD32F350上面已经测试完成。有需要的朋友们可以移植到自己的平台上。这个定时器可以用在低功耗场景下(不能频繁中断),定时器不会频繁产生中断,根据具体时间计算产生中断的间隔。不会大量占用CPU资源。

2 定时器实现

soft_timer.h

#ifdef __cplusplus

extern "C" {

#endif

#ifndef __SOFT_TIMER_H__

#define __SOFT_TIMER_H__

#include

typedef void (*sw_func_cb_t)(void *cb_data);

#define SW_TIMER_HANDLE_MAGIC (0xdcba0000)

/*

* Step1: Call sw_timer_alloc() to allocate a software timer handle.

* Step2: Call sw_timer_start() to register the callback function and start the timer.

* Step3: Call sw_timer_stop() to stop timer , and you can call sw_timer_start to restart

* the timer.

* Step4: Call sw_timer_free() to free the allocated timer if it's no longer in use.

*/

int sw_timer_alloc(uint32_t *handle);

int sw_timer_free(uint32_t handle);

int sw_timer_start(uint32_t handle, uint32_t timeout_ms, sw_func_cb_t func, void *cb_data, uint8_t repeat);

int sw_timer_stop(uint32_t handle);

/*

* Call by hardware timer interrupt server

*/

void sw_timer_timeout_irq(void);

#endif

#ifdef __cplusplus

}

#endif

soft_timer.c

/*

* Copyright (C) 2020, 2020 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-09-18 huohongpeng First add

*

*/

#ifdef __cplusplus

extern "C" {

#endif

#include "soft_timer.h"

#include

#include

/*

* Software timer max number

* User to configurate [1-65535]

*/

#define SW_TIMER_MAX_NUMBER 100

/*

* Hardware timer max count value

* Note : depend on hardware platform, user to overwrite

*/

#define __HW_TIME_MAX_COUNT (0xffff)

/*

* Hardware timer how many count value equal 1ms

* Note : depend on hardware platform, user to overwrite

*/

#define __HW_TIME_COUNT_PER_MS 10

#include

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现不同频率闪烁 LED 灯,你可以使用 GD32定时器功能。下面是一个基本的示例代码,你可以根据自己的需求进行修改: 首先,需要初始化定时器和 LED 引脚。假设你的 LED 连接在 PA0 引脚上: ```c #include "gd32f30x.h" void timer_init(void) { /* 使能定时器时钟 */ rcu_periph_clock_enable(RCU_TIMER1); /* 配置定时器基本参数 */ timer_parameter_struct timer_initpara; timer_struct_para_init(&timer_initpara); timer_initpara.prescaler = 7199; // 设置预分频值,得到1ms的计数周期 timer_initpara.counter_mode = TIMER_COUNTER_UP; // 向上计数模式 timer_initpara.period = 999; // 设置周期为1s timer_initpara.clock_division = TIMER_CKDIV_DIV1; timer_initpara.repetition_counter = 0; timer_init(TIMER1, &timer_initpara); /* 使能定时器更新事件中断 */ timer_interrupt_enable(TIMER1, TIMER_INT_UP); /* 使能定时器 */ timer_enable(TIMER1); } void led_init(void) { /* 使能GPIOA时钟 */ rcu_periph_clock_enable(RCU_GPIOA); /* 配置PA0引脚为推挽输出 */ gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0); } int main(void) { /* 初始化定时器和LED */ timer_init(); led_init(); while (1) { /* 检查定时器更新事件 */ if (timer_flag_get(TIMER1, TIMER_FLAG_UP) != RESET) { /* 清除定时器更新事件标志 */ timer_flag_clear(TIMER1, TIMER_FLAG_UP); /* 切换LED状态 */ gpio_bit_write(GPIOA, GPIO_PIN_0, (bit_status)(1 - gpio_input_bit_get(GPIOA, GPIO_PIN_0))); } } } ``` 在上面这段代码中,定时器1被配置为每1秒触发一次更新事件中断。在中断处理函数中,我们切换 PA0 引脚的状态从而实现 LED 的闪烁效果。 如果你想要实现不同频率的闪烁,可以根据你的需求修改定时器的预分频值(prescaler)和周期值(period)。例如,如果你想要一个500ms的闪烁周期,你可以将预分频值设置为 3599,将周期值设置为 499。 希望这个示例能帮到你!如果有任何问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值