● 実験テーマ101
「PIC32MX_カラーOLEDの表示実験」
(前回のOLEDにBMPイメージを表示するのにPIC32MXを使ったがNGだった顛末+Adafruit製のOLEDに変えての実験記事です。)
※ 2018.2.8
→ 1回目の更新です。
Adafruit OLEDキャリーボード上の、SDスロットを使って、カードに格納された、
ジャケットイメージ(100x100dot BMP)を読出し、OLEDに表示する追試をしました。
1月31日からの記事を参照してください。
※ 今回は、Adafruit製のOLEDに変えての実験記事が主体です。
これをやるに前に、前回のOLEDにBMPイメージを表示するのにPIC32MXを使ったが思うように動かせなかったのですが、
これの顛末も自分の備忘録として残したいと思い書きました。
■ 2017.12.26
・前回のOLED((NVK-128SC008F/制御IC:LD50T5128M)にBMPイメージを表示するのにPIC32MXを使ったが
結果的には、思うように動かせなかった。
当初は、来年(2018年)の干支の、戌(狛犬)のイメージを表示させて新年に公開しようと思っていたのだが・・・・
まずは、動かせなかったが、それまでの顛末を書いてみる。
■ 2018.1.1
・表示テスト・ソース上がる。
HEX書込みOK。
@ OLED無負荷電源電圧確認
VDDIO= 3.31V
+5V= 5.21V
VCC= 15.99V
A OLED繋ぐも、表示せず。
誤配線が1つ有り。
WR/ラインが冶具の、未使用ピン:15pinに繋がっていた。
16pinに直すが表示せず。
また、ソフトに誤記あり。
WR/ポート:RD5はミス、RD4に修正→ これでも動かず。
■ 2018.1.2
・8bitデータバス・ポート:RE0〜RE7が機能しているか確認した。
PIC32MXのポートレジスタは、32bitだが、64pinQFPパッケージの、PIC32MXは、実際には、16bitが有効で
REポートは、0-7の、8bitしか実装されてないので、コマンド或いはデータ引数:unsigned
char cmd, data
を、16bitにキャストして、LATE= (unsigned short)cmd;
(或いはdata)としているが、これで良いのか不安
だったので、簡単な、REポートの単体テストプロを組んで、挙動を確認してみた。
問題無いことを確認した。
このポートは正常に動いている。
■ 2018.1.3
・VDD-VCCタイミングを実測してみた。
・VDDがONしてから、VCCがONするまでの時間規定は、100mSminである。
結果的には、規格を満足して問題はない。
この時間は、殆ど、ソフトで入れている、mS単位の遅延時間の合計による。
バスアクセス時間の違いは、このオシロの低速レンジでは、差が出ない。
WRパルス幅をNOP 1個で設定している場合と、5個(スペック上:30nSmin)で設定している場合の差も殆ど判らない。
電源ON直後にはポートのレベル設定をしてないので、RESETラインにゴミが出ているが、10mS後に、正式な20mSの
負パルスでリセットしているので、この影響は無い。
PIC24Fでやった場合と、時間の差異(PIC32MXの方が多少長目)があるのは、遅延関数の精度バラツキによるものである。
■ 2018.1.4
・Fcy=16kに落として自作ロジアナでバスタイミング確認
全てのバスラインが正常に動いていて、OLEDに供給していることを確認した。
この時は、プローブの装着し易さから、OLED無負荷でタイミングを確認した。
↑-- 上画像をクリックすると、他データビット等、全ての測定写真が見られます。
■ 2018.1.8
・今、不可解なのは、バスタイミングは大方良さそうなのに、何故、PIC24FでOKで、PIC32MXだとNGなのか?
という点である。
ここで、両者のタイミングを実測比較(Fcy=16k)してみて、PIC24Fのタイミングに近いタイミングになるように、
ライトのデータ・セットアップ、ホールドマージンを、NOP遅延で調整して試すことにした。
これでも未だ表示しない。何故かコマンド・データを受け付けて無いようだ。
■ 2018.1.9
・Fcy=4MHz(Tcy=25nS)まで落とせば、ましな波形が中華オシロの、5uS/divで見れるはずなのでやってみた。
(100M帯域のデジオシがあれば一発なのに・・・・)
何となく手掛かりが掴めそうな感触になった。
OLED負荷(実装)にして、データバスを観測すると、波形が階段状になり、Hiレベルが、約2V付近まで下がる区間
が出て来る。(尚、OLED無負荷なら問題無い。)
これは、前回の、PIC24Fでは、起きない。
OLEDの、Vih=0.7*VDD=0.7*3.3=2.31V,
Vil=0.3*VDD=0.3*3.3=1.0Vなので、このレベルは、フローティングレベル
になり、判断が、不定になる可能性がある。
ただ、他のコントロール信号は、変化が緩慢なのかこのような現象は起こらない。
■ 2018.1.10
・たかが、4MHzなので、反射が起きているとは思えないが、バスラインに、数Ω(47〜100Ω)のダンピング抵抗
を入れてみた。
一見、階段状の波形は無くなったと思いきや、階段状になっていたところが、Lowレベルに下がっただけである。
OLEDコントローラの入力インピーダンスが低いのかもしれない。
これでは駄目である。
■ 2018.1.12
・ある事に気が付く。
数週間前に、Fcy=16kに落として、バスタイミングを見た時は、OLEDは外してバス無負荷状態だった。
その時のタイミングは以下で問題ない。
今迄、16kに落としてバスを見た時、OLED負荷で測定したことは測定のし易さから、一度もなかった。
OLED負荷で確認してみた。OLED負荷だと、WR/の立下り部で、データレベルが約2Vに下がる現象が起き、正しいレベルを書込めない。
それで未だに表示してないと考えられる。
このタイミングは、ソフトで、WR/が立下がるまでの時間を延ばしても、全体のバス信号が伸びるだけなので、
相対的なタイミングは一緒で変えられない。
■ 2018.1.13
・OLEDコントローラの、VDDスペック=2.4V〜 2.8Vtypのところ、3.3Vで動かしているのがいけないのかと思い
トレーニング基板の、3.3Vレギュレータ出力にダイオードをかまし、約0.65V落として供給してみた。
これでも階段状にダウンする現象は同じだった。
■ 2018.1.15
・PIC24Fでは良くて、PIC32MXだと駄目な理由が解らない。
ポートのドライブ能力の違いとも思ったが、どちらかというと、PIC32MXの方がドライブ能力は高いようなので関係無さそう。
これについて復習の意味で調べてみた事をまとめてみた。
@ PIC24F
出力ポート
・最大18mA(吸い込み・吐き出し(供給)共通)→ 後閑本に、明記されている。
Voh(min)= Vdd-0.7= 2.6V
・データシートによると、VDD=3.3Vでの値は明記されてないが、測定条件項目に下記載があった。
これによると、シンク+ソースで、トータル12.5mA
IOL = 8.5 mA, VDD = 3.6V IOH = -3 mA, VDD = 3.6V
A PIC32MX 出力ポート
・最大25mA(吸い込み・吐き出し共通)→ 後閑本に、明記されている。
PIC24Fより流せる??誤記??
Voh(min)= Vdd-0.7= 2.6V
・データシートによると、VDD=3.3Vでの値は明記されてないが、測定条件項目に下記載があった。
これによると、シンク+ソースで、トータル19mA
IOL = 7 mA, VDD = 3.6V
IOH = -12 mA, VDD = 3.6V → 問題になっているのはハイの時に入力に供給できる電流だが、データシートを見る限りは
何故か、PIC32MXの方がドライブ能力が高い。現象と矛盾がある??
※ 見方を変えれば、データビットのハイ出力時の落ち込みの原因は、ドライブ能力以外の要因と考えられなくもない。
■ 2018.1.16
・ここまでやれることはみな試してきて駄目。
結論的には、データバスのドライブ不足かAC的な要因あるいは、トレーニング基板に実装されている
PIC32MXの一部不具合が考えられる。何故、WR/と同期して立下りでレベルが落ちるのかが不可解。
バスラインにHCバッファ(Iol=6mA)を挿入しての実験もしてみたが、駄目。
PIC24Fの、RBポートでは上手く行っていて、データシートによると、Iol=8mA@Vdd= 3.6V である。
トランジスタアレーを使う手もあるが、今更回路を複雑にしたくないし、そこまでやる気はないので
このプロジェクトは、一時クローズすることにした。
この後、何か進展(追試するかも?)があった時は、随時アップしたいと思います。
<※ ここからが、今回の本題の記事です。 ● Adafruit製のOLEDに変えての実験記事 これも動くまで想像以上に悩みました。>
■ 2018.1.17
・これまでの記事に書いたように、前テーマの、OLED(制御IC:LD50T5128M)を、PIC32MXでは、どうしても
動かすことは出来なかった。
スペックと、症状に矛盾あり過ぎ。
約3週間やったが、一時クローズすることにした。
次のテーマは、OLEDから離れたテーマにしようとも思ったが、前々から気になっていた、
スイッチ・サイエンスさんから販売されている、Adafurit製の小型キャリーボード付き、1.5inch
カラーOLEDモジュール(SPI制御)
の表示実験にしてみようと思う。(ちと高価:税込み5605円だが、小型なのと、OLEDに必要な電源が全て搭載されているので納得)
これを、PIC32MXで動かしてみる。
・前回使用の、aitendoから購入したOLEDは、とにかく輝度が低くて、色も今一だったのでこれを試すのも良いかも。
これをOLEDの実験としては、最後にしようと思う。
応用としては、さらに進化したMP3プレーヤを考えている。
今度のコントローラは、SSD1351である。
主な参考資料は、Adafruit HP上の、チュートリアル等だが、Web上にも製作例あり。
「mgo-tec電子工作」さん。
注文を済ませる。
■ 2018.1.18
・スイッチ・サイエンスさんから、物が届く。
■ 2018.1.19
・このキャリーボードの回路図も、Adafruit
HP上から、チュートリアルpdfの最後のページに載っていたが、
拡大しても、ピントがずれ、ぼけて非常に見ずらくなっている。
他に、eagle cadの、schの、htmlソースもアップされていたが、eagleで正常に開けず。
この見ずらいpdfで回路をざっと見たところ、
SCLKと、SDO(PICから見た信号名で、OLED側では、MOSI)は、SDとOLED共通になっている。
デフォルトは、4線式SPIになっている。
また、読込み(SDI)は、SD専用となっている。(たぶんOLEDの読込はしていない。)
たぶん両者の、CS/で切替えて使えばよいと思われる。
それから、SDのライトプロテクト信号は出ていない。
カード検知の、CD/のみ。
・一応実験回路は作成済み。
最初のテストは、SD未使用にして、フォント(キャラクタ+漢字)表示+
斜め線+BOX+円描画+BMPイメージ
までの描画テストにしようと思う。
・参考ソースとして、mgo-tec電子工作さんのページのがあるが、4線式SPIの基本関数は、ノキア5110液晶で
温度計を作った時の関数が、解り易く書かれているので、これを参考にすることにした。
■ 2018.1.20
・今回の文字フォントは、ASCII文字:8x8bot(フォント部7*5dot)と、S-JIS漢字フォント:12x12dotの2つにする。
将来的に、MP3プレーヤに応用しようと考えている為だ。
とりあえず漢字表示も含めて、全てのテスト項目のソースを書上げ、コンパイルもOKになった。
■ 2018.1.22
・ケーブル冶具作成済み。
HEX書込みOK。
<動作確認>
(1) まずは駄目。表示せず。調査開始。
@ 電源電圧確認(OLED内部にて)
・VIN= 5.22V, VDDIO= 3.29V, VCC= 13.6V → OK
A RESETピンが変。
最終的に、3.3Vに落着くはずが、パタパタ動いている模様。(テスターにて)
→ OLED_RSTと、OLED_CSの、ポート定義が同じRD7だった為。CSの方を、RD4に修正。
これでも駄目。Hi固定にはなったが・・
B プログラムは、RUNしていることを確認した。→ RF0
Lチカにて。
C PIC32MXを最高速:Fcy= 80MHzで動かしているので、SPIの、データセットアップ・ホールド時間
のマージン不足と思い、WR/出力前後に、NOPを挿入したが駄目。
D ポート割付けと、TRIS(入出力)レジスタの設定を再確認したが問題なさそう。
E Adafruitのサンプルコードの、OLED初期化項目の以下2点が?
(尚、mgo-tec電子さんのコード:Adafuruitのサンプルコードを参照してるとのこと。)
writeCommand(SSD1351_CMD_PRECHARGE); // 0xB1
writeCommand(0x32);
writeCommand(SSD1351_CMD_VCOMH); // 0xBE
writeCommand(0x05);
//// 理解不能なこと
データシートのコマンド表の、command/dataの区別の記述と、データシートのコマンド詳細の説明に矛盾がある。
また、Adafruitのサンプルコード+mgo-tec電子さんのコードとも矛盾がある。
サンプルコードでは、一部のコマンドが、コマンド+コマンドでワンセットになっている。
たぶんこれを、ダブルバイトコマンドとデータシートのコマンド詳細では記述しているものと思われる。(これが怪しい。)
しかし、同じデータシートのコマンド表では、当該コマンドがコマンド+データとなっていて矛盾(誤記?)している。
サンプルコードを信用すれば、今?となっている記述は、コマンド+コマンドでワンセットでよさそうなのだが・・・
とりあえず、サンプルコードと同じにしてみる。
これでも表示せず。
(最初自分なりに考えて、ここがおかしい(誤記)と思いコマンド+データと修正したが、未だに動いていない。)
■ 2018.1.23
・SPI書込み関数は、参考コードとは違えて書いている。
若干の違いがある。
私は、SDINを先にチェンジして後で、SCLKを立上げている点だが、(参考コードはこの逆)
基本的には、これでも、SCLKの立上りに同期して、SDINが転送されて行くので良いような気がする。
まあ、セットアップマージンの点では、データチェンジの前に必ず、クロックHi→Loのアクセス時間を入れた方が、
有利かも。
あと、参考コードは、CS/の後にRESETパルスONを入れている点が異なる。
とにかく同じような記述(タイミング)にして試しても未だ表示せず。
何が悪いのだろうか?
もう一つ気になるのは、リセットパルスON前後に入れている遅延時間と、パルス幅が、500mSと、やに長い時間に
してある。
RESET ON後、約200mS後にセグメント・コモン電源がするので、その時間も兼ねて長くしているのかな?
これもサンプルコードと同じにしてみたが未だ表示せず。
■ 2018.1.24
・去年の暮れから約3週間、PIC32MXで、OLEDが一度も表示して(光っても)くれない。
ここで頭の中にある疑問点を一度整理しながら進めることに。
@ AdafruitのOLEDキャリーボード(1.5inch 128x128
RGBColorOLED コントローラ:SSD1351)の、Eagle回路図データ
が公開されているが、正常にオープン出来ないでいる。
キャリーボードのpdfファイルの最終ページに載っているが、ワザとか判らないがピントがぼけて見ずらい状態。
正常にオープンする方法は?
→ Adafruit
HP- Downloads and Linksをクリックすると、*.pngの回路図イメージがダウンロード出来た。
これでまともに見られる。
A @に関係あるが、キャリーボードに搭載されている、OLEDモジュールの型番が不明
→ ダウンロードした回路図で明確に確認出来た。
「UG-2828GDEDF11」(現在、aitendoの在庫から外されている品種)だった。
B コントローラ:SSD1351内部の電源電圧構成(ブロック)が、今一理解できない?下記でOKなことを確認した。
→ ・ VIN= 5V
・ VDDIO= 3.3V(アナログ電源): キャリーボード上の3.3Vレギュレータにより供給(入力:5V)
・ VDD = 2.5V(デジタル・コア電源):
コントローラ内部の、VDDレギュレータにより供給
・ VCI = 3.3V: コントローラ内部の、VDDレギュレータの入力電圧(キャリーボード上の3.3Vレギュレータにより供給)
・ VCC = 13V(OLEDパネル電源):
キャリーボード上のDC/DCにより供給
・ VCOMH= 10.66V(コモン電源): レジスタ設定値によって供給電圧が決まる。今回は、VCOMH=
0.82xVCC
・ここまで全く表示してないのは、SPIコマンド・データが正常に書き込まれてなく、コントローラ内部の、VDDコア用レギュレータ
から、2.5Vが出力されてないからと考えられる。
このレギュレータは、SPIコマンドによって制御される。
ABhコマンド+01hデータで、このレギュレータが有効になる。
実際に、キャリーボード上で、VDDを測ってみることにした。
FFCコネクタに出力されているポイント(パスコンC4)で測定したら、VDD=
2.17Vであった。低目なのは、このVDDは、
供給元を、外部/内部と選択できるようになっていて、ブロック図にはなかったが、それの切替え素子(ダイオード等)の
電圧降下によるものと考えられる。
また、今VDDは正しく供給されているが、これは、ABhコマンド+01hデータで書込まなくても、RESET状態であれば、
内部レギュレータ有効になるので、SPIが正しく動いているのかの判断にはならない。
そこで、ABhコマンドが効いているか、ABh+0hにして、内部レギュレータを無効にしてみたが、変わらず、2.17Vのまま。
やはり、コマンド・データを正しく受け付けてない。
・WEB検索していたら、今回のキャリーボードに搭載されている、OLEDモジュール:UG-2828GDEDF11評価ボードのアプリノート
を見つけた。それには、OLED初期化のフローとサンプルが載っていた。
これによると、コマンドライト+データライトを、SSD1351のデータシートでは、ダブルバイトコマンドと称していることが、
はっきりした。
コマンドライトが並んでいるところは、シングルバイトコマンドで、その他は、コマンド+データで良いようだ。(1/22
E項目の疑問が解決)
■ 2018.1.25
・調査続行である。
@ VCOMHピンの電圧を確認
→ RESETが正しく掛かっていれば、BEhコマンド+05h(デフォルト)で、0.82xvVCC:13V=
10.66V位になるはず。
結果、VCOMH= 0Vであった。
これでは光らない。
ちなみに、VCC= 13.6VでOK。
A ダブルバイトコマンド(コマンド+データ)を使うべきところを、コマンド+コマンドとしてたところを、コマンド+データ
に直して試してみた。これには、BEhコマンドも含まれる。
→ これでも未だ表示せず。
B RESET波形が正しいか確認。
→ OKだった。
C この時点で初めて、自作ロジアナで、SPIタイミングを確認してみる。
RESET解除のタイミングで最初の数コマンドを取ればよい。
ただ自作ロジアナなので、Fsck≒100kに落として測定することになる。
→ ちょっと、タイミングを確認するのが遅かったが、
結局原因は、PIC32MXトレーニング基板に実装の、PIC-RD4ポート(OLED_CS/)が、何らかの理由で壊れて、Lowぱなし
になっていたのが原因だった。
OLED_CS/ポートを、空いている、RD3ポートに変更した。
これでタイミングも良さそうだし、未だ低速だが初めてOLEDにモザイクが表示された。
OLED初期化の最後(Display ON)で止めていて、その前で、RAMクリアしてないので、これで正常。
・ここで改めて、キャリーボード上で、各電源電圧を実測してみた。
<実測結果:下記の通リよさそうである。>
VDD= 1.99V(2.5Vtypに対し低めだが前記したようにこれは、VDDピンに入出力切替ロジックが入っていてそれによる電圧降下のため。本来のVDDはICの中なので測定不可)
VCI= 3.26V
VDDIO= 3.26V
VCC= 13.71V
VCOMH= 11.40V
※ 測定ポイントは以下の写真を参照してください。
■ 2018.1.26
・PIC32MXの、フルスピード:Fcy= 80MHzにて、WR/にも一切、NOP遅延を入れない状態で、昨日のように
ゴミ表示するか確認してみたところ、問題無く表示出来た!!
・ここで、全てのテスト項目を動かしてみた。
漢字表示以外は、全てOKだった。
何故か、全く表示しない?
これはなんてことなかった。
テストループに入る前に、漢字コードの初期化:8140h
が抜けていたのが主な原因だった。
・去年の暮れに準備しといた、128x128サイズ/RGB565フォーマットの、今年の干支、「狛犬」の、BMPイメージも
綺麗に表示出来ました。
さらに、Adafruit HPにアップされている、「lily128.bmp」も、どんな感じになるのか表示させてみることに。
これをダウンロードすると、176x176サイズ/24bitカラー フォーマットのBMPイメージだった。
花びらの色が、深い青になっている。
これをそのままOLEDに表示することは出来ないので、画像加工ソフトで、サイズダウン+減色処理し、
128x128サイズ/RGB565フォーマットに加工します。
このBMPファイルを、C言語で扱える、データ記述フォーマット(テーブル形式)に、
フリーソフト:Binary File Extractor(「レフトアームテクノロジー」 さん作成)で変換しプログラムに組み込めばOK。
以下にこれをOLEDに表示させた時の写真をアップしました。
このように減色処理されているので、花びらの色が、明るい空色になっています。
また、Adafruit
HPにある、このイメージのデモ写真を見ると、これの拡大された花びらの部分がアップされた画像に
なっているようです。花びらの色が、明るい空色は同じですが・・
・これで長い間、実験して来たが、ようやく、PIC32MXで、OLEDを表示させることが出来ました。
他の表示デモは、このページ冒頭の写真を参照してください。
今迄実験してきたOLEDの中では、一番綺麗(輝度も高いし、コントラストもはっきりしている。)だと思います。
---<ここから、追試:「Adafruit OLEDキャリーボード上の、SDスロットを使っての実験」の記事>-------------------------------------------
■ 2018.1.31
・せっかく、キャリーボードに、SDスロットが実装されているので、これを使って、BMP表示の実験をしてみようと
思いました。
将来的に、MP3プレーヤを予定しているので、アルバム・ジャケット・イメージを、繰り返し表示しようと思います。
・今回のキャリーボードの、ヘッダーピンには、カード検知信号:SD_CDは出ているが、ライトプロテクト信号:SD_WE
は出ていない。
まあ無視すればよい訳だが・・・
・SDカード内のBMPファイルを読み出して表示する手順の復習をしてみた。(100x100サイズとする。)
@ ヘッダ部は、138バイト(ダンプして確認した。)なので、ここは読み飛ばす。
(128x128dotの場合も、138バイトで良い。ダンプして確認済み。)
A 139バイト目から、100x100ワード分、BMPデータを、SDから読込みバッファに格納する。
B 大元のBMPデータは、左下から、右上に向かって配列されているので、このままの順で描画すると、
上下逆さの画像になってしまう。
バッファ・ポインタ[9999]から読出して、下に向かって描画する必要がある。
■ 2018.2.1
・SDカードからBMPを読込んで表示する実験だが、仕様をどうしようか、ちょっと迷っている。
OLED_MP3プレーヤにすることを前提にしたいのだが・・・
最終的には、BMPでなく、JPEGタグから、ジャケットイメージを、SDから読込んで、それを表示(以前断念した訳だが・・)
するのが理想的だし、市販のプレーヤはそうしている。(もう一度、チャレンジしてみるかも??)
なので、以前、QVGA(UL024TF)のタッチパネル式 MP3プレーヤの時にやった、100x100サイズのジャケットイメージ
にしようと思う。
関数は表示位置を変えられるものに変更する。(前作あり。)
そして、空スペースの最下段に、読出した、BMPファイル名を表示しようと思う。
一応、ソース書上げ、コンパイル〜HEX書込みまで、OKとなった。
・チェック開始。
まずは駄目。
何故か、カードを入れてないのに、"Find Card OK!"になる。
ところで以前、UL024TFでMP3プレーヤを作った時、キャリーボード上のピンには、CDも、WEも出ていなかった。
その対策として、幾つかやったが、Microchip社、FAT16ファイルシステム中の、SD-SPI.cの、
BYTE MDD_SDSPI_MediaDetect (void)
{
// return(!SD_CD);
return(1); // CDの無い、UL024TF使用のため修正(強制的にカード検知状態にする) 160712
}//end MediaDetect
この関数、FSconfig.hの中で、#define MDD_SDSPI_MediaDetect MDD_MediaDetect
と定義されていた。
何と、まどろっこしいのか・・・
そして、カード検知のところでは、負論理接点の場合は、
if(!MDD_MediaDetect()){ // カード挿入中か?
OLED_Str(0, 0, "Wait Card Insert", CYAN, BLACK); // 挿入待ちメッセージ
}
else{ //// カード挿入状態であれば以下を実行する。
としていた。
現在は、この記述になっている。
調べている内に、キャリーボード上の、スロットの、SD_CS接点は、カード検知で、'Hi'であることに気付く。(テスターにで確認した。)
以前使ってた、サンハヤトのものは、負論理であった。
if(!MDD_MediaDetect()){ の部分を、if(MDD_MediaDetect()){
に修正。
これで、SDカード未挿入時に、"Wait Card Insert"とブリンク表示するようになった。
ただこの時、SDカードを挿入しても、"Wait Card Insert"のまま?
ハード的にSD_CD接点は機能していることを確認している。
未挿入→ OV/ 挿入→ 2.2V位
この原因は単純なことで、BYTE MDD_SDSPI_MediaDetect (void)関数の修正をする前の状態(CD接点を見る)
に戻してなかったことが原因だった。(気が付くのが遅かった。)
つまり、下記のようにすればよい。
BYTE MDD_SDSPI_MediaDetect (void)
{
return(!SD_CD);
}//end MediaDetect
・これを直して、カード未検知/検知は良くなったが、検知後、先に進まない?
詳しく症状を確認すると以下の通リだった。
@ カード検知して、"Find Card OK!"メッセージは表示されるが、何故か、"Find"の後ろあたりに赤ドット3つ位のゴミが表示される?
A カード初期化後、最初のファイルサーチを行い、ファイルが見つかると、全画面クリアするが、何故か、全画面クリアせず、
@の状態(Find"の後ろあたりに赤ドット3つ位のゴミが表示される。)のまま?
・考えてみると、コードを書いている時から、不安なことがあった。
@ SPIは、OLED用の、自前のSPI関数と、SD用の、Microchip社、FAT16ファイルシステム内の、SPI関数を使っている。
A Adafruitのキャリーボードに実装されている、SDカードスロットピンの、SCKと、SDO(SD側:MOSI)は、OLEDコントローラの
それと共通接続になっている。
しかし、それぞれの、チップセレクト:CSは、個別になっているので問題無いと思っていたのだが・・そうではないようだ。
■ 2018.2.2
・さらに症状詳細を確認してみた。
@ カード未挿入時
"Wait Card Insert"が、約0.5秒毎に点滅表示している。→ これはOK(変な、赤ドットも表示しない。)
この時点では未だ、SDの、SPIは動いてないはず。
A カード挿入して、P_ONにて、
"Find Card OK!"(FSInit()の前)で止めた時、何故か、初期メッセージ"START
TEST"表示時に、赤ドットのゴミが表示される。
これは、単純に、OLED初期化後の、全面クリア後の、メッセージ表示のところで止めても起こる。
・どうやら、OLEDとSDの、MOSI(SDO)と、SCKを共通ポートでコントロールしているのが、既にここで影響しているようである。
しかし、SDカードを挿入してなければ、SDの影響が無いので正常に表示している。
■ 2018.2.3
・疑問点を整理する為に、PIC-OLED-SD
相互の接続ブロック図を書いてみた。(SD_CD信号は省略してあります。)
・重要なのは、OLEDとSDで共通に使っている、RG6-RG8ポートは、SPI2モジュール・ピン(SCK2,
SDI2, SDO2)との
マルチ機能ピンになっていることである。
しかも、OLEDコントローラの、SPI制御方式は、単純ポートを使っての、ソフトウエア通信なのに対し、
SDカードの、SPI制御方式は、単純ポートではなく、ハードSPI(PIC内の、SPI2モジュール)を使っての通信である。
なので、少なくとも、
@ SDカードをアクセス後に、OLEDアクセスをする前には、RG6〜RG8を、単純入出力ポート(SPI2モジュールとして使わない)
に戻す設定が必要。
→ この方法だが、SPI2CONbits.ON= 0; でSPI2モジュールを無効化し、TRIS*で、RG6〜8の入出力設定をすれば良いと思う。
A 逆に、OLEDアクセス後に、SDカードをアクセスする前には、RG6〜RG7を、SPI2モジュールとして使う(単純入出力ポートでない)
設定に戻す必要がある。
→ この方法だが、SPI2CONbits.ON= 1; でSPI2モジュールを有効化すれば良いと思う。
・とりあえずは、これでBMPイメージを表示したが、未だ不完全。
@ OLEDアクセスからスタートするが、SDカードを挿入したまま、P_ONした時も、OLED用のSPI設定にしないと、変な赤ドットの
ゴミが表示されるみたい。
これは後で直すことにした。
A 何故か、IMAGE001.BMP〜 IMAGE003.BMPまでは表示するが、それ以降の、BMPイメージを表示しない。(ブランクのまま)
→ イメージファイルのオープンが変に、続けて同じファイルを、2回オープンしていて、fptrが1つ多目にインクリメントされてた
せいのようで、これを直して、全ての、BMPイメージの繰返しループ表示と、ファイル名表示が、OKになった。
・残る問題は、SDカードを挿入して、P_ON時の最初のメッセージにゴミが出るのと、SDカード未挿入で、P_ONした時に、最初のメッセージは
良いが、次にカードを挿入した時に、"Find
Card OK!"にゴミが出る。の2点である。
■ 2018.2.4
・昨日の残る問題
@ SD挿入したまま、P_ON時
最初の、"Find Card OK!"に、ゴミ発生。
ただこれは、この状態で、RESET SWを押したときは起こらない。
さらに違う条件でも確認した。
OLED初期化末尾の、OLED_Ciear(BLACK)→ DISPLAY_ONコマンド発行後で止めても、ゴミは出なかった。
(今回より、OLED初期化後に、OLED_Ciear(BLACK)を実施してたのを、OLED初期化関数の、DISPLAY_ONコマンド発行前に
RAMクリア(OLED_Ciear(BLACK))を実施するように変更しました。)
A SD未挿入から、P_ON
挿入待ちメッセージにはゴミは出ない。
SDを挿入すると、"Find Card OK!"にゴミが出る。
■ 2018.2.5
・最初に、どこでこの現象が起きるか確認してみた。
OLED初期化末尾の、OLED_Ciear(BLACK)→ DISPLAY_ONコマンド発行後で止めても、ゴミは出なかったが、
その次に初期メッセージ"START TEST"を表示させた後で止めると、何故かそこにゴミドットが出る。
これは、RESET SWを押しても同じ。
・よく解らなくなって来た。
現象を整理すると、
@ SDカード未挿入で、P_ON時の、初期メッセージにゴミは発生しない。
A SDカード挿入で、P_ON時の、初期メッセージにゴミが発生する。
これは、RESET SWを押しても同じ。
B 初期メッセージは、必要ないので削除した。
SDカード挿入で、P_ON時、"Find Card OK!"にゴミ発生。
ここで、RESET SW押せば、次はゴミ発生しない。
C A、Bの時、メッセージ表示前に、OLED-SPI設定に戻しても、変わらず?
D 設定を戻す方法で解決したのは、SDアクセス後の、OLED表示。
例えば、全画面クリア・BMP表示が全く機能しなかったが、正常になった点である。
■ 2018.2.6
・変にゴミ表示する現象だが、なんとか解決出来た。
力技の部分もあるが・・・
<原因>
・ 根本的な原因は、OLED-SPI(単純ポートによるソフトウエアSPI)と、SD-SPI(ハード:SPI2モジュール)の切替え(元の設定に戻す)
タイミングが、シビアだということが考えられる。
<対策>
・SDアクセスが、なるべく少なくなるようなフローに、ソフトの骨組みを変更し、タイミングのシビアさから逃げる。
その主なものは、
@ カード検知と、FSInitを分けて処理していたのを、FSInit関数を、1回だけ呼んで、その戻り値でカード検知を
判断し、検知と初期化処理を一緒の処理にした。
A そして、カード未検知の場合、OLEDに、その旨のメッセージを、検知するまで点滅表示していたが、これをやると、
SPIモード(ソフトSPI/ハードSPI)の、設定切替えが頻繁に必要になり、ゴミが出てしまっていた。
その逃げとして、LEDの点滅に変更した。
OLEDへのメッセージ表示は、検知・初期化後の、"Find Card OK!"だけにした。
※ これでやっと、ゴミが出なくなった。
やれやれである。
<回路図>
・こちらから、どうぞ→ 「PIC32MX_カラーOLED実験_2」
<最終ソース及びヘッダファイル: SDカード未使用版>
※ Adafruitの、OLEDを使ったプロジェクトのみアップします。
・こちらから、どうぞ→ PIC32MX_OLED_TEST_2.c
///
カラーOLEDライブラリ
SSD1351_OLEDlibPIC32MX.c
SSD1351_OLEDlibPIC32MX.h
///
アスキーフォント・漢字フォント
ASCII_font.h (8x8dot)
KanjiFont12b.h (12x12dot)
///イメージデータ
imagedata.h (狛犬)
imagedata_2.h (百合の花)
--------------------------------------------------------------------------------------------------------
<1回目の更新: SDカード使用版の、プロジェクトファイル一式>
※ 180208 1回目の更新(カードに格納された、 ジャケットイメージ(100x100dot BMP)を読出し、OLEDに表示する追試。
※ 今回は、ファイル数が多いので、プロジェクト一式を、ZIP圧縮して公開します。
この中のOUTPUTフォルダに、HEXファイルが有りますので、ご利用ください。
・こちらから、どうぞ→ PIC32MX_OLED_ImageDisp_UsedSD_TEST