Raspberry Pi : ハードウェアPWMについて

RaspberryPi : GPIOの制御方法にふれる

でも少し触れたハードウェアPWMはホントに1個なのか?について、RaspberryPiに初めて勉強し始めた当初から疑問に思ってたので、検証を実施。まず、根拠としては、搭載しているARMのBCM2836のデータシートを見ると、PWMは2基ありそう。

bcm2835データシート(bcm2836と同じと思われる)

bcm2835-pwm01.jpeg

bcm2835-pwm02.jpeg

上の図から、pwm_chn_1pwm_chn_2の2基のPWMモジュールが、DMAと繋がっています。下の図では、2つのGPIOポートがそれぞれのPWMモジュール(PWM0とPWM1)に繋がっているようなので、GPIOポートは4個使えるけど、同時に違う波形を生成できるのは2個までということになる。(ちなみにRaspberryPiでは、GPIO12~19までしか繋がってない)

ただし、いくつかの海外の掲示板を見ると、そのうちの一つのPWMモジュール(おそらくPWM1)はオーディオ機能とも繋がっており共用らしいので、巷で言われている「ハードウェアPWMは1基」というのは、独立して使用できるのは1基ということなのかな?と理解しています。音楽プレイヤーとして使う予定がなければ使えそうです。

こちらとしては、プログラムで同時に2個の異なる矩形波が生成できれば良いので、試してみることにする。

  • PWMモジュールと繋がっているとされる4つのGPIOにPWM設定を行えるか?
  • 1つのGPIOに別の波形を設定して、オシロで観察したらほかの3つのGPIOの波形はどうなる?
  • 繋がってないGPIOに同じ設定をするとどうなるのか?

などを以下で検証。

検証結果

4つのGPIOにPWM設定(周期20ms、パルス幅5ms)をWiringPi-Pythonで設定し、gpioコマンドで設定状態を確認したところ、以下の結果になった。

hardware_pwm01.jpeg

BCM12,13,18,19のピンを見ると、もともとMODEがINだったのが、設定後にはALT0ALT5に変化した。オシロで確認したところ、以下の波形を4つのポートで確認。設定した内容になっていた。

image

次にBCM18(GPIO18)ピンのみに異なるPWM設定(周期15ms、パルス幅10ms)を設定した結果が以下になる。GPIO12番も以下の結果になっていたので、GPIO18と12番が同じPWMモジュールに繋がっていることが確認できた(PWM0)

image

ところがである。じゃあ残りの2つのピン(GPIO13と19)は、前の設定のまま(周期20ms、パルス幅5ms)だよね?と確認すると以下なっていた。

image

波形が変わってしまっている。。ただし、設定したDuty比は前のままで周期だけが20msから15msに変わっているようであり、一応独立はしてそう。今度はプログラムが怪しくなってきた。

wiringpi2.pwmSetClock( clock )
wiringpi2.pwmWrite( pwm_pin, duty )

よく見ると、WiringPiでは、Duty比の設定はピンごとに設定できるが、周期の設定はピン事ではなく、本体への設定のようである。なので、「周期は共通であるが、2個のハードウェアPWMで、個別にDuty比の設定が可能」ということになる。

改めて、再度設定してオシロで確認する。

PWM0(GPIO12,18)に対して、周期20ms、パルス幅10msを設定。

image

PWM1(GPIO13,19)に対して、周期20ms、パルス幅15msを設定。

image

とりあえず、ハードウェアPWMはやはり2個設定できることが分かった。ただし、同じ周期でないといけないので、サーボモータを2個つなげる場合は、同じモデルか同じ周期じゃないと制御できないことになるので注意する必要がありそう。