定时器分为硬件定时器和软件定时器,几乎所有的微控制器上都配备了数量有限的硬件定时器,即控制器本身有专门实现定时的模块。几乎所有的硬件定时器的工作原理都是一样的:定时器在外部时钟提供的周期脉冲下进行计数工作,当计数到用户指定的次数时,就产生一次中断。这个过程完全由微控制器内部的定时器硬件电路实现,不需要 CPU 干预。
相比之下,软件定时器则需要 CPU 的介入来实现了。实现软件定时器一般有两种方法:一种是纯粹依赖 CPU 指令的堆积来实现;另一种是以硬件定时器产生的时间片为基准单位,CPU 基于这个基准单位进行累积来实现。
显然,硬件定时器的精度取决于驱动的时钟脉冲,一般情况下可以达到很高的精度(纳秒级),而软件定时器的实现由于引入了非硬件因素,精度必然有所下降。
在嵌入式应用中,经常使用定时器进行定时,当定时时间到达之后执行预定的操作。一个具体的嵌入式系统可能有几个甚至数十个定时应用,而这些应用对定时器的精度、最大周期等要求往往都是不同的。比如使用定时器产生一个准确频率的方波是对定时精度比较高的应用,而使用定时器定时翻转一个用户指示灯以表示当前设备的工作状态,则对定时器精度的要求大为下降,这时如果启用硬件定时器无疑是一种资源的浪费。所以,在一个具体的嵌入式系统中,硬件定时器和软件定时器配合使用,是提高性能和降低成本的有效方法。
那么,在 STM32 中如何利用一个硬件定时器构建多个软件定时器呢?
我们来分析软件定时器的基本需求:在嵌入式应用中,对定时器的使用模式一般是“定时时间到达后执行预定的操作”。所以需要解决如下一些问题:
1、 定时多久?——定时时间必须是可配置修改的;
2、 定时时间到达后做什么?——需要指定执行函数;
3、 定时器如何工作?——可以选择单次执行或循环执行。
具体实现如下:
【头文件 softtimer.h】
#ifndef __SOFT_TIMER_H__
#define __SOFT_TIMER_H__
#include "stm32f10x.h"
/* 单次执行 */
#define TIMER_ONESHOT 0
/* 循环执行 */
#define TIMER_PERIOD 1
/* 软件定时器结构体信息块 */
typedef struct __TIMER
{
u32 Timeoutcnt; // 表示定时器软件计数变量
u32 Timeout; // 表示定时器单次定时周期
void (*Timeoutfunc)(void *parameter); // 定时到达后的执行函数
void *Parameter; // 执行函数的参数
u8 Timerflag; // 表示定时器处于单次执行模式还是循环执行模式
}Timer_typedef;
extern Timer_typedef TimerList[10];
/* 初始化软件定时器 */
extern void TIMER_TimerInitialisation(void);
/* 启动一个软件定时器 */
extern void
TIMER_TimerStart(u8 TimerIdent,
u32 Timeout,
void (*Timeoutfunc)(void *parameter),
void *parameter,
u8 flag);
/* 用于判断定时时间是否到达,并执行对应函数 */
extern void TIMER_Execute(void);
#endif
上一篇:STM32网络丢包问题分析
下一篇:STM32 硬件I2C 到底是不是个坑?
推荐阅读最新更新时间:2024-11-07 05:58
设计资源 培训 开发板 精华推荐
- AD5328 八通道、12 位数模转换器的典型应用
- 使用 ON Semiconductor 的 NCP5381 的参考设计
- 自用SlimeVR-带充电座
- LT6654AMPS6-1.25、16 位 ADC 电压基准的典型应用
- AD9259-50EBZ,用于评估 AD9259 四通道、14 位、50 MSPS 串行 LVDS ADC 的评估板
- LTC3630AIMSE 4V 至 24V 输入至 3.3V 输出、具有外部软启动、小尺寸的 250mA 稳压器的典型应用电路
- EVAL-AD5372EB,使用 AD5372、32 通道、16 位、串行输入、电压输出 DAC 的评估板
- ADS1018IDGST模块
- LTC1701,高效率 2.5V/500mA 降压稳压器
- 使用 Microchip Technology 的 TC2575 的参考设计