/******************************************************** * カラーグラフィックLCD(132x132ドット)用ライブラリ * コントロール・デバイス:Philips PCF8833 * * lcd_Init(); // 初期化 * lcd_Clear(); // 全画面消去 * lcd_Pixel(); // 1ドット表示 * lcd_Char(); // ANK文字表示 * lcd_Str(); // ANK文字列表示 * lcd_Line(); // 直線描画 * lcd_Image(); // イメージ図表示 * lcd_Scroll(); // 画面スクロール * * デバッグ年月日: 2012/12/4 N.Ishii *********************************************************/ #include /* PIC32 peripheral library */ #include "ColorLCD_Lib_PCF8833.h" #include "font.h" // ANK文字 5x7ドット #include "KanjiFont12b.h" // 漢字文字フォント 12x12ドット /******************************** * コマンド、データ出力関数 *********************************/ void lcd_cmd(unsigned char cmnd){ unsigned char i, Mask; LCD_CS = 0; // CS Low LCD_SCK = 0; LCD_DIO = 0; // 9th bit Command LCD_SCK = 1; // Min 25ns Mask = 0x80; // 上位ビットから for(i=0; i<8; i++){ // 8ビット繰り返し LCD_SCK = 0; if((cmnd & Mask) != 0) LCD_DIO = 1; // Bit 1 else LCD_DIO = 0; // Bit 0 LCD_SCK = 1; // Min 25ns Clock Mask = Mask >> 1; } LCD_CS = 1; // CS High } void lcd_data(unsigned char data){ unsigned char i, Mask; LCD_CS = 0; // CS Low LCD_SCK = 0; LCD_DIO = 1; // 9th bit Data LCD_SCK = 1; // Min 25ns Clock Mask = 0x80; // 上位ビットから for(i=0; i<8; i++){ // 8ビット繰り返し LCD_SCK = 0; if((data & Mask) != 0) LCD_DIO = 1; // Bit 1 else LCD_DIO = 0; // Bit 0 LCD_SCK = 1; // Min 25ns Clock Mask = Mask >> 1; } LCD_CS = 1; // CS High } /**************************** * LCD初期化関数 *****************************/ void lcd_Init(void){ delay_ms(10); LCD_RESET = 1; // Clear RESET delay_ms(10); // 10msec wait lcd_cmd(SLPOUT); // スリープウェイクアップ lcd_cmd(INVON); lcd_cmd(COLMOD); // ピクセル・フォーマット lcd_data(0x03); // 12bit/1dot(2dotを、3byteで送る、EPSONのTYPE-Aに相当) lcd_cmd(MADCTL); // メモリ・データ・アクセス制御 // lcd_data(0x08); lcd_data(0xC0); // mirror x and y, reverse rgb 121201 lcd_cmd(SETCON); // コントラスト設定 lcd_data(0x30); delay_ms(100); lcd_cmd(DISPON); // 表示オン } /*************************** * 画面消去関数 * 消去用色指定あり ****************************/ void lcd_Clear(unsigned short Color){ short i; lcd_cmd(PASET); // ページ開始終了アドレスセット lcd_data(0); lcd_data(ENDPAGE-1); // =131 lcd_cmd(CASET); // コラム開始、終了アドレスセット lcd_data(0); lcd_data(ENDCOL-1); // =131 lcd_cmd(RAMWR); for(i=0; i<132*66; i++){ // 2ドット連続書き込みを繰り返す lcd_data((Color>>4)&0x00FF); lcd_data(((Color&0x000F)<<4)|(Color>>8)); // lcd_data(((Color&0x000F)<<4)|((Color>>8)&0x000F)); // 121201 lcd_data(Color & 0x00FF); } } /* /// 4096色TYPE-B対応: Sim's blog方式 void lcd_Clear(unsigned short Color){ short i; lcd_cmd(PASET); // ページ開始終了アドレスセット lcd_data(0); lcd_data(ENDPAGE-1); // =131 lcd_cmd(CASET); // コラム開始、終了アドレスセット lcd_data(0); lcd_data(ENDCOL-1); // =131 lcd_cmd(RAMWR); for(i=0; i<132*132; i++){ // 1ドットにつき、2バイト連続書き込みを繰り返す lcd_data(Color >> 8); lcd_data(Color); } } */ /*********************************** * 1ピクセル表示関数 * 座標は(0,0)-(131,131) ***********************************/ void lcd_Pixel(short Xpos, short Ypos, unsigned short Color){ /* if page>131 or colum >131 then do nothing */ if((Xpos>4)&0x00FF); // 2ドット分の色指定 lcd_data(((Color&0x000F)<<4) | (Color>>8)); //lcd_data(((Color&0x000F)<<4)|((Color>>8)&0x000F)); // 121201 lcd_data(Color & 0xFF); // 2ドット同色 } } /*************************** * 直線描画関数 ***************************/ #define abs(a) (((a)>0) ? (a) : -(a)) void lcd_Line(short x0, short y0, short x1, short y1, unsigned short Color) { short steep, t; short deltax, deltay, error; short x, y; short ystep; y0=131-y0; y1=131-y1; /// 差分の大きいほうを求める steep = (abs(y1 - y0) > abs(x1 - x0)); /// x、yの入れ替え if(steep){ t = x0; x0 = y0; y0 = t; t = x1; x1 = y1; y1 = t; } if(x0 > x1) { t = x0; x0 = x1; x1 = t; t = y0; y0 = y1; y1 = t; } deltax = x1 - x0; // 傾き計算 deltay = abs(y1 - y0); error = 0; y = y0; /// 傾きでステップの正負を切り替え if(y0 < y1) ystep = 1; else ystep = -1; /// 直線を点で描画 for(x=x0; x= deltax) { y += ystep; error -= deltax; } } } /***************************************** * ANK文字表示関数 8x8ドット * 132/8=16文字/行 132/8=16行 * (0, 0) - (15, 15)の範囲 ******************************************/ void lcd_Char(char line, char colum, unsigned char letter, unsigned short Color1, unsigned short Color2){ unsigned char j, i, Mask; unsigned short pos; if((colum < 16) && (line < 16)){ // 範囲チェック for(j=0; j<5; j++){ // 横5ドット Mask = 0x80; // 上位ビットから表示 for(i=0; i<8; i++){ // 縦1ライン分表示 if((Font[letter-0x20][j] & Mask) != 0) lcd_Pixel(colum*8+j+4, (line+1)*8-i+1, Color1); else lcd_Pixel(colum*8+j+4, (line+1)*8-i+1, Color2); //背景色 Mask = Mask >> 1; } } for(j=5; j<8; j++){ lcd_Pixel(colum*8+j+4, (line+1)*8-i+1, Color2); //背景色 } } } /****************************** * 文字列描画関数 * 16文字x16行で指定 ******************************/ void lcd_Str(char line, char colum, unsigned char *s, unsigned short Color1, unsigned short Color2) { while (*s){ lcd_Char(line, colum++, *s++, Color1, Color2); if(colum > 15){ line++; colum = 0; if(line > 15) line = 0; } } } /************************************************** * 漢字文字表示関数 13x13ドット *  132/13=10文字×10行 *  フォントは12x12 * 漢字コードの範囲をチェックし異常なら-1を返す ***************************************************/ short lcd_Kanji(char line, char colum, unsigned char *ptr, unsigned short Color1, unsigned short Color2) { short low, high; high = *ptr++; low = *ptr; // 漢字範囲チェックと表示 if(((high > 0x80) && (high < 0xA0)) || ((high > 0xDF) && (high < 0xEB))) { if((low > 0x3F) && (low < 0xFD) && (low != 0x7F)) { KanjiCode(line, colum, high, low, Color1, Color2); // 漢字表示制御 return(0); // 正常戻り } else return(-1); // エラー戻り } else return(-1); } /************************************* * 漢字表示 コード指定で表示 *  2バイトコードで指定 * 表示位置は10文字/10行で指定 **************************************/ void KanjiCode(char line, char colum, short upcode, short lowcode, unsigned short Color1, unsigned short Color2) { short upper, lower, i, j, pos; unsigned char Mask; if((line < 10) && (colum < 10)){ // 画面内か? // 漢字コードから配列インデックス計算 upper = (upcode -0x81)*188; // xxFC-xx40+1-1(7F分) if(lowcode < 0x7F) // コード7Fはスキップ lower = (lowcode - 0x40); else lower = (lowcode - 0x41); // 7Fコードの1文字分を引く // 漢字表示出力 3バイトの2ラインずつを6回繰り返す for(j=0; j<6; j++){ // 8ドット連続部の表示 Mask = 0x80; for(i=0; i<8; i++){ // 1ライン目前半8ドット表示 if((KanjiFont12b[upper+lower][j*3] & Mask) != 0) lcd_Pixel(colum*13+i+3, line*13+j*2, Color1); else lcd_Pixel(colum*13+i+3, line*13+j*2, Color2); //背景色 // 2ライン目後半8ドット表示 if((KanjiFont12b[upper+lower][j*3+2] & Mask) != 0) lcd_Pixel(colum*13+i+7, line*13+j*2+1, Color1); else lcd_Pixel(colum*13+i+7, line*13+j*2+1, Color2); //背景色 Mask = Mask >> 1; } // 分割部4ドットずつ表示 Mask = 0x80; // 1ライン目後半4ドット表示 for(i=0; i<4; i++){ if((KanjiFont12b[upper+lower][j*3+1] & Mask) != 0) lcd_Pixel(colum*13+i+11, line*13+j*2, Color1); else lcd_Pixel(colum*13+i+11, line*13+j*2, Color2); //背景色 Mask = Mask >> 1; } // 2ライン目前半4ドット表示 for(i=4; i<8; i++){ if((KanjiFont12b[upper+lower][j*3+1] & Mask) != 0) lcd_Pixel(colum*13+i-1, line*13+j*2+1, Color1); else lcd_Pixel(colum*13+i-1, line*13+j*2+1, Color2); //背景色 Mask = Mask >> 1; } } } } /********************************************************* * 漢字文字列表示 * 10文字×10行で指定 *********************************************************/ void Kanji_Str(char line, char colum, const short* ptr, unsigned short Color1, unsigned short Color2) { while(*ptr){ if((line < 10) && (colum < 10)){ // 画面内か? KanjiCode(line, colum++, (short)*ptr++, (short)*ptr++, Color1, Color2); if(colum > 9){ line++; colum = 0; if(line > 9) line = 0; } } } } /********************************************************* * イメージ表示関数 *  データは縦方向8ライン分が1バイトで格納されている * 128×128/8=2kバイト/画面 * グラフィック色(Color1)と背景色(Color2)両方を指定 **********************************************************/ void lcd_Image(char line, const unsigned char *ptr, unsigned short Color1, unsigned short Color2) { unsigned char Mask; short i, vline, colum; for(vline=line; vline