既是TIM2也是TIM5,就看你配置了。但两个不能同时配置,至少在引脚功能上不能冲突,也就是说你可以用TIM2的PWM,同时也可以使用TIM5的定时器功能,因为定时器功能并不会通过引脚输出信号,所以没有冲突。
配置定时器的步骤:
1)开对应定时器时钟
2)定义结构体
3)配置
4)中断函数使能
5)使能定时器
*注:你可以在用函数的时候“|”上另一个定时器,或者重复操作以上步骤。
配置优先级:
1)定义个结构体
2)设置优先级组别
3)初始化设置
前期准备:
STM32CubeMX
STM32RCT6核心板
IDE Keil(MDK-ARM)
STM32CubeMX部分
1. 配置时钟
选择STM32F103RCTx系列芯片,配置时钟的同时会自动配置IO口引脚
在这里插入图片描述
将HCLK设置为最大频率72MHz
在这里插入图片描述
2.配置TIM
在这里插入图片描述
Internal Clock(内部时钟)
Prtscaler (定时器分频系数) : 71
Counter Mode(计数模式) Up(向上计数模式)
Counter Period(自动重装载值) : 999
CKD(时钟分频因子) :No Division (不分频 )
auto-reload-preload(自动重装载) : Enable (使能)
在这里插入图片描述
勾选update interrupt(更新中断)
1. 定时器溢出时间计算公式:
在这里插入图片描述
Tout:中断溢出的时间
arr:自动重装载值
psc:定时器分频系数
Tclk:时钟频率
Tout = ((71+1)*(999+1))/72 us
Tout = ( 72 * 1000 ) / 72 us
1000us = 1ms
所以这里我们的定时时间为:1ms
也就是说单片机1ms进入一次定时器中断
2. 定时器计数模式:
向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
向上/向下计数模式(中央对齐模式):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
在这里插入图片描述
2. 计数时钟:
内部时钟(TIMx_CLK):
外部时钟模式1:外部捕捉比较引脚(TIx)
外部时钟模式2:外部引脚输入(TIMx_ETR)
内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。
3.配置IO口
在这里插入图片描述
将PB0设置为:
低电平
Output模式
既不上拉也不下拉
响应速度低
4. 工程生成
在这里插入图片描述
在这里插入图片描述
工程管理依旧是这几个选项,然后GENERATE CODE,STM32CubeMX部分完成。
MDK 5部分
HAL_TIM_IRQHandler(htim1);//定时器中断处理函数
此函数的作用是判断中断是否正常,是哪一类定时器中断(溢出中断/捕获中断/PWM中断…),然后进入相应的中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器溢出中断回调函数
定时器中断时,每进行完一个中断,并不会立刻退出,而是会进入到中断回调函数中
点开main.c在这里插入图片描述
在如图位置上添加
HAL_TIM_Base_Start_IT(htim1);//开启定时器1
1
1
然后再tim.c文件中,添加
/* USER CODE BEGIN 0 */
uint16_t Tim_cnt = 0; //定时器计数
/* USER CODE END 0 */
1
2
3
1
2
3
然后在tim.c文件中重写
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)函数
在这里插入图片描述
/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim-Instance == htim1.Instance)
{
Tim_cnt++;
if(Tim_cnt==500) //0.5s进行一次下列代码
{
Tim_cnt=0; //清0
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
}
}
}
/* USER CODE END 1 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
设一个全局变量,每进一次中断+1,因为1ms进入一次中断,所以当Tim_cnt=500的时候(即0.5s)写入我们需要运行的代码(不要忘记清0)
编译下载时需要选择相对应的下载器,勾选以下
在这里插入图片描述
运行即可
本期工程文档——Gitee
在这里插入图片描述
首先我们来看一下定时器的基本框图:
不管是做PWM输出、定时中断还是输入捕获都肯定要搞清楚CK_INT 从哪里来,频率是多少?才能正确使用定时器。时钟肯定是来自时钟树,那我们就要去Reference manual里找找:
时钟源确实可以找到,但注意时钟存在翻倍可能性!if APBx PRESC= 1 x1 else x2 : 直接理解是如果APBx PRESC 预分频 设置成1 timer时钟等于APBx 不然 timer时钟为2倍APBx 。可是还是没有找到时钟源和timer时钟具体数值关系,这个就要去Datasheet里找了,找MCU系统框图:
我们发现有2个APB(Advanced Peripheral Bus) ,最大主频还还不一样,分别挂了多个定时器。到这里我们总算找到了timer的具体关联的时钟源了。如何计算频率呢?
举例1:假设使用的是timer2 AHB1=168MHz
// Timer2 On APB1 42MHz(MAX) == 可设 APB1 PRESC =4 APB1 =42MHz。
// if APBx PRESC = 1x1 else x2 == Timer2_CLK = 42MHz*2 = 84MHz 。
举例2:假设使用的是timer1、timer2 AHB1= 84 MHz
// Timer2 On APB1 42MHz(MAX) == 可设 APB1 PRESC =2 APB1 =42MHz。
// if APBx PRESC = 1x1 else x2 == Timer2_CLK = 42MHz*2 = 84MHz 。
// Timer1 On APB2 84MHz(MAX) == 可设 APB2 PRESC =1 APB2 =84MHz。
// if APBx PRESC = 1x1 else x2 == Timer1_CLK = 84MHz*1 = 84MHz 。
参考资料:1. Reference manual 2.Datasheet
本文标签:stm32配置timer2