【STM32CUBEMX+PWM+UART】
1.案例应用
? 本案例为使用STM32CUBEMX配置TIM2生成PWM捕获信号,并对TIM3,TIM4(也可捕获其它设备输出)输出的PWM波进行捕获(本例捕获上升沿,极性可以自己设置),最后求取并串口打印TIM3,TIM4输出PWM的周期、占空比以及1个周期内高电平的持续时间。
2.工具
-
STM32CUBEMX
-
IAR
-
STM32F411VET6
3.PWM实验
3.1.1 STM32CUBEMX 工程配置
-
打开 STM32CubeMX,点击“New Project”,选择芯片型号,STM32F411VETx
-
RCC、SYS配置
? ——>这里如下图所示配置,不懂的可以百度
-
TIM2配置 ,使用内部时钟源,CH1 作为输入捕获通道,默认映射到 PA0 引脚 ,如下图所示
? ——>在 Parameter Settings 页配置预分频系数为 7,其计数时钟就是 80MHz/(7+1)=10MHz(时钟树配置后边说),计数周期(自动加载值),转换为十六进制形式(也可十进制),输入 32bit 最大值 0xFFFFFFFF。
——>设置通道1的捕获极性,初始设置为上升沿(也可以修改,根据实际需求)
? ——>在 NVIC页面使能捕获/比较中断
? ——>在 GPIO 页面设置捕获输入引脚下拉电阻,设置成上拉也可以,主要是为了使在没有信号输入时在输 入引脚上得到稳定的电平
-
TIM3配置, 使用内部时钟,CH1~CH4 为 PWM 输出通道,默认映射引脚分别为 PA6,PA7,PB0, PB1
? ——>在 Parameter 页配置预分频系数为 7,计数周期(自动加载值)为 9999。其溢出频率就是 80MHz/(7+1)/(9999+1)=1kHz(即 周期,1ms ),这就是 TIM3 各通道输出的 PWM 信号的频率,配置各通道输出极性以及脉宽,将通道1,通道2,通道3,通道4 分别设为1234, 2345,5678, 6789,即1个周期内高电平时长0.1234ms,0.2345ms,0.5678ms, 0.6789ms,2, 3 ,4通道设置方法同通道1。其他参数使用默认值
? ——>在 GPIO 页面配置相关引脚的特性,PA6,PA7,PB0, PB1设置相同
-
TIM4 配置 ,使用内部时钟,CH1,CH2 为 PWM 输出通道,映射引脚分别为 PD12,PD13
? ——>在 Parameter 页配置预分频系数为 7,计数周期(自动加载值)为 999。其溢出频率就是 80MHz/(7+1)/(999+1)=10kHz(即 周期,0.1ms ),配置各通道输出极性以及脉宽,将通道1,通道2 分别设为234, 567,即1个周期内高电平时长0.0234ms,0.05678ms, 2通道设置方法同通道1。其他参数使用默认值
? ——>在 GPIO 页面配置相关引脚的特性,PD12,PD13设置方法同PA6,PA7,PB0, PB1 -
(UART2)串口配置,打印输出信息
-
时钟树配置,在 Clock Configuration 界面配置时钟源,使用外部 8M 晶振作 PLL 时钟输入,并使用 PLL 输出作为系统时钟80MHz
-
配置工程文件名、路径、ToolChain/IDE——>GENERATE CODE ,完成之后打开项目。
3.1.2 代码编写
——>定义printf函数,具体操作见STM32CUBEMX+UART串口调试,循环接受发送数据
——>main.c
#include "main.h" #include "tim.h" #include "usart.h" #include "gpio.h" #include "stdio.h" #include <stdio.h>void SystemClock_Config(void);uint32_t campture_buf[3] = { 0};//存放捕获的数据 uint8_t campture_cnt = { 0}; uint32_t pwm_cycle, high_time; uint64_t duty; int main(void) { HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_TIM2_Init();MX_TIM3_Init();MX_TIM4_Init();MX_USART2_UART_Init();//使能 TIM3、TIM4 的各个通道 PWM 输出HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);while (1){ switch( campture_cnt){ case 0 :campture_cnt ++;__HAL_TIM_SET_CAPTUREPOLARITY(&htim2 , TIM_CHANNEL_1 , TIM_INPUTCHANNELPOLARITY_RISING);//设置捕获极性为上升沿HAL_TIM_IC_Start_IT(&htim2 , TIM_CHANNEL_1);//开启定时器输入捕获中断,跳转break;case 4 :pwm_cycle = campture_buf[2] - campture_buf[0];printf("cycle: %.4fms\r\n ", pwm_cycle/10000.0);high_time = campture_buf[1] - campture_buf[0];printf("High: %.4fms\r\n ", high_time/10000.0);duty = high_time;duty *= 1000;duty /= pwm_cycle;printf("Duty: %.1f%%\r\n ", duty/10.0);HAL_Delay(1000);campture_cnt = 0;break;}}} // TIM2 输入捕获中断处理回调凼数 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(TIM2 == htim ->Instance){ if(HAL_TIM_ACTIVE_CHANNEL_1 == htim ->Channel){ switch(campture_cnt){ case 1:campture_buf[0] = __HAL_TIM_GET_COMPARE(htim, TIM_CHANNEL_1);__HAL_TIM_SET_CAPTUREPOLARITY(htim , TIM_CHANNEL_1 , TIM_INPUTCHANNELPOLARITY_FALLING);//捕获下降沿campture_cnt ++;break;case 2:campture_buf[1] = __HAL_TIM_GET_COMPARE(htim, TIM_CHANNEL_1);__HAL_TIM_SET_CAPTUREPOLARITY(htim , TIM_CHANNEL_1 , TIM_INPUTCHANNELPOLARITY_RISING);//捕获上升沿campture_cnt ++;break;case 3:campture_buf[2] = __HAL_TIM_GET_COMPARE(htim, TIM_CHANNEL_1);HAL_TIM_IC_Stop_IT(htim, TIM_CHANNEL_1);//停止捕获campture_cnt ++;break;default:break;}}}}
个人浅见,如有问题欢迎大家留言讨论
上文中,当函数之行到 HAL_TIM_IC_Start_IT(&htim2 , TIM_CHANNEL_1);时,开启定时器捕获中断,此时,整个代码执行的流程为:
startup_stm32f411xe.s——> >TIM2_IRQHandler()——>HAL_TIM_IRQHandler()——>HAL_TIM_IC_CaptureCallback();执行完之后在跳回到 HAL_TIM_IC_Start_IT(&htim2 , TIM_CHANNEL_1);处,执行break;——>while()此时campture_cnt = 4 ——>case4:
? 测量思路:
1.设置 TIM2 CH1 为输入捕获功能;
2.设置上升沿捕获;
3.使能 TIM2 CH1 捕获功能;
4.捕获到上升沿后,存入 capture_buf[0],改为捕获下降沿;
5.捕获到下降沿后,存入 capture_buf[1],改为捕获上升沿;
6.捕获到上升沿后,存入 capture_buf[2],关闭 TIM2 CH1 捕获功能;
7.计算:capture_buf[2] - capture_buf[0]就是周期,capture_buf[1] - capture_buf[0]就是高电 平所占时间。
——>编译下载。用杜邦线将 PA0 和其他 PWM 信号输出脚(PD12,PD13,PA6,PA7,PB0, PB1任选其1)相连,即可测量信号的周期,高 电平所占时间,以及占空比,在串口 2会输出如下信息:
具体工程案例见:PWM_Capture.rar