目录
一、硬件及工程
二、建立工程
三、代码修改
1、重定义回调函数
2、启动定时器中断
四、下载运行
一、硬件及工程
文章依赖的硬件及工程配置参考本文作者的其他文章:细说ARM MCU的串口接收数据的实现过程-CSDN博客 细说ARM MCU的串口接收数据的实现过程-CSDN博客文章浏览阅读1.2k次,点赞35次,收藏10次。重定义串口中断接收的回调函数HAL_UART_RxCpltCallback()。这个函数已经在stm32g4xx_ hal_uart.c中有定义,只不过被定义为弱函数,实际就是一个空函数。需要重写它。与写EXTI的回调函数类似,也将该函数写在main.c中。串口有数据送来,会执行中断服务函数USART2_IRQHandler(),然后该函数又会调用函数HAL_UART_IRQHandler()。https://wenchm.blog.csdn.net/article/details/139541112
STM32G474RET6的定时器
TIM3有4个通道,所以可配置4个PWM输出:TIM3_CH1、TIM3_CH2、TIM3_CH3和TIM3_CH4。由于STM32有引脚复用功能,信号具体从哪一个引脚输出,是需要配置的。不过,输出的引脚也不是任意的,需要选择特定的引脚。譬如TIM3_CH1这个PWM输出,STM32G474RE中,可通过PA6、PB4和PC6送出。其他通道也分别有对应的可选引脚。当然,对TIM3_CH1而言,虽然可由这三个引脚输出,但最终只能选择其中的一个。对TIM3的这4个PWM信号,选择输出引脚对应关系如下:
TIM3_CH1——PB4
TIM3_CH2——PB5
TIM3_CH3——PB0
TIM3_CH4——PB1
二、建立工程
通过PB4输出配置一个通道TIM3_CH1。同时也配置了TIM3的中断,并在中断时控制一个GPIO输出脉冲信号,该GPIO可选用PC3引脚。用示波器进行观察PC3和PB4引脚的输出信号波形。
将PC3配置为输出(GPIO_Output)。在NUCLEO-G474RE板上,PC3通过CN7端子的第37引脚引出。
在GPIO模式和配置界面中选中PC3,output level =High、GPIO mode=PP、Pull_up、High speed;
外部时钟、Serial Wire;
配置定时器:在TIM3的模式(Mode)配置界面,将时钟源设置为Internal Clock;选择PWM Generation CH1。然后,将预分频因子(Prescaler)和计数器周期(Counter Period)分别设置为999和8499(这两个参数从0开始计数),计数模式(Counter Mode)设置为升模式(Up),并使能自动重载(auto-reload preload)。
预分频因子决定着两次计数之间的时间间隔,这里设置的1000(999+1),是将时钟脉冲分频1000倍。假如时钟频率为170 MHz,则分频1000倍后就是170 kHz。
将计数周期设置为8499,也就是计数到8499后,重新从0开始计。在计数频率170 kHz之下,计数器的周期为(1/170×10³)×8500≈50(ms),对应的频率为20 Hz。在PWM Generation Channel 1的参数配置中,选择PWM mode 1,脉冲数(Pulse)设置为2125(该参数从1开始),通道极性设置为High。通道极性参数用于指定在Pulse个计数期间,输出的是高电平还是低电平。这里脉冲数Pulse决定着占空比,这里设为2125,是计数器周期的1/4,所以占空比刚好为25%。
使能TIM3的全局中断。将其抢占式优先级设为1,响应优先级设为0。将System tick timer的抢占式优先级设为最高(0级)。
将系统时钟(SYSCLK)频率配置为170 MHz。
三、代码修改
硬件配置完成后,编译、自动生成代码。
由于配置了TIM3中断,希望在中断发生后通过PC3引脚送出一个脉冲信号,因此,需要重定义TIM3中断的回调函数HAL_TIM_PeriodElapsedCallback()。
1、重定义回调函数
将回调函数的定义放到main.c后面的注释对中,实现代码如下:
/* USER CODE BEGIN 4 */
/* 定时器中断回调函数操纵GPIO PC3输出波形 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_3,GPIO_PIN_RESET);
HAL_Delay(12);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_3,GPIO_PIN_SET);
}
/* USER CODE END 4 */
2、启动定时器中断
在定时器中断的例子中通过.ioc文件配置了定时器中断,但在默认情况下并没有开启,所以需要在主程序的初始化代码部分调用库函数HAL_TIM_Base_Start_IT() 以启动定时器中断。
对定时器的PWM输出而言,配置完成之后,自动生成的代码就已经具备产生PWM信号的条件了,但还是要在初始化时使能PWM。为此,可以调用库函数HAL_TIM_PWM_Start()。该函数有两个参数,一个是指定定时器句柄,另一个是指定需要开启的PWM通道。
将上述两个库函数放到main函数中,位于while(1)前与TIM3初始化函数MX_TIM3_Init()之间的注释对中:
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
/* USER CODE END 2 */
四、下载运行
示波器的通道1是PC3输出的波形,该波形是PC3在TIM3中断的控制下产生的一个约12 ms的脉冲(低电平脉冲)。由于在前面配置GPIO参数时,将PC3配置为上拉,即通常情况下是高电平输出,并且在TIM3的中断回调函数中,先让PC3输出0,延时12 ms,随后又输出1,所以最终产生了此波形。
示波器的通道2是PB4 PWM的输出波形。这是一个正脉冲,高电平所占时间为12.5 ms,周期实际为50 ms,占空比为25%,与前面设置的参数保持一致。这里的PWM之所以是正脉冲,是因为前面配置PWM输出通道极性时选择了High,如果选择的是Low,则这个波形会刚好反过来,类似于通道1中的波形。