基本的な TIM6 を試します。
One Pulse Mode 1回きり
ioc設定
Activated チェック
One Pulse Mode チェック
1周期 1秒にしてみます。クロックが 8MHz なので,プリスケールをまずは 8,000 そうすれば 1msec おきにカウンターが変わるはずです。
Counter Period 1000 = 8MHz / 8,000
auto-reload preload を Enable にします。
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim6);
uint32_t t0=TIM6->CNT;
HAL_Delay(100);
uint32_t t1=TIM6->CNT;
HAL_Delay(100);
uint32_t t2=TIM6->CNT;
/* USER CODE END 2 */
HAL_Delay(100);
で 100msecごとにカウンター値 CNT
を変数に保存しています。
再スタートする
停止したあと CEN フラグをセットします。CR1 レジスタの最初のビットです。
TIM6->CR1 = ( TIM6->CR1 ) | 1; // set CEN means restart
停止したことを知る
SRレジスタにある UIF フラグがセットされるのですが,普通に HAL でスタートさせるとセットした状態になるようです。あらかじめリセットしておきます。
/* USER CODE BEGIN 2 */
TIM6->SR = (TIM6->SR) & 0xfffffffe; // clear UIF
HAL_TIM_Base_Start(&htim6);
HAL_Delay(100);
uint32_t f0=(TIM6->SR) & 1; // UIF
HAL_Delay(1000); // TIM6 finished.
uint32_t f1=(TIM6->SR) & 1; // UIF
TIM6->CR1 = ( TIM6->CR1 ) | 1; // set CEN means restart
HAL_Delay(200);
uint32_t f2=(TIM6->SR) & 1; // UIF
/* USER CODE END 2 */
2回目はUIFをリセットせずスタートしたので,セットした状態になってますね。
繰り返すモード (One Pulse Mode = OFF)
/* USER CODE BEGIN 2 */
TIM6->SR = (TIM6->SR) & 0xfffffffe; // clear UIF
HAL_TIM_Base_Start(&htim6);
HAL_Delay(100);
uint32_t f0=(TIM6->SR) & 1; // UIF
uint32_t c0=TIM6->CNT;
HAL_Delay(1000); // TIM6 finished.
HAL_Delay(50);
uint32_t f1=(TIM6->SR) & 1; // UIF
uint32_t c1=TIM6->CNT;
/* USER CODE END 2 */
今度は自動でリスタートしていますね。2回目のCNT ≒ 150 ( = 100 + 1000 + 50 - 1000 )
UIFを予めクリアしておかないといけないのは One Pulse Mode と同じでした。
タイマー割り込みを併用する
こちらの記事と同じですね。ありがとうございます。
ioc TIM6 は DACのトリガーにもなれますので少し文言が違いますね。
定番のLチカですね。
/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim == &htim6) {
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim6);
/* USER CODE END 2 */
あっけないほど簡単です。
デバッガで止めてみると... 割り込みハンドラが呼ばれているときに UIF がクリアされているようです。
周期を変える
ARRレジスタを変更します。動いているときに強制的に変えていいかどうか RM0316 にはズバリ書いていないようですが,とにかく動いています。LEDのチカチカが速くなります。
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim6);
HAL_Delay(2000);
TIM6->ARR = 200; // Auto reload = 200;
/* USER CODE END 2 */