2023年2月21日:ラズピコのPWM。 やっぱしanalogWriteは捨てちゃえ
この続き。
ラジオペンチさんのコメント
「せっかくだから analogWritePure なんて関数・・・」と
ありましたので、難しいことはせずにサクッとまとめてみました。
※サクッとで、エラーチェックや
数値範囲チェックはしてません。
関数は2つ。
int pwmStart(pin_size_t pin, int val, int range, int frq)
まず、これで
分解能 range と 周波数 frq から、
val値に対する乗数を計算します。
pinはPWM出力ピン番号。 valはPWM幅。
というのはピコのPWM、クロックが125MHzで分周器の最大が
8bitの256未満 (m・n/16の浮動小数点で設定できる)という
制限があるのです。
PWM周波数500Hzで8bit分解能だと分周比が976.56になって
しまい、256.0を越えてしまいます。
そこで、PWM幅を得るval値にmlt値を乗じるようにして、
分周比が256.0を越えないようにします。
PWM周波数1kHzで分解能が100だと分周比が1/250で、
PWM幅valへの乗数が5となります。
val値0でL、100でH。
1~99でデューティ1%~99%が出てきます。
pwmStartの返り値である乗数(mlt)を得たあとは、
この関数↓でPWM幅を出力。
void pwmVal(pin_size_t pin, int val, int mlt)
浮動小数点計算が不要な分、処理が早くなります。
テストプログラムを走らせるとこんな感じ。
USBで通信 出力ピンをオシロで観察
# Pico PWM Test #5 (2023-02-22) Entでタイトル出力
# PWM Port >22 出力ピン番号
# PWM Freq (500Hz) >1000 PWM周波数
# PWM Range (256) >100 分解能 0~100で
PWM:22 m:5 1/250.000 mltとclkdiv値
# PWM Data >10 10だとデューティ10%
10/100 10.000%
# PWM Data >99
99/100 99.000%
# PWM Data >45
45/100 45.000%
# PWM Data >33
33/100 33.000%
# PWM Data > Entだけ入力で最初から
# PWM Port >
# PWM Port >19 出力を19ピンに
# PWM Freq (500Hz) >800 周波数を800Hzに
# PWM Range (256) >1000 分解能を1000に
PWM:19 m:1 1/156.250 mltとclkdivが確定
# PWM Data >120
120/1000 12.000%
# PWM Data >990
990/1000 99.000%
# PWM Data >10
10/1000 1.000%
# PWM Port >19
# PWM Freq (500Hz) >1200 1200Hz
# PWM Range (256) >4096 分解能12bitで
PWM:19 m:1 1/25.431 mltとclkdivが確定
# PWM Data >100
100/4096 2.441%
# PWM Data >4000
4000/4096 97.656%
# PWM Data >4095
4095/4096 99.976%
# PWM Data >4090
4090/4096 99.854%
1Hz単位でPWM周波数が設定できます。
PWM分解能も「2^n」だけでなく、100とか1000に
できるので、10進でPWMデューティを設定する時に
便利かと。
分解能が偶数だと、半値で1/2デューティが得られます。
※テストプログラム
・ダウンロード - pwm_serial_in5.txt
Arduino IDEの環境によってはコンパイルエラーが出るかも。
※ pwmStart() 実行時間
※ pwmVal() 実行時間
最近のコメント