TIM2 のインプットキャプチャを使用してみます。 ここでは周期やパルスのLow時間の計測を行ってみます。 |
|
周期測定の場合、下図のようにTIM2_CH1の立下りでキャプチャすることで計測できます。 今回は波形ではなくキー入力とします。 |
1.1. TIM2の設定 TIM2 CH1を入力として設定します。入力がキーなので、Parameter Settings はわかりやすいように Prescalerを31999としてクロックを1msとします。 Polarity SelectionはをFalling Edgeに設定します。 割込みも有効にしておきます。 また、PA0はPullUpに設定しておきます。 |
|
1.2. コーディング HAL_TIM_IC_Start_IT関数でTIM2が起動します。割込みコールバック関数はHAL_TIM_IC_CaptureCallbackです。 /* USER CODE BEGIN PV */ volatile uint16_t g_usCC1 = 0; volatile uint16_t g_usCC2 = 0; volatile uint16_t g_usFlag = 0; /* USER CODE END PV */ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { g_usCC1 = g_usCC2; g_usCC2 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1); g_usFlag = 1; } /* USER CODE END PV */ g_usCC2は前回のCC1レジスタ値。 g_usFlagはg_usCC1、g_usCC2を更新したフラグ変数です。 /* USER CODE BEGIN 2 */ HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); /* USER CODE END 2 */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if (g_usFlag != 0) { g_usFlag = 0; sprintf(msg, "%05dms (%04X/%04X)\r", g_usCC2 - g_usCC1, g_usCC2, g_usCC1); UsartTransmitStrings(&huart2, msg); } } /* USER CODE END 3 */ |
|
Low時間測定の場合、下図のようにTIM2_CH1の立下りと立ち上がりでキャプチャすることで計測できます。 |
2.1. TIM2の設定 TIM2 CH2を入力として設定します。Channel2はInput Capture indirect modeに設定します。 Input Capture direct modeにするとPA1がTIM2_CH2として設定されてしまいます。 Input Capture Channel 2 の Polarity Selection は Rising Edge にします。 |
2.2. コーディング 割込み処理を以下の様に変更します。if ((*htim).Channel == HAL_TIM_ACTIVE_CHANNEL_1) { g_usCC1 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1); } if ((*htim).Channel == HAL_TIM_ACTIVE_CHANNEL_2) { g_usCC2 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_2); g_usFlag = 1; } g_usCC2は最新のCC2レジスタ値。 g_usFlagはg_usCC2を更新したフラグ変数です。 Low時間はg_usCC1とg_usCC2の差で求まります。 /* USER CODE BEGIN 2 */ HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); /* USER CODE END 2 */ |
|
次に割込みからDMAに変更します。 |
2.1. TIM2の設定 DMAを設定します。TIM2_CH1とTIM2_CH2を設定し、ModeをCircular、Increment Addressはチェックを外します。 TIM2割込みはチェックを外します。 |
3.2. コーディング 割込み処理を以下の様に変更します。/* USER CODE BEGIN 0 */ void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim) { if ((*htim).Channel == HAL_TIM_ACTIVE_CHANNEL_2) g_usFlag = 1; } /* USER CODE END 0 */ 引数TIM_HandleTypeDef *htimでDMA転送終了Channelを判別できます。 今回はCC2のDMA転送終了で処理します。 /* USER CODE BEGIN 2 */ HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_1, (uint32_t *)&g_usCC1, 1); HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, (uint32_t *)&g_usCC2, 1); /* USER CODE END 2 */ CH1はg_usCC1、CH2はg_usCC2にDMA転送するよう指定します。 以下は今回の回路図です。 |