鳥なき里のマイコン屋(101) GD32VF103、タイマ PWM出力

Joseph Halfmoon

RISC-V搭載の「お求めやすい」マイコン、GigaDevice社GD32VF103の機能を一通り触ってみるべく「活動」しておりますが、まだまだ題材は尽きる気配はありません。今回は、ありがちな、タイマをつかったPWM出力をやってみたいと思います。使用する開発ボードは、久しぶり、Sipeed社のLongan nanoであります。

さてGD32VF103は、周辺回路として7個のタイマを搭載しています。この数の中にはウオッチドッグタイマとか、実時間タイマ(RTC)など特定用途向けのタイマは含まれません。プログラムで普通にタイマとして使えるタイマの数です。さらに言えば、タイマ0番から4番までの5本のタイマは、それぞれ4CHをその内部に含んでいるので、機能的には20+2本で22本といってもあながち間違いではありません。まとめるとこんな感じです

  1. タイマ0 Advanced timer (内部に4チャネル)
  2. タイマ1,2,3,4 General level0 timer (それぞれ内部に4チャネル)
  3. タイマ5,6 Basic timer

ザックリ言ってしまうと、タイマ0がこのチップ上は最強にいろいろできるタイマで、タイマ1,2,3,4はそのお手軽バージョン(タイマ0の一部割愛版)です。タイマ0から4までは、内部にコンペア、キャプチャのための4チャネルをもち、それぞれのチャネルでIOが可能なタイマです。これに対してBasic timerと呼ばれている5番と6番は、入出力用ではなく、内部の「タイミング」を生成するため、例えば、DMAの周期とか割り込み周期とか、「昔ながらの」タイマの仕事を行うためのものです。

基本、すべてのタイマは16ビット幅のカウンタと、16ビット幅のプリスケーラ(もちろんプログラマブル)を持っています。一番ゴージャスなタイマ0にいたっては、配下?のタイマ1、2、3、4をプリスケーラとして接続するようなモードも持っています。

タイマ0,1,2,3,4については以下のような、近代的な(いつの時代からだ)マイコンには必須の入出力機能が備わっています。

  • インプットキャプチャ
  • アウトプットコンペア
  • PWM出力

また、モーター制御のため

  • Quadrature decoder
  • Hall sensor function

も備えています。

今回、まずは

TIMER 3 の CH0からCH3までをつかったPWM出力

をやってみます。タイマは4本あるのですが、REMAPしないデフォルト状態では、多くの入出力信号端子はポートAとポートBに集中しています。このため、Longan nanoのような48ピンパッケージ版でもタイマの端子にはあまり不自由はしません。このところ100ピン版のSeeed Studio版の開発ボードばかり使ってきましたが、今回、久しぶりにLongan nanoに戻ってきました。TIMER 3 にしたのは、Longan nanoのUSBを下にしておいた時の右肩のGND端子の横に

GND, GND, PB9, PB8, PB7, PB6

と言う具合にTIMER 3 のCH3, CH2, CH1, CH0出力が並ぶので、出力信号を「観察しやすい」というだけの理由です。

まずは、例によって、周辺回路の初期化。ポートBへのクロック供給(最初、PWM出力が出なくてさんざん、タイマ回りを見直しましたが、忘れていたのはこれでした)から始まり、Alternate Function(タイマはオルタネートなんだそうな)、タイマ端子の初期化です。

rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_AF);
// initialize GPIO
// PB6  ... TIMER3 CH0
// PB7  ... TIMER3 CH1
// PB8  ... TIMER3 CH2
// PB9  ... TIMER3 CH3
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6); // TIMER3 CH0
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7); // TIMER3 CH1
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); // TIMER3 CH2
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); // TIMER3 CH3

続いて、タイマ内部の設定ですが、この関数は、SDKの中のPWMのExampleをTIMER3用にして、さらに4CH全てを使うように設定しただけのものなので、先頭のみで以下省略させていただきます。

void timer_config(void)
{
    timer_oc_parameter_struct timer_ocinitpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER3);
    timer_deinit(TIMER3);
~以下略~

ちゃんとPWM出力でているのか、確認するために、いつもお世話になっている

Digilent社Analog Discorery 2

を使用させていただきました。CH1, 2の波形みるとこんな感じ。OKかな。

 

 

なお、「ゆっくり」観察できるように周期は160msくらいになるように設定してあります(Example設定値の10倍)。

Analog Discovery 2のオシロは2CHなので、4CHある全信号を同時に見ることはできません。しかし、Analog Discovery 2は優れものです。Analogといいながら、

Logic Analyzer(的な)

機能を含んでいます。そのときの接続がこちら。

これでRUNすれば、アイキャッチ画像のようなPWM波形の出来上がり。

まっことありがち

鳥なき里のマイコン屋(100) GD32VF103、Standbyモード へ戻る

鳥なき里のマイコン屋(102) GD32VF103、タイマ、インプットキャプチャ へ進む