/****************************************************************************** * グラフィックLCD(128x64ドット)用ライブラリ * lcd_Write(); * lcd_Read(); * lcd_Init(); * lcd_Clear(); * lcd_Pixel(); * lcd_Char(); * lcd_Char1(); * lcd_Str(); * lcd_Line(); * lcd_Image(); * Delay1m(); * * 140322 * lcd_Write/Read関数に、waitマージン追加修正 * 170502 * PIC16F1938用に改修 * 190815:_v2に更新 * 直線描画関数に、ドットを黒(通常)にするか、白(消去)にするかの引数:On追加 ********************************************************************************/ #include #include "glcd_PIC16F_lib_v2.h" //#include "font.h" #include "font_add_note.h" // 190904 /*************************** * データ出力関数 ***************************/ void lcd_Write(char cs, char code, char DIflag){ int data; LCD_RW = 0; // write mode if(cs==1) LCD_CS1 = 0; else LCD_CS2 = 0; data = (int)code; LCD_DB = data; if (DIflag == 0) LCD_DI = 1; // 表示データの場合 else LCD_DI = 0; // コマンドデータの場合 __delay_us(1); // 1usec LCD_E = 1; // strobe out __delay_us(1); // pulse width 1usec LCD_E = 0; // reset strobe __delay_us(3); // これが無いと、GLCDの、Tahのバラツキ(規格は、Tah=10nSmin)で、正常に // 書込めない、GLCDがある。後閑氏のソースには、このウエイトが無かったが、 // 最初買ったGLCDは、それでも正常動作していた。    追加:140322 LCD_CS1 = 1; LCD_CS2 = 1; LCD_RW = 1; __delay_us(5); } /***************************** * データ読み出し関数 *****************************/ char lcd_Read(char cs){ unsigned char data; LCD_TRIS = 0xFF; // chane to input mode LCD_RW = 1; // set read mode if(cs==1) // CS1 or CS2? LCD_CS1 = 0; else LCD_CS2 = 0; LCD_DI = 1; // set data mode __delay_us(1); // 1usec delay LCD_E = 1; // strobe out __delay_us(1); // pulse width 1usec LCD_E = 0; // reset strobe // __delay_us(3); // wait 3usec __delay_us(5); // 後閑氏のウエイト設定値:3uは、規格のウエイト値(Tddr=320n(min))は満足しているが、GLCDのバラツキ // で、正しく読み出せないGLCDもあることを確認した。そこで5uに増やし正常読込を確認した。 // ここが正しく読み出せないと、トット描画の時、ドットが途切れたり、余計なところにドット描画したりする // 現象が起きる。 // 尚、最初買ったGLCD(2011/4購入)は、3uでも正常に読込動作していた。   140322 data = LCD_DB; // input data __delay_us(1); // wait 1usec LCD_CS1 = 1; // reset CS LCD_CS2 = 1; LCD_TRIS = 0x00; // back to output mode return data; // return cuurrent status } /*************************** * 画面消去関数 ****************************/ void lcd_Clear(char data){ char page, colum; for(page=0; page<8; page++){ // repeat 8 page lcd_Write(1, 0xB8+page, 1); // page set lcd_Write(1, 0x40, 1); // colum reset lcd_Write(2, 0xB8+page, 1); // page set lcd_Write(2, 0x40, 1); // colum reset for(colum=0; colum<64; colum++){ // repeat 64 colum lcd_Write(1, data, 0); // fill data lcd_Write(2, data, 0); // fill data } } lcd_Write(1, 0xC0, 1); // reset start line lcd_Write(2, 0xC0, 1); } /**************************** * 初期化関数 *****************************/ void lcd_Init(void){ __delay_ms(10); lcd_Write(1, 0x3F, 1); // Display on lcd_Write(2, 0x3F, 1); // Display on lcd_Clear(0); } /**************************** * Draw Piccel Function * 座標は(0,0)-(127,63) *****************************/ void lcd_Pixel(int Xpos, int Ypos, char On){ char cs, data, page, pos, count, i; /* if colum >127 then do nothing */ if(Xpos<128){ if(Xpos>63){ // 64=0) ? (a) : -(a)) void lcd_Line(int x0, int y0, int x1, int y1, char On) { int steep, t; int deltax, deltay, error; int x, y; int ystep; /// 差分の大きいほうを求める 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; /// 直線を点で描画 /// On=1:黒描画(通常)・On=0:白描画(消去) for(x=x0; x= deltax) { y += ystep; error -= deltax; } } } /************************* * 文字表示関数 * (0, 0) - (7, 15) **************************/ void lcd_Char(char line, char colum, int letter){ char cs, i; int pos; if(colum < 16){ if(colum > 7){ pos = (colum- 8) * 8; cs = 1; } else{ pos = colum * 8; cs = 2; } lcd_Write(cs, 0xB8+line, 1); // set page lcd_Write(cs, 0x40+pos, 1); // set colum for(i=0; i<5; i++) lcd_Write(cs, Font[letter-0x20][i], 0); lcd_Write(cs, 0, 0); lcd_Write(cs, 0, 0); lcd_Write(cs, 0, 0); } } /************************* * 文字表示関数2 7x8 * (0, 0) - (7, 17) **************************/ void lcd_Char1(char line, char colum, int letter){ char cs, i; int pos; if(colum < 18){ if(colum > 8){ pos = (colum- 9) * 7; cs = 1; } else{ pos = colum * 7; cs = 2; } lcd_Write(cs, 0xB8+line, 1); // set page lcd_Write(cs, 0x40+pos, 1); // set colum for(i=0; i<5; i++) lcd_Write(cs, Font[letter-0x20][i], 0); lcd_Write(cs, 0, 0); lcd_Write(cs, 0, 0); } } /****************************** * 文字列描画関数 ******************************/ void lcd_Str(char line, char colum, char *s) { while (*s) lcd_Char1(line, colum++, *s++); } /***************************** * イメージ表示関数 *****************************/ void lcd_Image(char *ptr) { char cs, Xpos; int page, colum; for(page=0; page<8; page++){ for(colum=0; colum<128; colum++){ if(colum > 63){ Xpos=colum-64; cs = 1; } else{ Xpos = colum; cs = 2; } lcd_Write(cs, 0xB8+page, 1); lcd_Write(cs, 0x40+Xpos, 1); lcd_Write(cs, *ptr++, 0); } } } /********************************* * スクロール関数 ***********************************/ void lcd_Scroll(int delay){ int i; for(i=0; i<64; i++){ lcd_Write(1, 0xC0+i,1); lcd_Write(2, 0xC0+i,1); Delay1m(delay); } } /******************************* * 遅延関数 ********************************/ /// 1msec Delay SubFunction ///(タイム変数の引数付き:XC8の遅延関数は、引数は定数のみしか扱えないので別途用意:170428) void Delay1m(int time){ while(time > 0){ __delay_us(1000); time--; } }