STM32之CubeMX学习笔记(10)定时器常用功能归纳


STM32的定时器

定时器应该是各位单片机学习者学完GPIO后第一个学习的内容了吧。在嵌入式芯片中,操作定时器是非常基础且重要的事,灵活使用定时器也是嵌入式软件的精髓,在略微顶层的设计中,由于更多地是与人交互,所以ms级定时器已经非常够用了,但是在操作底层时,很多us级的定时器都只能勉强够用,也有的是直接接入芯片的频率进行最快速的操作。

在学32单片机前,我先学的是51单片机。可怜的51单片机只有两个定时器,还都是16位的,在做一些复杂应用的时候是根本不够用,甚至还要一个定时器拆成两个定时器来用(真实存在)。但在学习stm32过后,就算是入门的F103,定时器资源都是用不完的。而且stm32的定时器的功能强大,基本库和HAL的功能也基本相同,这也决定了stm32拥有非常广泛的用途。

同样,有很多大佬都已经总结过、整理过stm32的定时器了。这一期中,我就不在赘述其基本功能了,就结合cubemx和hal库,整理一下定时器中断、定时器生成PWM和编码器模式的函数使用。

STM32-定时器详解
STM32CubeMx配置定时器

定时器中断

在这里插入图片描述
定时器中断应该是最基本的操作了,我们勾选Internal Clock来选择时钟源。当然,每个时钟的内部时钟源的频率是有所不同的,请仔细查询资料或者手册,确定使用的时钟是APB1时钟源还是APB2时钟源。如图所示,我使用的F401RCT6的时钟4,其时钟频率是84MHz,当分频84倍后,其频率为1MHz,设置计数器为10,则这个时钟是10us的时钟中断,中断频率100KHz。
在这里插入图片描述
注意别忘了使能NVIC,将Enabled的选项打勾即可。接下来我们就要到程序中去写了。
在生成代码后,我们可以看见CubeMX已经帮我们把MX_TIM4_Init();放在了初始化中,但是此时定时器中断是不启动的,我们需要使能中断。

HAL_TIM_Base_Start_IT(&htim4);

当然这个中断是可以随时关闭的,我们可以通过调用下面的函数来关闭中断。

HAL_TIM_Base_Stop_IT(&htim4);

接下来,我们来写中断服务函数。首先我们要重写一下下面这个函数。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

这个函数原本已经是被弱定义过了,就是这个库其他地方需要用这个函数,但是函数内容又需要用户自己定义,这时候就会使用弱定义这种方式。如果你没有定义这个函数,编译器就会在使用时调用弱定义地方的函数。如果定义了,就会调用重新定义地方的函数。
使用结构一般如下:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(TIM4 == htim -> Instance)
	{
		HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
	}
	/*
	if(TIM? == htim -> Instance)
	{
		中断服务程序
	}
	*/
}

在这个函数中,只要定时器4发生中断,那么就会把LED的电平翻转一次。在HAL库中,我们不需要重置中断标志位,它会被自动置位,并且根据设定的时间精准地进入下一次中断。而且和标准库不同,它用一个函数处理了所有定时器中断。

生成PWM

CubeMX设置PWM输出
在这里插入图片描述
在这里插入图片描述
这个7200是为了凑stm32F103的72MHz的频率,具体情况可以更改

在系统自动生成的初始化后面加上PWM启动的代码。

	HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_2);
	HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_3);
	HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_4);

随后我们只需要调用下面的函数,就可以更改PWM的占空比了。

__HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_2, Compare);

其中Compare与计数器最大值的比值就是PWM的占空比。

编码器模式(Encoder Mode)

首先,我们设置一下编码器模式。如果不了解编码器的使用,可以参考以下的教程。
【平衡小车制作】(三)编码器讲解(超详解)
在这里插入图片描述
在分频器设置中我一般不分频,使其灵敏度最高。在计数器设置中一般设置高一点,有时过零点的检测会出些问题,我也会初始化将其值设置为一个中位数。Input Filter可以适当设置一点,可以保证采样的稳定性。
在这里插入图片描述
记得在自动生成的初始化后还要再加上以下的函数,编码器才会正式工作。

HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);

从上面可以看到我把这个计数器设置为65535,是16bit的最大计数器值。我们可以取其中位数,大概30000,进行预装填。

__HAL_TIM_SET_COUNTER(&htim2, 30000);

当我们转动编码器后时再去读取这个值,只需要调用:

EncoderNum = __HAL_TIM_GET_COUNTER(&htim2);

便可以读取当前的编码器值。

在小车应用中,可以将读取放在中断中,在每次读取后再重新复位30000,小车的速度就是读取的值与30000作差,可以做速度闭环。

CubeMX学习笔记总结

从2020年开始的这个系列,由于各种原因拖到了现在,而且匆匆结尾。在2020年的时候,关于CubeMX的教程在CSDN上还是比较少的,如今已是百花齐放。我也在2023年的春天把基本的功能总结完了,也为CubeMX的教程贡献出自己的想法。

由于当下科技发展太快,目前我也在努力学习,希望把考研和疫情浪费的时间尽快补回来,在做完2020年留下的任务之后,也要向前看,拥抱这个AI时代最前沿的技术。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值