1.时钟的配置
我们使用内部时钟CK_INT
APB1是AHB分频产生,AHB=168M,APB1四分频后为42
APB1的分频系数是1,那么CK_INK就是APB1
APB1的分频系数不是1,那么CK_INK就是APB12
APB1的分频系数不是1,故CK_INK时钟为APB12=84M
2.计数模式
向上计数
![请添加图片描述](https://img-blog.csdnimg.cn/d9df0cdc084449b586259f6d5cfc8951.png
向下计数
中央对齐计数
3.定时器相关寄存器
1.CNT
当前值寄存器,向上就加,向下就减
2.TIMx_PSC
对时钟就行分频
3.TIMx_ARR
自动重装寄存器
4.TIMx_CR1
向上还是向下计数,使能
5.TIMx_DIER
中断使能寄存器
4.定时器HAL库函数
1.定时器时基部分初始化函数
HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);
初始化结构体
![请添加图片描述](https://img-blog.csdnimg.cn/d7f40075b1f543b594f2886b883bd8ea.png
TIM_Base_InitTypeDef Init;结构体
预分频,计数模式,自动装载值,时钟分频因子,重复计数次数(高级寄存器使用)
2.定时器时基部分初始化回调函数
HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);
进行定时器时钟使能与中断优先级
3.使能定时器
HAL_TIM_Base_Start(TIM_HandleTypeDef *htim);
使能定时器
HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
使能定时器以及定时器更新中断
3.定时器中断处理函数
HAL_TIM_TRQHandler(TIM_HandleTypeDef *htim);
这个是中断通用处理函数,在这个函数里面肯定有一个回调函数,我都懒得提
5.定时器中断实现步骤
1.使能定时器时钟
2.初始化定时器,配置ARR,PSC
3.开启定时器中断
4.设置中断优先级
5.编写中断服务函数
6.定时器中断实验代码
要求
配置定时器的中断,每500ms中断一次,在中断服务中控制LED1实现状态取反。
向下计数为例
溢出时间 t = (ARR+1)(PSC+1)/TCLK
0.5s
命
ARR+1=5000
PSC+1=9000
TCLK = 9*10^6
就得到0.5s
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
TIM_HandleTypeDef htim;
void TIM3_Init(void)
{
htim.Instance=TIM3;
htim.Init.Prescaler= 9000-1; //预分频
htim.Init.CounterMode= TIM_COUNTERMODE_UP; //向上模式
htim.Init.Period=5000-1; //装载值
HAL_TIM_Base_Init(&htim);
HAL_TIM_Base_Start_IT(&htim);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
__HAL_RCC_TIM3_CLK_ENABLE();
HAL_NVIC_EnableIRQ(TIM3_IRQn);
HAL_NVIC_SetPriority(TIM3_IRQn,1,3); //使能TIM3,1抢占,3优先
}
}
void TIM3_IRQHandler()
{
HAL_TIM_IRQHandler(&htim);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
LED0 = !LED0;
LED1 = !LED1;
printf("我中断了\r\n");
}
int main(void)
{
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART
LED_Init(); //初始化LED
KEY_Init(); //初始化按键
TIM3_Init();
HAL_TIM_Base_Init(&htim);
while(1)
{
}
}