「Raspberry PI 3でサインスマート 1.8″ LCDの表示」でRaspberry PI 3によりLCDへドットを表示できることは確認しました。「EUC-JPコードを用いた美咲フォントへのアクセス方法 」で美咲フォントのフォントパターンが取得できることを確認しました。今回はこの二つの事例を組み合わせて、Raspberry PI 3でサインスマート 1.8″ LCDに文字を表示します。
サインスマート 1.8″ LCDの文字表示プログラムの作成
chardisplay関数を新規に作成し、行/カラム、表示する文字コード(漢字コード)をパラメータにして呼び出します。プログラムの漢字コードはEUC-JPを使用し、これを区点コードに148行目から151行目で変換しています。
#include <stdint.h> #include <unistd.h> #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <getopt.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/types.h> #include <linux/spi/spidev.h> #include <wiringPi.h> #define RSpin 5 // レジスタ選択ピン指定 #define REpin 6 // リセット信号ピン指定 #define LCD_BF 4096 // 1度に転送するデータ数(最大4096) int LCD_Cmd(unsigned char,int,...); void SetDot(int x, int y, int color); void chardisplay(int column, int row, char* text, int color); static uint8_t SPIMode = 0,SPIbit=8; //SPIモード0 bit数8 static uint32_t SPISpeed =60000000; // 32MHz // SPIデバイス定義 // # ls -l /dev/spidev* で確認できる。 // Pi2の場合CE1に接続した場合は0.0 // CE2に接続した場合は0.1 だった。 static char *SPIDevice = "/dev/spidev0.0"; int fd,ret=0; char font_path[] = "code/misaki_gothic_lcd.bmp"; //フォントファイルパス unsigned char bhd[62],FontData[94][96]; //unsigned char bhd[62],FontData[500][500]; unsigned char BMPData[0xf000/LCD_BF][LCD_BF]; int main(int argc,char *argv[]){ int column,row; // wiringPi初期化 if(wiringPiSetup()==-1) printf("wiringPi error\n"); // wiringPi初期化エラー // ピンの初期化 pinMode(RSpin,OUTPUT); pinMode(REpin,OUTPUT); // 液晶リセット信号送信 digitalWrite(REpin,0); delay(100); digitalWrite(REpin,1); delay(100); // SPIデバイスの初期化 fd = open(SPIDevice,O_RDWR);if(fd<0) printf("SPI Device error\n"); //SPI デバイス初期化エラー ret = ioctl(fd,SPI_IOC_WR_MODE,&SPIMode);if(ret <0) printf("SPI Mode error\n"); //SPI Mode設定エラー ret =ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&SPIbit);if(ret <0) printf("SPI bit/Word error\n");//SPI bit/Word設定エラー ret =ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&SPISpeed);if(ret <0) printf("SPI Speed error\n"); //SPI Speed設定エラー LCD_init(); // 液晶描画方向設定 LCD_Cmd(0x36,1,0xC0); // 縦長 0x48 横長0x28 // 描画エリア設定 0~BMPのサイズ LCD_Cmd(0x2A,4,0x00,0x00,0x00,128); LCD_Cmd(0x2B,4,0x00,0x00,0x00,160); LCD_Cmd(0x3A,1,0x06); //色深度設定 16bit=0x05 18bit=0x06 // 表示RAM転送モードに設定 CmdSend(0x2C); int i,k, x, y; long color= 0xff0000; for(i=0; i<0xf000/LCD_BF ;i+=1) { for(k=0; k<LCD_BF; k+=1) { BMPData[i][k] = 0x00; } DataSend(LCD_BF,BMPData[i]); } FILE *bmpr; char buf[1]; bmpr=fopen(font_path,"rb"); fread(bhd,1,62,bmpr); fread(FontData,1,96*94,bmpr); fclose(bmpr); unsigned char *SText1 = "TomoSoft"; unsigned char *SText2 = "ソフトウェアエンジニア"; color = 0xff0000; column=5; row = 0; chardisplay( column, row, SText1, color); color = 0xff00FF; column=3; row = 1; chardisplay( column, row, SText2, color); for(i=0; i<0xf000/LCD_BF ;i+=1) { DataSend(LCD_BF,BMPData[i]); } close(fd); // SPIデバイス開放 return 0; } void chardisplay(int column, int row, char* text, int color) { int x,y,k,charcount; int pat; char buf[1]; unsigned int ku,ten; unsigned int word; charcount = 0; while(1){ if((text[charcount]) == 0) break; word = (unsigned int)((text[charcount+1])<<8); word |= text[charcount]; printf("%x %x %x\n",text[charcount],text[charcount+1],word); ku = (word & 0xff)-0xA0-1;//数字1 ten = (word>>8)-0xA0-1; x=(column+(charcount/2))*8; y=row*8; for(k=0; k<8 ;k+=1) { buf[0]=FontData[(8*ku)+k][ten]; int i = 0; pat=0x80; while(pat>0) { if((buf[0]&pat)==0) SetDot( x+i, y +k, color); pat>>=1; i++; } } charcount+=2; } } void SetDot(int x, int y, int color) { int pos = (x+(y*128))*3; BMPData[pos/LCD_BF][(pos%LCD_BF)] = (color & 0xff0000)>>16; BMPData[pos/LCD_BF][(pos%LCD_BF)+1] = (color & 0xff00)>>8; BMPData[pos/LCD_BF][(pos%LCD_BF)+2] = color & 0xff; } // LCDへのコマンド転送 // LCD_Cmd(コマンド,設定値サイズ(Byte),設定値(カンマ区切り)); int LCD_Cmd(unsigned char TrCmd,int TrByte, ...){ int dti=0; unsigned char TrData[TrByte]; va_list dt; va_start(dt,TrByte); for(dti=0;dti<TrByte;dti++)TrData[dti]=va_arg(dt,int); va_end(dt); CmdSend(TrCmd); if(TrByte > 0)DataSend(TrByte,TrData); } // LCDへのデータ転送 // TrByte=転送データサイズ // TrData=転送するデータ // 8bit値 うまく転送できない場合はchar型の変数を渡すとうまくいく。 int DataSend(int TrByte,unsigned char TrData[]){ digitalWrite(RSpin,1); // RS信号切替 uint8_t ReData[TrByte];//受信用変数 // 転送するデータの準備 struct spi_ioc_transfer tr={ .tx_buf =(unsigned long)TrData, .rx_buf =(unsigned long)ReData, .len = TrByte, .delay_usecs = 1, .speed_hz = SPISpeed, .bits_per_word= SPIbit, }; // 転送 ret =ioctl(fd,SPI_IOC_MESSAGE(1),&tr); if(ret<1)printf("SPI 転送エラー(Data)\n"); int i=0; return ret; // 受信データサイズを返す } // コマンド転送 int CmdSend(unsigned long TrData){ digitalWrite(RSpin,0); // RS信号切替 uint8_t ReData; //受信用変数 // 転送するデータの準備 struct spi_ioc_transfer tr={ .tx_buf =(unsigned long)&TrData, .rx_buf =(unsigned long)&ReData, .len = 1, .delay_usecs = 1, .speed_hz = SPISpeed, .bits_per_word= SPIbit, }; // 転送 ret =ioctl(fd,SPI_IOC_MESSAGE(1),&tr); if(ret<1)printf("SPI 転送エラー(Com)\n"); return ReData; // 受信データを返す } int LCD_init(void){ // 液晶リセット信号送信 digitalWrite(REpin,0); delay(1); digitalWrite(REpin,1); delay(1); //液晶初期化コマンド送信 CmdSend(0x01); // ソフトリセット delay(15); CmdSend(0x11); // スリープ解除 delay(10); // フレームレート設定 LCD_Cmd(0xB1,3,0x01,0x2C,0x2D); LCD_Cmd(0xB2,3,0x01,0x2C,0x2D); LCD_Cmd(0xB3,6,0x01,0x2C,0x2D,0x01,0x2C,0x2D); // 液晶反転設定 LCD_Cmd(0xB4,1,0x07); // 電源設定(PWCTR1~3) LCD_Cmd(0xC0,3,0xA2,0x02,0x84); LCD_Cmd(0xC1,1,0xC5); LCD_Cmd(0xC2,2,0x0A,0x00); LCD_Cmd(0xC3,2,0x8A,0x2A); LCD_Cmd(0xC4,2,0x8A,0xEE); LCD_Cmd(0xC5,1,0x0E); CmdSend(0x20); // ガンマ設定 LCD_Cmd(0xE0,16,0x0F,0x1A,0x0F,0x18,0x2F,0x28,0x20,0x22,0x1F,0x1B,0x23,0x37,0x00,0x07,0x02,0x10); LCD_Cmd(0xE1,16,0x0F,0x1B,0x0F,0x17,0x33,0x2C,0x29,0x2E,0x30,0x30,0x39,0x3F,0x00,0x07,0x03,0x10); CmdSend(0x29); CmdSend(0x13); }
コンパイル・リンクは次のコマンドで実行します。
# gcc -o lcdchar lcdchar.c -lwiringPi
サインスマート 1.8″ LCDの文字表示プログラムの実行
作成したプログラムを次のコマンドで実行します。
# sudo ./lcdchar
実行した結果を次に示します。「TomoSoft」次に「ソフトウェアエンジニア」が文字の色を変えて表示されています。