---
# System prepended metadata

title: STM的PWM輸入捕獲
tags: [STM32]

---

[TOC]

# PWM輸入捕獲
- 閱讀前請先了解timer的捕獲模式
- 一般的輸入捕獲可以在腳位電平變化時紀錄timer當下的counter值。如果是一個PWM輸入，則可以用軟體方式判斷每次腳位電平變化時間，計算出PWM週期與佔空比
- STMF407也有一個專門的<font color="red">PWM輸入捕獲</font>模式(捕獲模式的特例)，透過晶片內部電路直接算出PWM週期與佔空比，不過就需要占用兩個捕獲暫存器
- [推薦網站1](https://blog.csdn.net/weixin_44793491/article/details/126852975)

# PWM輸入捕獲模式
- 外部輸入接腳雖然只有一個(圖中TI1)，但是PWM訊號會進到兩個捕獲通道(圖中IC1、IC2)
![image](https://hackmd.io/_uploads/HytGvegryl.png =40%x)
- 進入兩捕獲通道的信號分別在對應的捕獲暫存器紀錄PWM週期或占空比
- 作為input trigger的線路就對應儲存PWM週期，另一路為占空比
- <font color="red">注意捕獲暫存器紀錄的值要加 1 才是正確週期和占空比</font>
- 時序
    ![image](https://hackmd.io/_uploads/ryoEfp1Bkg.png =80%x)

# CubeMX
- 選擇combined channel的 PWM input on Chx
- 使用timer3 (APB1, 84MHz)，設置預除器和週期暫存器使timer頻率只有100Hz
- reset mode使得每次PWM週期開始時，counter會自動歸0
- 當counter值被存到捕獲暫存器時會發生捕獲中斷，有需要的話記得啟用捕獲的NVIC設定
- ![image](https://hackmd.io/_uploads/rkFz56JSkg.png)



# 相關函式
- 以下函式皆在 stm32f4xx_hal_tim.c中 
## Init(初始設定)
- Initialize相關的函式，CubeMX會生成，這裡不紀錄
## Activate(啟用)
- HAL_TIM_IC_Start()
- HAL_TIM_IC_Start_DMA()
- HAL_TIM_IC_Start_IT()
## Read
- HAL_TIM_ReadCapturedValue()
## Callback(中斷回調)
- HAL_TIM_IC_CaptureCallback()
- HAL_TIM_IC_CaptureHalfCpltCallback()



# 程式範例(使用捕獲中斷)
- 在 USER CODE BEGIN 2 啟用捕獲與捕獲中斷，注意PWM輸入雖然只有一個接腳但其實是兩個捕獲通道
``` c++=
/* USER CODE BEGIN 2 */
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);
```
- 在USER CODE BEGIN 4添加callback function，取得捕獲暫存器的值
``` c++=
uint32_t IC_Val1 = 0, IC_Val2 = 0;

/* USER CODE BEGIN 4 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{

  if (htim == &htim3)
  {
    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
      IC_Val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
    else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
      IC_Val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
  }

}
```
