STM32F103 定时器中断实验
程序员文章站
2022-04-01 15:37:05
...
实验目的
STM32集成了丰富的定时器资源,通过本实验学习STM32的定时器(TIM)的使用,数据手册请参看第13,14 ,15章
实验简介
STM32一共8个都为16位的定时器。其中TIM6,TIM7 是基本定时器;TIM2,TIM3,TIN4,TIM5是通用定时器:TIM1和TIM8是高级定时器。
基本定时器(TIM6和TIM7)
这两个定时器只具备最基本的定时器功能,就是累加的时钟脉冲超过预定值时,能触发中断或触发DMA请求。由于在芯片内部与DAC外设相连,可通过触发输出驱动DAC。也可以作为其它通过定时器的时钟基准,框图如下:
通用定时器(TIM2~TIM5)
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。
使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整
高级定时器(TIM1和TIM8)
TIM1和TIM8是两个高级定时器,他们具有基本,通用定时器的所有功能,还具有三相六步电机的接口,刹车功能(break function)及用于PWM驱动电路的死区时间控制等,使得它非常适合于电机控制。
代码
main.c
#include MyIncludes.h
void timetick_isr(void)
{
HAL_HPIO_TogglePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5);
}
int main(void)
{
System_Init();
LED_Init();
SysTick_Init(NULL);
Timer_Init(1,1000,timetick_isr);
//定时器中断初始化
//三个参数: 使用TIM1 自动重载值参数
//函数指针
while(1)
{
}
}
Timerx.h
#ifndef __TIMERX_H_
#define __TIMERX_H_
#include "stm32f1xx.h"
#include "stm32_types.h"
#include "stm32f1xx_hal.h"
typedef struct
{
void (*T1_Handle)(void);
void (*T2_Handle)(void);
void (*T3_Handle)(void);
void (*T4_Handle)(void);
void (*T5_Handle)(void);
void (*T6_Handle)(void);
void (*T7_Handle)(void);
void (*T8_Handle)(void);
}_TIMER_ISR;
//定时器中断中运行的函数的结构体
void Timer_Init(uint8_t timer_num,uint32_t ms,void (*ISR)(void));
//定时器初始化函数
#endif
Timerx.c
#include "Timerx.h"
_TIMER_ISR Timer_ISR;
//定时器中断结构体变量声明
TIM_HandleTypeDef Tim1_Handle;
TIM_HandleTypeDef Tim3_Handle;
TIM_HandleTypeDef Tim4_Handle;
TIM_HandleTypeDef Tim7_Handle;
void Timer_Init(uint8_t timer_num,uint32_t ms,void(*ISR)(void))
{
TIM_TypeDef *TIMx;
uint32_t uwPrescalerValue = 0;
uwPrescalerValue = (uint32_t)((SystemCoreClock)/10000)-1;
//时钟预分频系数:(72000000/10000)-1 =719
//计数频率 = 时钟频率/(时钟预分频系数+1)
//72000000/(719+1)=1000000 = 0.1ms;
//0.1ms计数频率
//(感觉单位应该是MHz,这上面写的是ms)
if(timer_num == 1)
//定时器1,高级定时器
{
TIMx = TIM1;
__HAL_RCC_TIM1_CLK_ENABLE();
//定时器1使能
Timer_ISR.T1_Handle = ISR;
Tim1_Handle.Instance = TIMx;
//设置定时器
Tim1_Handle.Init.Period = 10 * ms - 1; //自动重装值
Tim1_Handle.Init.Prescaler = uwPrescalerValue;
//设置计数频率为0.1ms计一次数
Tim1_Handle.Init.ClockDivision = 0;
//时钟不分频,来自RCC
Tim1_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
//递增计数
HAL_TIM_Base_Init(&Tim1_Handle);
//初始化定时器参数
HAL_TIM_Base_Start(&Tim1_Handle);
//使能定时器及中断
HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn,4,0);
// 配置NVIC中断
HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
//使能中断
}
else if( timer_num ==3 )
{
TIMx = TIM3;
__HAL_RCC_TIM3_CLK_ENABLE();
Timer_ISR.T3_Handle = ISR;
Tim3_Handle.Instance = TIMx;
Tim3_Handle.Init.Period = 10 * ms -1;
Tim3_Handle.Init.Prescaler = uwPrescalerValue;
Tim3_Handle.Init.ClockDivision = 0;
Tim3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_Base_Init(&Tim3_Handle);
HAL_TIM_Base_Start_IT(&Tim3_Handle);
HAL_NVIC_SetPriority(TIM3_IRQn,4,0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
}
else if( timer_num ==4 )
{
TIMx = TIM4;
__HAL_RCC_TIM4_CLK_ENABLE();
Timer_ISR.T4_Handle = ISR;
Tim4_Handle.Instance = TIMx;
Tim4_Handle.Init.Period = 10 * ms - 1;
Tim4_Handle.Init.Prescaler = uwPrescalerValue;
Tim4_Handle.Init.ClockDivision = 0;
Tim4_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_Base_Init(&Tim4_Handle);
HAL_NVIC_SetPriority(TIM4_IRQn,4,0);
HAL_NVIC_EnableIRQ(TIM4_IRQn);
}
else if( timer_num == 7)
{
TIMx = TIM7;
__HAL_RCC_TIM7_CLK_ENABLE();
Timer_ISR.T7_Handle = ISR;
Tim7_Handle.Instance = TIMx;
Tim7_Handle.Init.Period = 10 * ms - 1;
Tim7_Handle.Init.Prescaler = uwPrescalerValue;
Tim7_Handle.Init.ClockDivision = 0;
Tim7_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_Base_Init(&Tim7_Handle);
HAL_TIM_Base_Start_IT(&Tim7_Handle);
HAL_NVIC_SetPriority(TIM7_IRQn,4,0);
HAL_NVIC_EnableIRQ(TIM7_IRQn);
}
}
void TIM1_UP_TIM10_IRQHandler(void)
//TIMER中断服务函数
{
HAL_TIM_IRQHandler(&Tim1_Handle);
//处理定时器1中断请求函数
}
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&Tim3_Handle);
}
void TIM4_IRQHandler(void)
{
HAL_TIM_IRQHandler(&Tim4_Handle);
}
void TIM7_IRQHandler(void)
{
HAL_TIM_IRQHandler(&Tim7_Handle);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
//用户回调函数,在HAL_TIM_IRQHandler中调用
{
if(htim == &Tim1_Handle)
{
if(Timer_ISR.T1_Handle != NULL)
Timer_ISR.T1_Handle();
//定时器1回调
}
else if( htim == &Tim3_Handle)
{
if(Timer_ISR.T3_Handle != NULL)
Timer_ISR.T3_Handle();
}
else if( htim == &Tim4_Handle)
{
if(Timer_ISR.T4_Handle!= NULL)
Timer_ISR.T4_Handle();
}
else if(htim == &Tim7_Handle)
{
if(Timer_ISR.T7_Handle != NULL)
Timer_ISR.T7_Handle();
}
}