一、引言
介绍
TIMER定时器是一种广泛应用于微控制器中的硬件模块,用于实现精确的时间测量和控制。定时器可以产生精确的延时、计数事件和定时中断,支持多种工作模式如单次、连续、PWM(脉宽调制)和捕获比较等。它们在控制系统中扮演着重要角色,被广泛应用于实时控制、信号生成、频率测量和事件计数等场景。
工作原理
TIMER定时器的工作原理是通过内部时钟源驱动一个计数器,根据预设的分频器将时钟频率分频后进行计数。当计数器达到预设的自动重载值时,会产生溢出事件或中断,触发相应的处理程序。定时器可以配置为向上计数、向下计数或双向计数模式,通过设定不同的计数值和触发条件,定时器可以实现精准的定时、PWM输出、输入捕获和输出比较等功能。
二、代码
1.main.c
GENERAL_TIMx_Configuration()
用来初始化通用定时器,使其每1毫秒触发一次中断并执行中断服务函数(见tim.c)使timer_count+1
程序在主循环中不断检查timer_count
的值,当timer_count
达到500,即0.5s时,将其重置为0,并调用LED1_Turn()
切换LED的状态,循环往复,则实现每0.5s切换一次LED的状态,实现LED的周期性闪烁
#include "stm32f10x.h"
#include "LED.h"
#include "tim.h"
__IO uint16_t timer_count=0;
int main(void)
{
/* 初始化板载LED灯 */
LED_Init();
/* 通用定时器初始化:1ms中断一次 */
GENERAL_TIMx_Configuration();
/* 无限循环 */
while (1)
{
if(timer_count==500)
{
timer_count=0;
LED1_Turn();
}
}
}
2.tim.c
GENERAL_TIMx_NVIC_Configuration()用于中断优先级配置
GENERAL_TIMx_Configuration()用于初始化并配置定时器,使其每1毫秒触发一次中断
GENERAL_TIM_INT_FUN()是定时器的中断服务程序,当定时器产生更新事件(每1毫秒)时调用,用于使timer_count+1
具体请见代码旁的注释
#include "stm32f10x.h"
#include "tim.h"
// 计数器变量,记录定时器中断次数
extern __IO uint16_t timer_count;
/**
* 函数功能: 通用定时器 TIMx,x[2,3,4,5]中断优先级配置
* 输入参数: 无
* 返 回 值: 无
* 说 明:配置定时器中断的优先级
*/
void GENERAL_TIMx_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 设置中断优先级分组 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* 设置中断来源为通用定时器的中断 */
NVIC_InitStructure.NVIC_IRQChannel = GENERAL_TIM_IRQ;
/* 设置主优先级为 0 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
/* 设置抢占优先级为3 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
/* 使能定时器中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 应用中断配置 */
NVIC_Init(&NVIC_InitStructure);
}
/**
* 函数功能: 通用定时器 TIMx,x[2,3,4,5]配置
* 输入参数: 无
* 返 回 值: 无
* 说 明:初始化定时器,使其每1毫秒触发一次中断
*/
void GENERAL_TIMx_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* 开启TIMx的时钟,TIMx内部时钟CK_INT=72M */
GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK, ENABLE);
/* 配置定时器中断优先级 */
GENERAL_TIMx_NVIC_Configuration();
/* 设置自动重装载寄存器值(计数值) */
TIM_TimeBaseStructure.TIM_Period = 1000 - 1;
/* 设置预分频器,时钟分频为72(71 + 1),即定时器计数频率为1MHz */
TIM_TimeBaseStructure.TIM_Prescaler = 71;
/* 时钟分频因子(未使用) */
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
/* 设置计数模式为向上计数 */
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
/* 初始化定时器TIMx */
TIM_TimeBaseInit(GENERAL_TIMx, &TIM_TimeBaseStructure);
/* 清除定时器更新中断标志位 */
TIM_ClearITPendingBit(GENERAL_TIMx, TIM_IT_Update);
/* 使能定时器更新中断 */
TIM_ITConfig(GENERAL_TIMx, TIM_IT_Update, ENABLE);
/* 启动定时器 */
TIM_Cmd(GENERAL_TIMx, ENABLE);
}
/**
* 函数功能: 通用定时器中断处理函数
* 输入参数: 无
* 返 回 值: 无
* 说 明:在定时器产生更新事件时调用,增加计数器timer_count
*/
void GENERAL_TIM_INT_FUN(void)
{
/* 检查更新中断标志位是否置位 */
if (TIM_GetITStatus(GENERAL_TIMx, TIM_IT_Update) != RESET)
{
/* 增加计数器timer_count */
timer_count++;
/* 清除定时器更新中断标志位 */
TIM_ClearITPendingBit(GENERAL_TIMx, TIM_IT_Update);
}
}
3.tim.h
配置通用定时器 TIM2,进行宏定义和函数声明。
#ifndef __TIM_H__
#define __TIM_H__
#include <stm32f10x.h>
#define GENERAL_TIMx TIM2
#define GENERAL_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd
#define GENERAL_TIM_CLK RCC_APB1Periph_TIM2
#define GENERAL_TIM_IRQ TIM2_IRQn
#define GENERAL_TIM_INT_FUN TIM2_IRQHandler
void GENERAL_TIMx_Configuration(void);
void GENERAL_TIMx_NVIC_Configuration(void);
void GENERAL_TIM_INT_FUN (void);
#endif
4.其他
LED.c和之前一样不用改
三、实验结果
每0.5s切换一次状态,每1秒实现一次亮灭
作业五
四、总结
这次作业让我更好地了解了TIMER定时器,在老师给的代码基础上进行修改,顺利完成了本次作业,锻炼了我的动手实践能力,拓展了专业知识,令我受益匪浅