OLED試す、続きです。文字列を表示するようにするのに、ちょっと考えたので書きます。と言っても真新しいことは何もないですが、自分の備忘録ということで。
文字を表示するために、ピクセルの構造の理解が必要です。128x32の表示領域ですが、32ピクセル方向を縦方向とすると縦は8ビットごとにページに分割されておりますので、横128ピクセルx縦4ページということになります。横方向はピクセルで指定できるが縦方向はページの指定しかできない。ピクセルで指定して文字を表示しようとすると、ページのどの位置かを計算する必要があり文字を上下に分けてオフセットなど、ちょっと面倒です。なので、横方向の開始位置はピクセルで指定できるが縦方向はページの開始でのみ指定するような作りにしました。(ページをまたがるような表示はできいない)
キャラクタ液晶でないので、フォントをプログラム上に持つ必要があります。適当なフォントを拾ってきて組み込めばいいやって思ったのですが、なかなか見つからない。探しかたもよくないのか知れないが、いいのが見つけられなかった。そこで、GLCD FontCreater(ブログ記事https://cycle.eek.jp/blogs/ee9king/245)を使って作りました。
システムフォントを元に上記エディタで手修正をかなり加えて見やすくしたものと、縦2ページ分使って大きくしたPrototypeフォントを貼っておきます。どちらも、const unasigned char宣言のヘッダファイルにしてます。(32~127のキャラクタのみ)。Prototypeのほうも、かなり手修正しました。ほとんど作ったといっても良いぐらい。
縦が1ページに収まる(縦が8ドット)のフォントは、下記で表示します。lcd_puts("文字列")で表示(漢字は出ませんよ!)
void lcd_puts(const char *s){
i2c_start(LCD_ADDR,I2C_RW_WRITE);
i2c_send(DC_BIT);
while(*s)
lcd_putc( *s++ );
i2c_stop();
}
void lcd_putc(unsigned char c){
int offset=0;
if( (c<32) || (c>127) ) return;
c=c-32;
offset = c * 6;
i2c_send(font1[offset++]);
i2c_send(font1[offset++]);
i2c_send(font1[offset++]);
i2c_send(font1[offset++]);
i2c_send(font1[offset++]);
i2c_send(font1[offset++]);
}
FONT1[]構成は、縦8x横6ピクセル構成で、ファイル1文字=6Byte、8bitづつ横6個並んでいる構成のため、配列のオフセットを増やしながら6回送信すれば表示されます。フラッシュROMサイズは96文字x6=576バイト占有します。
で、問題の2ページまたがる文字ですが、1文字を表示するのにページ指定を2回しなければいけない関係で、文字列表示ではなく、1文字づつ表示する関数にしました。今回は数字を表示するので、特に文字列表示の必要性もなかった。
void lcd_putc2(unsigned char c,int col,int page){
int offset=0;
int i;
if( (c<32) || (c>127) ) return;
c=c-32;
offset = c * 25;
offset++; // 1byte目は実サイズ幅が入っているので飛ばす。
i2c_start(LCD_ADDR,I2C_RW_WRITE);
i2c_send(0x00);
i2c_send(SET_COLUMN_ADDR);
i2c_send((unsigned char)col);
i2c_send(127);
i2c_send(SET_PAGE_ADDR);
i2c_send((unsigned char)page++);
i2c_send((unsigned char)page);
i2c_stop();
i2c_start(LCD_ADDR,I2C_RW_WRITE);
i2c_send(DC_BIT);
for(i=0;i<24;i=i+2){
i2c_send(font2[offset+i]);
}
i2c_stop();
i2c_start(LCD_ADDR,I2C_RW_WRITE);
i2c_send(0x00);
i2c_send(SET_COLUMN_ADDR);
i2c_send((unsigned char)col);
i2c_send(127);
i2c_send(SET_PAGE_ADDR);
i2c_send((unsigned char)page++);
i2c_send((unsigned char)page);
i2c_stop();
i2c_start(LCD_ADDR,I2C_RW_WRITE);
i2c_send(DC_BIT);
offset = c * 25 + 2;
for(i=0;i<24;i=i+2){
i2c_send(font2[offset+i]);
}
i2c_stop();
}
FONT2[]は縦16ドット横12ドットの構成で、1文字は25バイトで構成されます。先頭の1バイトは文字の横実サイズを示しますが、これは無視します(GLCD Createrの出力がそうなっています。これを利用すればプロポーショナルな表示ができるが、今回は不要)。ヘッダファイル構成は、0上、0下、1上、1下、2・・・・のように並んでいるので、奇数データが上のページ、偶数ページが下のページの構成になります。上のページを描画したら下のページに移動して下のページを描画、というソースになっております。1文字25バイトですので、2400バイト占有します。
ロゴの表示(画像)
画像は作ったものを表示させます。作る際に、ページごとに横方向に並び、余りが出ないような構成(横32ドットx縦32ドット=4ページ)としました。SET_HORIZONTALモードで開始位置とサイズを指定しておくと、横方向に準場に送信するだけで所望の絵が送信できます。
void disp_logo(int col,int page){
int i;
i2c_start(LCD_ADDR,I2C_RW_WRITE);
i2c_send(0x00);
i2c_send(SET_COLUMN_ADDR);
i2c_send((unsigned char)col);
i2c_send((unsigned char)col+31);
i2c_send(SET_PAGE_ADDR);
i2c_send((unsigned char)page);
i2c_send( 3 );
i2c_stop();
i2c_start(LCD_ADDR,I2C_RW_WRITE);
i2c_send(DC_BIT);
for(i=0;i<128;i++){
i2c_send( logo[i] );
}
i2c_stop();
}
ロゴのデータを作るのにエクセルもどきのLibreOfficeを活用しました。
コメントを追加