HOME >> 鉄道模型実験室 > Arduino Nano Every のPWMキャリア周波数を20kHzにする

鉄道模型実験室 No.158  Arduino Nano Every のPWMキャリア周波数を20kHzにする

 20kHz化の方法について、先回に引き続き調べてみると色々な事が分かりましたので、今度は2020/4/3のブログ「ArduinoのPWMキャリア周波数を20KHzにする」の説明を補足します。

 

■ Arduino Nano Every におけるPWMキャリヤ周波数のアップの挑戦

  .

 まず、最初に取り組んだの「Arduino Nano Every のPWM周波数をアップする」(2020/3/3)でした。 ここでは、プリスケーラの設定倍率を指定することにしました。

      TCA0.SINGLE.CTRLA = 0b0101 ;

 ENABLE指定ビットは常に1に設定します。 この一行だけの命令追加で、キャリア周波数は 15.7kHz までアップさせることが出来ました。

   *****************************************************

 

 その後、上記のブログのように、DEKOさんのアヤシいお部屋の「Arduino Nano Every」の記事のごとく、20MHzに設定できるメニューを追加してテストを実施しました。 Nano Every で使用しているCPUは Uno と違って、ATMega4809を使用しているのでクロックスピードがもともと20MHzもあり、Nanoとの互換性のために、16MHzに落として使用しているとの事。 それでは、もとに戻してやれば、16MHz ⇒ 20MHzなので、16KHz ⇒ 20KHzになると考えたからです。

 この時に観測したオシロ波形は次のようでした。

キャリア周波数は 19.5KHz となり、狙いどうりです。

立ち上げリタイミングはピタリと一致しています。

CH1はD9ポート、CH2はD10ポートです。 CH1はD10ポート、CH2はD6ポートです。  

キャリア周波数は 19.5KHz となり、狙いどうりです。

立ち上げリタイミングはピタリと一致しています。

CH1はD10ポート、CH2はD5ポートです。 CH1はD5ポート、CH2はD3ポートです。  

 

■ 色々な疑問

 上記の方法によれば、Arduino Nano Every のPWMキャリア周波数を 約20kHz にする事ができたのですが、何故なぜの疑問が残っています。

  1. たった一行だけの命令で、TCA0.SINGLE.CTRLA = 0b0101 5個のポートの周波数を変えられるのか?
  2. そのタイミングもピタリと一致しているのは何故か? Uno の場合はタイミングがずれているのに・・・・・・・!
  3. この命令の書き方は他の場合と異なっているので、何を意味しているのだろうか? 特に、SINGLE と言う命令は何を意味するのか?
  4. クロック周波数を変更するメニューの意味は?

などですが、皆さんは何が気になりますか?

 

● クロック周波数を変更するメニューの意味は?

 まず最初に、4番目の疑問からですが、記述しているの内容が bootloaderbuild.f_cpu などの単語が出てきますので、諦めるることにしました。 自分の技量では理解できる範疇では無いことが明らかです。 ここでは、そっくりそのまま活用さて頂くことにします。

 

● Arduino Nano Every のPWM制御の関係レジスタ

 ATMega4809 のデータシートをもとに、 先回の Uno の場合と同様なブロック図を作成してみました。

 すると、Uno の ATmega328P とは基本は同じであるものの、様子が異なっている事が分かります。 16ビットタイマーひとつで、6個のポートから出力している事が分かります。

Arduino のモデル CPUモデル タイマーの数 タイマーの種類 各タイマーの出力チャネル数
Uno
ATmega328P
8ビットタイマー×2、16ビットタイマー1個
Nani Every
ATmega4809
16ビットタイマー2個

 ただし、ATmega4809 には、タイマーの使い方として、Normal ModeSplit Mode の二つの使い方が可能となっています。 この Split Mode は、16ビットタイマーを上位ビットと下位のビットに分け、それぞれ二つの8ビットタイマーとして使用出来るモードです。 このNani Every はまさにこのモードを使用して、一つのタイマーから6個のポートに出力しているのです。 その様子を示したので上記のイラストです。

 Nano Every でのデフォルトの設定はどうなっているのか、とあちこちを探しましたが見つけることが出来ませんでした。 データシートによると CTRLD レジスタの SPLITM ビットをHIGHにすると Split Mode になるようですが、どこで設定しているのか分かりませんでした。 このため、ここは状況から推定しています。

 

 同じタイマーを上下に分けたとしても、作動クロックなどは同じですから、6個のポートのPWM波形のタイミングが揃っているのは納得できますね。 疑問2は納得ですが、ポート数が6個? 実際は5個しか無いのに?

 

 そこで、CPUのポートとEveryのポートのつながりを追っていきますと、 WO3 のポートが切れていました。 Every では使用していなかったのです。 これも納得です。

 また、タイマーの波形には、Fast PWM ( Single-slope PWM )や Phase-Correct PWM ( Dual-slope PWM )などあるのですが、ここでは、Fast PWM を使用しています。

 

● たった一行の命令だけで?

 各レジスタの設定については、それぞれ必要なのですが、タイマーの数が少ない事と、上位の Split Mode を選択すると制約されるため、Uno の場合のような面倒さはありません。

   分周比を64から4に変更するだけで、16倍も速くすることが出来てしまいました。

 この分周比の変更だけで充分だったのです。 後は、CPU自身のクロックを元々の 20MHz にアップすれば、約20kHz のキャリヤ周波数が得られるのです。

 

この命令の書式は?

 当初は、分周比の設定を変えれば良いと思って、ビットごとの設定命令である cbi( ) や sbi( ) を使って記述しましたがエラーとなってコンパイル出来ませんでした。 そこで、サンプルで記述されていた方法を使うとコンパイル可能で、かつ、実際のPWM周波数も変更できていたので、このサンプルの記述方法が正しい事を確認しました。

 でも、どうしてなの? の疑問のままでしたが、データシート内で TCA0.SINGLE.CTRLA の用語の検索を掛けると 22ページにその用語が引っかかりました。 そこには、異なるモードで異なるレジスタセットを持つ場合は、機器名の後にモード名を記述せよとの説明がありました。

  タイマー名 ピリオド モード名 ピリオド レジスタ名 即ち  TCA0.SINGLE.CTRLA = 0b0101 と記述することになります。

 

 すると、モード名が違うのでは? との疑問が沸きます。 SINGLE とは、Single-slope PWM と Dual-slope PWM のことか、あるいは Normal Mode と Split Mode のことなのな分かりませんが、レジスタ CTRLA の分周比の指定方法は、どちらのモードでも同じだったので、どちらでもよかったようです。

 なお、別の参考資料( AVR日本語情報サイトのTB3217 )では、例題に示された記述れいでは、TCA0.SINGLE.CTRLA と TCA0.SPLIT.CTRLD を使用していますので、Normal Mode と Split Mode の意味のようですが、よく分かりません。

 これで、疑問3が一応分かったことにしておきましょう。

 

■ まとめ

 Arduino Nano Every でも 簡単に約20kHz のPWM波形を出力させる事が出来ました。 しかし、今から振り返ってみると、非常にラッキーな選択でした。

 まず最初に、小型のArduino として Nano Every を選択したことにあります。 単に、小型で最新型の機種であるとの単純な考えで選択したのでしたが、大正解でした。 そして、たった一行の命令を試しただけで目的を達成したのも、偶然のような気がします。

 要するに、素人が何も分からずに、あれこれ触っていた時の偶然のご褒美と考える事にします。 そして、何故なぜの追及心が必要であることも改めて感じました。 皆さんの参考になれば幸いです。

 

ページトップへ戻る  .


 2020/4/6 作成