前言:
每来一个TIM 时钟CNT计数器就记一个数,记到某一个程度就会产生溢出。然后ARR就会装载到CNT计数器里面
一:TIM
1:介绍
TIM(Timer)定时器
定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时 (计数器、预分频器、自动重装寄存器构成时基单元)
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
时间计算:频率 = CK_PSC (72MHZ) / (PSC+1) / (arr+1) 周期= 1 / 频率
最大计数时间:72000 000/65536/65536=0.0167638063430786-----频率
周期:1/0.0167638063430786=59.6523235555556-------最大计数周期
2:定时器的分类
STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4
我们STM32F1C8T6系列中的定时器全部都是16位的,也就以为着最大计数位2^16-1=65535
高级定时器比通用定时器多了一个重复次数寄存器;
每个定时器都会有4个通道;定时器1和定时器2多了一个ETR通道;高级定时器1有3个互补通道:1,2,3。都涉及了MDA操作
3:计数器
计数器分为3种计数方式
自动重装载寄存器=自动重装载寄存器+1 可以看到了自动重装载的值(ARR) 加到36,再加一个数(实际就是加到了37);才溢出
自动重装载寄存器=自动重装载寄存器+1 可以看到了自动重装载的值(ARR) 减到0,再减一个数;才溢出 和上面的 递增计数模式一样
自动重装载寄存器=自动重装载寄存器; 和上面的2种计数方法不同,少了一个1;arr写多少就会在多少溢出
当计数器配置为中央对齐模式或编码器模式时,DIR位为只读。
3:基本定时器
A:介绍
注意我们使用的STM32F103C8T6这个型号的版主没有基本定时器,我们使用其他型号的STM32板子,来完成我们基本定时器的实验
1 : 预分频器+CNT计数器+自动重装载寄存器=时基单元
2 : 基本定时器只能选择内部时钟;他们都为16位的
预分频器 : 可以对72MHZ的计数时钟进行预分频处理; 对输入的基准频率提前进行一个分频的操作
eg : 预分频器写0,那就是不分频,或者说是1分频 ; 输出频率=输入频率=72MHz
预分频器写1,那就是2分频,输出频率(实际分频系数)=输入频率/2=36MHz
预分频器写2,那就是3分频,输出频率(实际分频系数)=输入频率/3= 24MHz
所以预分频器的值和实际的分频系数相差了1; 实际分频系数=预分频器的值+1
递增计数器 : 计数器可以对预分频后的计数时钟进行计数,预分频器每来一个上升沿计数器就+1
所以计数器的值在计时过程中会不断地自增运行,直到达到目标值(自动重装载寄存器)然后产生中断,然后在重新开始计数
自动重装载寄存器(固定值) : 储存的是我们的计数目标,产生中断的目标值,(当计数器达到目标值就产生中断) 自动重装载寄存器=自动重装载寄存器+1
流程: 基准时钟------->预分频器------>计数器<--------->自动重装载计数器
计数器不断自增,会和自动重装载寄存器比较,当两个的值相同时,产生更新事件中断和DMA请求;
cpu会响应更新中断
B:时间计算
溢出时间其实实际上就是周期
C:HAL库配置
要使能定时器定时的话,就必须打开中断使能也就是3,CNT==ARR溢出产生的中断
D:HAL库函数
UEV:只有一种事件引起中断或者DMA请求,即计数器上溢的更新事件(UEV),就是CNT=ARR是发生的溢出事件。
中断ISR:就是中断号,在汇编语言中写,比如下面的:
void TIM2_IRQHandler()
{}
4:通用定时器
A:介绍
外部时钟模式:常用情况-->A:对外部电平高低的变换进行一个计数
B:选择计数器时钟源
5:高级定时器
6:定时器的基本结构
7:HAL函数总结
其他通用操作函数
自动重装载值(AutoReloadPreload): X.Init.AutoReloadPreload,如果我们中间需要改变ARR的值需要写这个:
1:DISABLE(失能,关闭缓存区):如果我们中途需要改变ARR的值,关闭缓存区,ARR会直接变为改的数据,并CNT==改的数据时发生更新中断。
2:ENABLE(使能,打开缓存区):打开缓存区,ARR值不会立即改变,而是在下次把新的ARR值写入,当CNT=ARR时发生溢出
在代码总结事件中验证
中断处理
中断事件类型
HAL_TIM_IRQHandler和中断回调函数
二:定时中断功能
定时器有很多功能:07:HAL------定时器功能(输出比较PWM)
CSDNhttps://mp.csdn.net/mp_blog/creation/editor/137024445
08:HAL---定时器功能(输入捕获功能)
CSDNhttps://mp.csdn.net/mp_blog/creation/editor/137085008
三:代码
A:基本定时器
使用基本定时器控制LED,注意我们STM32C8T6这个板子没有基本定时器,需要使用其他的板子
这个是直接计算的周期
使用的是内部时钟源
TIM_HandleTypeDef g_timx_handle;/* 定时器中断初始化函数 */
void btim_timx_int_init(uint16_t arr, uint16_t psc)
{g_timx_handle.Instance = TIM6;g_timx_handle.Init.Prescaler = psc;g_timx_handle.Init.Period = arr;HAL_TIM_Base_Init(&g_timx_handle);//CNT==ARR溢出产生的中断HAL_TIM_Base_Start_IT(&g_timx_handle);
}/* 定时器基础MSP初始化函数 */
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM6){__HAL_RCC_TIM6_CLK_ENABLE();HAL_NVIC_SetPriority(TIM6_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM6_IRQn);}
}/* 定时器6中断服务函数 */
void TIM6_IRQHandler(void)
{HAL_TIM_IRQHandler(&g_timx_handle);
}/* 定时器溢出中断中断回调函数 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM6){LED0_TOGGLE();}
}