こんにちは。Yukiです。
今回は、STM32F303K8(Nucleo-F303K8)でPWM出力してみたいと思います。
PWMが使えれば、いろいろ便利になりますからね。
PWMの概要
どのマイコンも同じような仕組みで動いています。
PWMモード1でTIMx_CNT > TIMx_CCPyレジスタになると、アクティブに
PWMモード2でTIMx_CNT < TIMx_CCPyレジスタになると、アクティブになります。
ということで、基本的にはPWM1モードで良いと思います。
なお、上の図はPWM1モードでの説明となります。
(実際には、カウンタが三角波のような波形になる動作方法もありますが、今回はシンプルにのこぎり波のような形で動作させています)
使用するポート確認
今回は、とりあえずPWMを使えれば良いので、PWM1_CH1を使おうと思います。
PWM1_CH1がどこに接続されているのか見るには、データシートを参照します。
(Nucleoのピン配置図にも記載されていますが、こちらは、一部のオルタネート機能が記載されていないため、データシートを見たほうが確実&有効活用できます)
STM32F303x6/x8 データシート(プロダクションシート) DS9866 Rev 8から参照・加工
今回PWM1_CH1はPA8に接続していることが分かります。またTIM1_CH1はAF8に属している事も分かります。(ここの数字などは、後で大切になってきます)
Mbed NUCLEO-F303K8から参照 (https://os.mbed.com/platforms/ST-Nucleo-F303K8/)
なお、上のNucleoピン配置図からPA8はD9に接続していることが分かります。
PWM出力を使うためのレジスタ操作
まずはTIM1のAPB2クロックを入力してあげます。(TIM1レジスタの有効化)
//TIM1クロック入力(有効)
RCC->APB2ENR |= (1 << 11);
次にPWM1_CH1をPWMモード1にします。
//PWMモード1
TIM1->CCMR1 &= (~(1 << 16));
TIM1->CCMR1 |= (1 << 6);
TIM1->CCMR1 |= (1 << 5);
TIM1->CCMR1 &= (~(1 << 4));
次に、CCRレジスタのプリロードを有効にします。
//CCRレジスタプリロード有効
TIM1->CCMR1 |= (1 << 3);
次に、TIM1のARRレジスタのバッファを有効にします。
//TIM1_ARRレジスタバッファ有効
TIM1->CR1 |= (1 << 7);
次にレジスタ更新を有効にします。
//レジスタ更新有効 (カウンタ初期化)
TIM1->EGR |= (1 << 0);
次に、PWMの出力を有効にします。
//出力有効
TIM1->CCER |= (1 << 0);
次に、ポートのメイン出力を有効にします。
//メイン出力有効
TIM1->BDTR = (1 << 15);
次に、PWMの設定をします。
初期時のDuty比を0にします。また今回は10bitPWMとします。
TIM1->CCR1 = 0; //CCRレジスタクリア
TIM1->ARR = 0x3FF; //10bit PWM
ここからは、ピンの設定をしていきます。
PA8をオルタネートモードに設定します。
//PA8 オルタネートモード
GPIOA->MODER |= (1 << 17);
GPIOA->MODER &= (~(1 << 16));
次に、PA8をAF6(TIM1_CH1)に接続します。
//PA8をAF6(TIM1_CH1)に接続
GPIOA->AFR[1] &= (~(1 << 3));
GPIOA->AFR[1] |= (1 << 2);
GPIOA->AFR[1] |= (1 << 1);
GPIOA->AFR[1] &= (~(1 << 0));
最後にTIM1のカウントを有効にします。
//TIM1 カウント有効
TIM1->CR1 |= (1 << 0);
PWMのDuty比はTIM1->CCRレジスタに入力することで、設定できます。
今回だと、10bitなので、0~1023の範囲で設定できます。
TIM1->CCR1 = 555; //例
配線
PWM(LED)はD9(PA8)に接続。
可変抵抗はA0(PA0)に接続しました。
結果
リセットしても正常に動作しました。
オシロスコープ画像です。
きれいなPWM波ですね。
次に動画です。
最初の動画が、LEDをボワーンとさせるやつですね。
For文で回しているだけです。
2番目の動画が可変抵抗でのLED調光ですね。
ちなみに、ソースコードは、2番目のやつです。
(動画編集適当ですが、ご了承ください)
余談
最近STM32マイコンを触るのが楽しくなってきました。
次は、PWM波でサーボモータを動作させてみようかなと思っています。