こんにちは。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ピン配置図からPA8D9に接続していることが分かります。

 

 

 

  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波でサーボモータを動作させてみようかなと思っています。