2016-11-15 12:57 | カテゴリ:PIC応用回路

CPU付きLEDXC8言語でのドライブに成功しました!!
(紆余曲折の末)



先日トライして、挫折、あきらめかけましたが、再再度トライして成功しました。
これもロジアナの助けがあっての成功でした。


(なぜマイクロチップ社のアプリノートで上手くいかなかったのか)

マイクロチップ社のAN160アプリケーションノートをPIC16F1716に応用しましたが上手くありません。
ここの解析を検討しましたが、以前に書きましたように、PWMの波形のフェーズとシリアル通信のクロック(SCKとSDO)のフェーズがなぜか約200nsecほどずれることがロジアナの観察で分かりました。
具体的には、SCKなどのシリアル通信の位相からPWMの位相が200nsecほど遅れることがわかりました。
この時は20MHzのクロックだったのですが、PIC16F1716のマニュアルを見てみると、PWMは、TMR2のカウントゼロから立ち上がって、TMR2がカウントアップし、P2Rで指定された値と一致したら、ゼロリセットされ、そのリセットパルスが各周辺レジスタに配信されます。
このTMR2のカウントが一致したときに出される「T2mutch」パルスが終わって、次のPWM信号が立ち上がります。

LED_T2Mutch.jpg

あれ~、それじゃあ、このT2mutchパルスの間はPWMがゼロのままじゃないの。
というわけで、ロジアナで確認したら、まさにT2mutchパルスが、SCKの立ち上がりから立ち上がって、T2mutchが終了したところでPWMが立ち上がる様に観察されました。
つまり、問題であったPWM3のパルスの立ち上がりの遅れを、このTMR2mutchのリセットパルスがちょうど埋めてくれるというわけです。(ラッキー)

PWM波形の位相の遅れの原因はこのT2mutchパルスだったのです。

続きはこちらです、、、、



(ならば問題が解決できるかも)

そこで、このSCK、SDO、T2mutch、PMW3の信号波形をしげしげと観察していると、なんか上手くいけそうな感じです。

所で、ここで、ちょっと横道になります。

と言うのは、このCPL_LEDを動作させるためには、アプリケーションノートにもある様に、PIC16F1716に備わっている、組み換え可能な論理回路を使用するのですが、この設定が「鬼」の様に複雑怪奇なんです。
マニュアルを見ていても、自分でやってみようという気になりません。
そこで、MPLABXに搭載されたのが、

「マイクロチップ・コード・コンフィギュレーター」~~(ドラえもんの口調で)(笑)


MPLAB-Xにプラグイン方式で組み込んで、プログラム作成中に使用できるのですが、これすごい便利です。
おまけに無料です(笑)


PICのプログラミングでいつも面倒で間違えやすいと思っていた、I/Oピンのアサイン、A/D変換設定、PWM設定、タイマー設定などを、画面上で必要なパラメータをクリックするだけで、勝手に「Cプログラム」でその部分をくみ上げてくれて、mainプログラムとその他のプログラムを自動的にプロジェクトに作り上げてくれるんです。
いつも、だいたい、AD変換を使用しない定義を忘れて、動作不良になったり、タイマーやPWM設定で苦労していたのが、これを使用すれば、かなり簡単になりそうです。

今はまだ、操作や仕組みを勉強中(試行錯誤で)なので、使いこなすところまではいっていませんが、便利そうです。
特に、最近の新しいPICに備わっている、CLC(Configuarable Logic Cell:構成組み換え可能な論理回路)機能は、便利な機能ですが、希望するように論理回路を構成するにはものすごく面倒で複雑な作業が必要ですが、この機能を使用すると数分でできてしまいます。
結果は、ボタン一つでプログラムとして書き出されます。
練習も兼ねてこれを使用して進めるいことにしました。

インストールは簡単です、
TOOL->PLUG INs->Avairable Plugins -> MPLAB Code Configurator
をチックして、左下のinstallボタンを押して進めます。

これで準備完了。

さて、本題に戻ります。

このLEDをドライブする基準パルスは、約2usecの波長ですから、PICの基本クロックを20MHzとすれば、よさそうです。
次に、PWMやMSSPの基本とするタイマー2(TMR2)の基準は、LEDのパルスに合わせて2usecに設定します。
今までですと、このTMR2のパルスでPWM3をセットすると、SCKの立ち上がりから遅れてPWM3が立ち上がっていますが、今回、TMR2のMUTCH信号のT2MUTCHとPWM3の論理和をとれば、SCKの立ち上がりからPWM3の波形と一つにできます。
この波形で、LEDドライブの「ゼロ」を示すパルスができます。
よって、SCKとSDOの反転と(T2MUTCHとPWM3の論理和)の論理積をとれば良さそうです。


同じように考えて、こんどはLEDドライブの「1」のパルスもできそうです。


この様な、論理和や論理積などは、PIC16F1716に内蔵されているCLC機能(組み合わせ可能な論理回路)で、目的のCPU付きLEDのドライブ波形を取り出せるみたいです。

まとめますと、SCKとSDOで、波長2usecとなる様に設定。
それに合わせるためにクロックはタイマーTMR2を使用、波長が2usecとします。
PWM3もTMR2をクロックとして、Duty比は、CPU_LEDの短い信号のパルス幅(4-500nsec)にT2mutchの波形と合計で合わせるように、とりあえず30%にしました。
これで短いパルス波形は良さそうです。

次に長いパルス波形ですが、これも、SCKとPWM3、T2mutchを合わせて、1.5usecくらいになり、良さそうです。

これらを論理回路で考えると、下記の様になり、CLCを利用して、実現できそうです。

最終設定
TMR2 = 1 usecクロック
PMW3 = 25%Duty、クロックはTMR2
MSSP = クロックはTMR2、 SPIマスター設定
CLCP設定

これらをMPLABXの設定画面で確認してみます。(注意:このままでは動作しません、最後までご覧ください)

((T2mutch) or (SCK) or (PWM3)) and (SDO) -> CLC1
((SCK) and (nSDO) and ((PWM3) or (T2mutch))) -> CLC2
(CLC1) or (CLC2) -> CLC3


(TMR2)の設定

LED_TMR2.jpg


(PWM3)の設定

LED_PWM3.jpg


(MSSP)の設定

LED_MSSP.jpg

(CLC1)の設定

LED_CLC1.jpg

(CLC2)の設定

LED_CLC2.jpg


そして、二つのパルスを組み合わせるために論理和をとります。

(CLC3)の設定

LED_CLC3.jpg

なお、不要な論理回路の入力ピンは、必要に応じてGNDに落としたり、出力を反転したりしてあります。

以上を組み込んでプログラムしなおして、ロジアナで波形を観測してみました。

(最終波形)

LED_最終波形


オー!!
ちゃんと出ています。
短いパルスも長いパルスも指定された仕様にほぼ適合しています。
CLC3の項目の横の波形が出力波形です。

テストプログラムでは、1バイトの固定データ(例として0xAAなど)を出力して、確認したら、ちゃんとそのデータに合わせて、長短パルスが出力されていました。
そこで、R,G,Bのデータをそろえて、順次出力してみました。
あれー??
ロジアナにちゃんとパルスが出てきません。


(なぜ1バイトデータはOKで、3バイトはダメか?)

ちょっと悩みましたが、おそらく、連続して、シリアル通信バッファーに書き込んで前のデータを送っている最中に次のデータを書き込んで、ERRORになっているのかもしれません。
シリアル通信は、1バイト送信するのに約2usec弱かかります。
それならと、各SSP1BUF命令の間に20usecのDelayを入れてやったら、OKでした。

(mainプログラム)

LED_mainprog.jpg


というわけで、CPU_LEDのXC8言語だけでのドライブに成功しました。
今回は、これまでですが、この待ち時間はある意味ゆとりですから、MSSPのSPI通信の送信完了を割り込みで処理すれば、LEDに送る色のデータを処理する時間もできて、もっともっと使いやすくできると思います。


メデタシ、メデタシと、、、

早速、プログラムで疑似乱数を色データ値として代入して発光させてみました
じっと眺めていると、何か期待した感じと異なります。

早速、ロジアナでトリガーをかけて観察してみました。

データとデータの間の休み時間に最終出力(CLC3)にパルスが出ています。

(不要パルス)

LED_YobunPulse.jpg

良く見てみると、送信データの最終ビットが、「ゼロ」の時は、この余計なパルスは出ていませんが、「1」の時にデータの出力が、このお休み時間帯にずーっと「1」になったままです。
そのために、予期しないパルスが出ていることがわかりました。

これを消すためには、SDCが「ゼロ」(このお休み期間はSDOは「1」ですが、SCKは「ゼロ」に維持されています)の間は、このパルスをSCKと論理積をとって消すことができそうです。

ここを修正した論理がこちら、

(CLCP修正 )これでOKです!

   送信中断時の不要なパルスをSCK=L で除く(注意:わかりやすい表現に改良しました)


* {((T2mutch) or (SCK) or (PWM3)) and (SDO) } ->CLC1
* (CLC1) and (SCK)-> CLC4
* ((SCK) and (nSDO) and ((PWM3) or (T2mutch))) -> CLC2
* (CLC4) or (CLC2) -> CLC3(ここからCPU_LEDの制御信号が出ます)


修正後の波形がこちら
送信中断時には、余分なパルスは出ていません。

(最終波形収正版)

LED_FinalData.jpg


(7色発光動画)



デモプログラムによる7色+白の発色の様子。
輝度が明るすぎるため、1/16に落としています。


最終デモプログラム(MPLABXのXC8プロジェクトの圧縮フォルダー)はこちらからDLしてください。(GoogleDriveです)


最終のMPLABXのプロジェクト

【ジャンル】:趣味・実用 【テーマ】:電子工作
コメント(6)

管理者のみに表示する