(追記始め)
以前の表示だが,かろうじてI2Cが接続できただけで,やっぱりどうもデータが化けている。いろいろデータの送り方を試行錯誤したが,最終的にはsaharaさんのページで紹介されていたマイクロチップのサポートページのoled.zipをダウンロード。自分の環境に移植することで,うまく動くようになった。
本体メモリーにバッファを持つタイプ。描画スピードとかは少しずつテストしていこう。
やれやれ。ともかく,目標はクリアした。きれい! うれしい!!
ちなみに移植手段としては,saharaさんのページの通り,I2C初期化はMCCのコードに任せ,送信関数部分のレジスターの定義名などをPIC24FV16KM202用に修正しました。
ああ,振り返ってみると,これだけで動いたんだな。でもいい勉強になった。
あ,横5ドットの文字で,5ドットに続けて次の文字が書かれていたので,1ドット余白を作るようにしました。
amazonで買った,SSD1306の128*32です。
MPLAB X IDE v5.25
XC16 (v1.41) でした。
(追記終わり)
当面の目標であったOLEDだが,やっとPIC24FV16KM202で動き始めた。まだめちゃくちゃな表示だけど,うれしい!
参考にさせて頂いたwebページはたくさんあれど,とりあえず以下3つ。
http://www.eonet.ne.jp/~jr3tgs/oled_test.htm
https://neo-sahara.com/wp/2017/11/16/pic24fj64gb002-ssd1306gm009605/
https://tool-lab.com/make/pic-practice-40/
普通にMCCでMSSPを追加,生成された例をよく読んで,必要なコマンドを書いていったつもりだが,どうにも動かない。I2Cに適切に送り出していない。タイムアウトせず,反応待ちで止まっている感じ。
micro:bitでは,あっけなく表示できたので,OLEDの故障ではない。
MSSP1ではなくてMSSP2を使わないとうまくいかないPICもある,ということで試すもダメ。
そこで,上のSaharaさんのページに,こんなことが書いてあった。
「基本的に、I2Cの初期化関連はMCCの吐いたコードに任せ、OLEDとのやり取りは参考にするコードの方をなるべく生かす。」
ということで,基本設定はMCCで行い,I2Cの基本はとっても理解しやすかったJR3TGSさんのページから移植することにした。
ビット定義等を修正しつつ,コンパイルエラーをとにかくなくす。動いた!
以下,MCCとソースの覚書
クロックは最速でOK
MSSP1の設定 High Speedで,Baud Rate Generatorの数字を調整して400kに合わせる。
以下をmain.cに記述。赤字は修正したところ。私の環境の都合で,日本語コメントは削除してコンパイルする必要があります。(冒頭の追記参照 結局これは使わず,別のものから移植しました)
void i2c_start() {
SSP1CON2bits.SEN = 1;
while(SSP1CON2bits.SEN);
}
void i2c_stop() {
SSP1CON2bits.PEN = 1;
while(SSP1CON2bits.PEN);
}
void i2c_write(unsigned char byte) {
IFS1bits.SSP1IF = 0; // レジスタ名をPIC24F用に修正
SSP1BUF = byte;
while(!IFS1bits.SSP1IF);
SSP1CON1bits.CKP = 1;
}
void oled_ini(void) {
i2c_start();
i2c_write(0x78); // OLED slave address
i2c_write(0x00); // Control byte Co=0, D/C#=0
i2c_write(0x8D); // Set charge pump
i2c_write(0x14); // Enable charge pump
i2c_write(0xAF); // Display ON
i2c_stop();
}
void oled_clr(void) {
unsigned int i;
i2c_start();
i2c_write(0x78); // OLED slave address
i2c_write(0x00); // Control byte Co=0, D/C#=0
i2c_write(0x20); // Set memory addressing mode
i2c_write(0x00); // Horizontal addressing mode
i2c_write(0x21); // Set column address
i2c_write(0x00); // Column start address 0
i2c_write(0x7F); // Column end address 127d
i2c_write(0x22); // Set page address
i2c_write(0x00); // Page start address 0
i2c_write(0x03); // Page end address 3d
i2c_stop();
i2c_start();
i2c_write(0x78); // OLED slave address
i2c_write(0x40); // Control byte Co=0, D/C#=1 (The following data bytes are stored at the GDDRAM)
for(i=0; i<512; i++) // 128 column * 4page
i2c_write(0x00); // filled with 0 (OLED clear)
i2c_stop();
}
int main(void)
{
// initialize the device
SYSTEM_Initialize();
oled_ini();
oled_clr();
// sample print A
i2c_start();
i2c_write(0x78);
i2c_write(0x40);
i2c_write(0x7C);
i2c_write(0x12);
i2c_write(0x11);
i2c_write(0x12);
i2c_write(0x7C);
i2c_stop();
while (1) {
_LATA0=(_RA1); // これはテスト用(ボタンを押したらLED消える)
}
return 1;
}
0 件のコメント:
コメントを投稿