上一篇学习了“ITM机制输出调试信息”,这一篇学习STM32的输入捕获。
Step1.打开 STM32CubeMX,点击“New Project”,选择芯片型号,STM32F412ZGx。
Step2. 配置时钟树
Setp3.配置 tiM2 使用内部时钟源,CH1 作为输入捕获通道,默认映射到 PA0 引脚。
配置 TIM3 使用内部时钟,CH1~CH4 为 PWM 输出通道,默认映射引脚分别为 PA6,PA7,PB0,
PB1。
配置 TIM4 使用内部时钟,CH1,CH2 为 PWM 输出通道,映射引脚分别为 PD12,PD13。
配置PB3引脚为SWO,作为信息输出接口。
Step4.配置外设参数。
在 configuration 界面中点击 TIM2/ TIM3/ TIM4 按钮,可以迚入参数配置界面。
TIM2:在 Parameter Settings 页配置预分频系数为 9,其计数时钟就是 100MHz/(9+1)=10MHz。
计数周期(自动加载值),转换为十六迚制形式,输入 32bit 最大值 0xFFFFFFFF。
注意,TIM2 的自动加载寄存器 ARR 和各个通道的捕获/比较寄存器 CCRx 都是 32bit 的。
在 NVIC 页面使能捕获/比较中断。
在 GPIO 页面设置捕获输入引脚下拉电阻,设置成上拉也可以,主要是为了使在没有信号输入时在输
入引脚上得到稳定的电平。
TIM3:在 Parameter 页配置预分频系数为 9,计数周期(自动加载值)为 9999。其溢出频率就是
100MHz/(9+1)/(9999+1)=1kHz,这就是 TIM3 各通道输出的 PWM 信号的频率。
各通道输出 PWM 的占空比参数如上图红框标注,其他参数使用默认值。按照图中参数,CH1~CH4
输出的 PWM 周期都是 1ms,而高电平时间分别是 123.4us,234.5us,567.8us,678.9us。
在 GPIO 页面配置相关引脚的特性。
TIM4:在 Parameter 页配置预分频系数为 9,计数周期(自动加载值)为 999。其溢出频率就是
100MHz/(9+1)/(999+1)=10kHz,这就是 TIM4 各通道输出的 PWM 信号的频率。
各通道输出 PWM 的占空比参数如上图红框标注,其他参数使用默认值。CH1,CH2 输出的 PWM 周
期都是 100us,而高电平时间分别是 23.4us,56.7us。
在 GPIO 页面配置相关引脚的特性。
Step5.生成源代码。
点击生成源代码按钮。
Step6. 打开项目,配置调试信息,参考上篇 “ITM机制输出调试信息”
Step7.添加功能代码。
先在 main.c 文件用户代码区输入包含标准输入输出头文件。在主凼数前面的用户代码区 0,定义一些全局变量。
- /* USER CODE BEGIN Includes */
- #include
- /* USER CODE END Includes */
- /* Private variables ---------------------------------------------------------*/
- /* USER CODE BEGIN PV */
- /* Private variables ---------------------------------------------------------*/
- uint32_t capture_buf[3]={0};
- uint8_t capture_cnt =0;
- uint32_t pwm_cycle,high_time;
- uint64_t duty;
- /* USER CODE END PV */
复制代码
在 while(1)之前的用户代码区 2,使能 TIM3、TIM4 的各个通道 PWM 输出。
- /* USER CODE BEGIN 2 */
- 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);
- /* USER CODE END 2 */
复制代码
在 while(1)中的用户代码区 3,写入 TIM2 CH1 通道的输入捕获控制和数据处理。
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- switch(capture_cnt)
- {
- case 0:
- capture_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 = capture_buf[2] - capture_buf[0];
- printf("Cycle:%.4fmsrn",pwm_cycle/10000.0f);
-
- high_time = capture_buf[1] - capture_buf[0];
- printf("High:%.4fmsrn",high_time/10000.0f);
-
- duty = high_time;
- duty *= 1000;
- duty /= pwm_cycle;
- printf("Duty:%.1f%%rn",duty/10.0f);
-
- HAL_Delay(1000);
- capture_cnt = 0;
- break;
-
- }
- }
- /* USER CODE END 3 */
复制代码
在 main 文件的用户代码区 4,写入 TIM2 输入捕获中断处理回调凼数。
- /* USER CODE BEGIN 4 */
- void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
- {
- if(TIM2 == htim->Instance)
- {
- if(HAL_TIM_ACTIVE_CHANNEL_1 == htim->Channel)
- {
- switch(capture_cnt)
- {
- case 1:
- capture_buf[0] = __HAL_TIM_GetCompare(htim,TIM_CHANNEL_1);
- __HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);
- capture_cnt++;
- break;
- case 2:
- capture_buf[1] = __HAL_TIM_GetCompare(htim,TIM_CHANNEL_1);
- __HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);
- capture_cnt++;
- break;
- case 3:
- capture_buf[2] = __HAL_TIM_GetCompare(htim,TIM_CHANNEL_1);
- HAL_TIM_IC_Stop_IT(htim,TIM_CHANNEL_1);
- capture_cnt++;
- break;
- default:
- break;
- }
- }
- }
- }
- /* USER CODE END 4 */
复制代码
至此,工程完成。功能是使用 TIM 的输入捕获功能,实现对 PWM 信号的周期和占空比测量,并将
数据通过串口发送出去。用杜邦线将 PA0 和其他 PWM 信号输出脚相连,即可测量信号的周期,高
电平所占时间,以及占空比,在DebugViewer 会输出这些信息。输出信息示例如下
按 照 本 例 的 配 置 , 测 量 精 度 是 0.1us , 测 量 信 号 周 期 范 围 是 0~0xFFFFFFFF*0.1us , 即
0~429.4967295 秒
测量基本思路是:
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]就是高电
平所占时间。
|