| 上一篇 | 下一篇 |
|---|---|
| 通用定时器 2/3/4/5 的简介和框图 |
3.2)计数器时钟源寄存器设置方法
| 计数器时钟源类型 | 设置方法 |
|---|---|
| 内部时钟(CK_INT) | 设置 TIMx_SMCR 的 SMS=000、ECE=0 |
| 外部时钟模式1:外部输入引脚(TIx) | 设置 TIMx_SMCR 的 SMS=111 |
| 外部时钟模式2:外部触发输入(ETR) | 设置 TIMx_SMCR 的 ECE=1(走 ETRF 时钟线) |
| 内部触发输入(ITRx) | 级联太复杂,也不怎么用,设置可参考 STM32F10xxx参考手册_V10 |
具体的寄存器讲解,大家看视频看看就行:第92讲 入门篇-计数器时钟源_哔哩哔哩_bilibili。
3.3)通用定时器中断实验示例
使用定时器 3,实现 500ms 定时器更新中断,在中断里翻转 LED1 。
时钟源选择第一种,计数模式选择递增,其他的和基本定时器一样设置。
timer.c文件如下:
c
#include "timer.h"
#include "led.h"
TIM_HandleTypeDef TIM3_Handler; // 定时器句柄
/**
* @brief 通用定时器TIM3初始化(含中断)
* @param arr:自动重装值
psc:时钟预分频数
* @others 溢出时间:T_out=((arr+1)*(psc+1))/F_clk (us),F_clk=72000000Hz
*/
void TIM3_Init(u16 arr,u16 psc)
{
TIM3_Handler.Instance=TIM3; // 通用定时器3
TIM3_Handler.Init.Prescaler=psc; // 分频系数
TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP; // 向上计数器
TIM3_Handler.Init.Period=arr; // 自动装载值
TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1; //时钟分频因子
HAL_TIM_Base_Init(&TIM3_Handler);
HAL_TIM_Base_Start_IT(&TIM3_Handler); // 使能定时器3和定时器3更新中断:TIM_IT_UPDATE
}
/**
* @brief 定时器初始化回调函数,包括开启时钟、设置中断优先级
* @param htim:定时器句柄
* @others 此函数会被TIMx_Init()调用
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
__HAL_RCC_TIM3_CLK_ENABLE(); // 使能TIM3时钟
HAL_NVIC_SetPriority(TIM3_IRQn,1,3); // 设置中断优先级,抢占优先级1,子优先级3
HAL_NVIC_EnableIRQ(TIM3_IRQn); // 开启ITM3中断
}
}
/**
* @brief TIM3中断服务函数
*/
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&TIM3_Handler);
}
/**
* @brief 中断服务函数底层回调函数
* @others 此函数会被HAL_TIM_IRQHandler()调用,具体内容为TIM3溢出后翻转LED1
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&TIM3_Handler))
{
LED1=!LED1; // LED1反转
}
}
//// 以下代码没有使用定时器HAL库共用处理函数来处理,而是直接通过判断中断标志位的方式
//void TIM3_IRQHandler(void)
//{
// if(__HAL_TIM_GET_FLAG(&TIM3_Handler, TIM_FLAG_UPDATE)!= RESET)
// {
// LED1=!LED1; // LED1反转
// __HAL_TIM_CLEAR_IT(&TIM3_Handler,TIM_IT_UPDATE); // 清除定时器溢出中断标志位
// }
//}
timer.h文件如下:
c
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
void TIM3_Init(u16 arr,u16 psc); // 定时器初始化函数
#endif
main.c文件如下:
c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "string.h"
#include "stdio.h"
#include "timer.h"
int main(void)
{
HAL_Init(); // 初始化HAL库
Stm32_Clock_Init(RCC_PLL_MUL9); // 设置时钟,72M
delay_init(72); // 初始化延时函数
LED_Init(); // 初始化LED
KEY_Init(); // 按键初始化
uart_init(115200); // 串口1初始化
TIM3_Init(4999,7199); // 定时器初始化
while(1)
{
LED0=!LED0; // LED0翻转
delay_ms(200); // 延时200ms
}
}
结果和基本定时器的一样。