PIC16F1823-I/P を用いたLED点滅テスト(ソフトPWM編)

前回「PIC16F1823-I/P を用いたLED点滅テスト(TMR0編)」ではタイマー割り込みを使用して本格的にタイミング制御を行うようにしました。

LEDを応用しか機器を設計する上で重要なダイナミック点灯などはこの制御が必須でもあるので、重要なノウハウになります。

 

そして今回は、このタイマー割り込みを応用して、LEDの明るさをソフトウェアでPWM制御してみたいと思います。

PICマイコンにはハードウェアレベルでPWMを搭載していますので、本格的にPWM制御するには内臓I/Oユニットを使用するのがベストではありますが、PWMユニットは1ユニットしか搭載していませんので複数の波形制御を行うのは困難です。

ソフトウェアで記述すると複数のPWM制御を行うことが可能となりますし、ハードウェアPWMでは出来ない微妙なタイミング調整も出来ます。

ただしPWM周波数はせいぜい10KHz程度でしょうから、このあたりは接続する機器と目的で使い分けるのが良いと思います。

 

ソフトPWMを実現する上で必要なのは、

基準となるタイマー割り見込みは許容できるもっとも高い周波数で割り込みを発生させること。

PWM波形を内部的に処理するレジスタの定義。

特にタイマー割り込みをどこまで引き上げるかは悩みどころだと思います。

今回のサンプルでは、LEDの明るさをソフトPWMで高速点滅するのが目的ですので、点滅が目に見えてはいけません。

人の目は80-100Hz以上であれば光の点滅は脳の錯覚(残像)により連続発光に見えるので、PWM波形全体の周期は100Hz以上でなくてはいけません。

 

それらを考慮して作成したソースが下記。

2016.08.08 追記  / HN なおさんよりメールにて指摘があり、割り込みプログラムでTMR0をリロードしていないバグがありました。

謹んでお詫び申します。

 

前回のサンプルからの変更点としては、タイマー割り込みを1msから250usに変更したこと。

かなり早いタイミングでタイマーを駆動しています。

そして、PWMで明るを制御するレジスタの追加。

SET_PWMFREQ      PWM周期設定レジスタ(タイマー周期 x 設定値)
CNT_PWMFREQ      PWM周期カウンター
SET_PWMPER       PWM判定レジスタ、SNT_PWMREGより大きい場合LEDが点灯

 

今回main関数のほうで、SET_PWMFREQを40と設定していますので、PWM周期は250us x 40で10ms…つまり100Hz周期・分解能4KHzで明るさ制御していることになります。

そしてもSET_PWMPERで変化点を順次変更するようにプログラムしています。

 

このプログラムをビルドして実行したのが下記の動画。

暗い部分の諧調をもっちょっと滑らかだったらいいのですが、LEDの発光特性的にいきなり明るく見えてしまうので致し方ないところ。

ここを改善していくにはもっとタイマー割り込みを早くしてPWMの分解能をあげていく必要があるかもしれません。

 

このサンプルプログラムではRC0端子にタイマー割り込みの期間中”H”となるようデバック情報を埋め込んでいます。

この信号をオシロで取り込んだのがこちら、

マス目ひとつが200usですので、大体250us周期でタイマーが割り込みが発生しているのが判ります。

 

次にこの”H”の区間、割り込みの処理時間はどのくらいか確認してみます。

マス目ひとつが5usなので、大体4usくらい(1.6%)でしょうか…このくらいの処理時間でPWM制御できているのであれば、100us位までタイマー割り込みを高速化しても良いのかもしれません。

ただメインプログラムの処理は何も行っていませんし、そのた割り込みも動作させていません。

また複数のPWMレジスタを用意して複数の波形整形を行うのであればそりなりに割り込み時間を要することになりますので実際には必要とする処理とのトレードオフとなると思います。
TOP/電子工作の部屋にもどる