搭建了基础的环境,配置了一个简单的工程后,CubeMx的基本操作就会了。然后基于这个操作往下推进,开始对关键模块定时器的攻略,这个部分需要先熟悉一下Stm32的定时器基本原理。
《STM32参考手册》中仅对定时器的介绍就已经占了100多页,这里就不一一展开,挑一些关键的理解一下。
STM32一共有8个都为16位的定时器。其中TIM6、TIM7是基本定时器﹔TIM2、TIM3、TIM4、TIM5是通用定时器﹔TIM1和TIM8是高级定时器。这些定时器使STM32具有定时、信号的频率测量、信号的PWM测量、PWM输出、三相6步电机控制及编码器接口等功能,都是专门为电机控制领域量身定做的。
先说说基本定时器,特点:
- 时钟源都是TIMxCLK,时钟经过PSC预分频输入至脉冲计数器TIMx_CNT
- 只能够向上计数,只有向上计数模式
- 工作的计数器TIMx_CNT直接由时钟触发,当TIMx_CNT的值等于重载寄存器TIMx_ARR中的值N时,产生溢出事件,可触发中断,或DMA请求,CNT的值重置为0,重新开始计数。
再看看通用定时器,特点:
- 具备基础的定时功能外,还具备输入脉冲频率检测,输出PWM的功能
- 具备编码器接口
- 溢出时触发中断或DMA
- 相对基本定时器具备脉冲捕获/比较寄存器,能够用于捕获外部输入的脉冲数量和脉宽
试试通用定时器的触发中断的功能。
第一步:选择时钟源,配置如下图所示,选择内部时钟。设置分频系数与触发中断计数器,在下图的PSC和Counter Period设置。
第二步:撰写打开定时器中断的代码, 生成代码后,需要一个关键步骤,就是在用户代码编辑区域,打开定时器TIM3的使能。如下图所示,可以看到User code begin2 的字样,这里就是经过CubeMx生成代码之后,用户编程序的地方。
HAL_TIM_Base_Start_IT(&htim3);
然后在中断程序中输入我们需要执行的操作,中断程序在哪里呢?
第三步:增加执行函数。在下图函数的这个里面,因为CubeMX在配置了中断之后,就会自动生成专门的中断.c文件,这里TIM3_IRQHandler就是TIM3的中断执行函数,在其中加入我们个人需要执行的代码。
然后电机debug运行,得到如下结果,累加时间与分频时间相同。
再试试中断生成一路PWM的功能
第一步:配置GPIO
第二步:配置初始电平。如下图配置PA4的输出为输出模式, 并且设置初始输出电平为高电平。
第三步:配置中断执行函数,执行输出电平的翻转,生成占空比为50%的PWM。
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
g_main_count ++;
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_4);
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
/* USER CODE END TIM3_IRQn 1 */
}
输出结果,输出周期为42ms。由于此时我的定时器时钟为18M,分频系数为18,counter period为20000,经过18分频后,定时器时钟为1M,电平反转周期等于 20000/1000000 = 1/50 = 0.02s,约为20ms,单个电平持续时间为20ms,两个电平则为40ms左右,因此基本符合。这里也有个问题就是为什么不是精确的20ms,而是21ms。