/**************************************************************************** * ノキア5110LCD駆動用ライブラリー * * 原典参考先: * @ トラ技2006年3月号 小林さんの記事 * A 「太田さんのホームページ」の記事 * * 2016.11.19 N.Ishii *****************************************************************************/ #include "p24FJ64GA002.h" #include "nokiaGlcdlib.h" #include "ASCII_font.h" /**************************************************************************** * ノキア5110LCDコントロールユニット PCD8544を 初期設定をする *****************************************************************************/ void LCD_init() { // LCD初期設定 SPI_RES = 0; // LCD リセット指令 関数呼び出し delay_us(10); // LCD リセット保持 SPI_RES = 1; // LCD リセット解除 関数呼び出し SPI_DC = 0; // 関数を呼び出してポートをL。他の出力端子は補償される SPI_SCE = 0; // LCD チップイネーブル SPI_CLK = 0; // 初期設定 SPI_tx_byte(0b00100000 | 1, 0); // H = 1 SPI_tx_byte(0b00000100 | 1, 0); // TC = 1 (0-3) SPI_tx_byte(0b00010000 | 3, 0); // Bais = 3 (0-7) // SPI_tx_byte(0b10000000 | 68, 0); // Vop = 68 (0-127) コントラスト設定 SPI_tx_byte(0b10000000 | 74, 0); // 68では薄いので、74に変更 161118 SPI_tx_byte(0b00100000 | 0, 0); // H = 0, Horizontal addressing SPI_tx_byte(0b00001000 | 4, 0); // Display Mode Normal = 4 SPI_tx_byte(0b01000000 | 0, 0); // Set Y = 0 (0-5) SPI_tx_byte(0b10000000 | 0, 0); // Set X = 0 (0-83) } /**************************************************************************** * LCDの書き込み位置を X、Y に設定する *---------------------------------------------------------------------------- * 入力: unsigned char x,unsigned char y * 出力: 無し *---------------------------------------------------------------------------- * 備考: 0 <= x <= 83, 0 <= y <= 5 * ただし y は右上から下方向 LSBが最小値の8ビット単位 * ノキアLCDのグラフは、左上が原点。 *****************************************************************************/ void LCD_locate(unsigned char x,unsigned char y) { SPI_tx_byte(0b01000000 | y, 0); // Set Y = y SPI_tx_byte(0b10000000 | x, 0); // Set X = x } /**************************************************************************** * 現在の書き込み位置から指定バイトのデータ列を書込む *---------------------------------------------------------------------------- * 入力: unsigned char *datap,int len * 出力: 無し *---------------------------------------------------------------------------- * 備考: このコマンドはlenの回数分x位置を増やしながら横へ * 1バンク分指定されたバイトデータを書き込む *****************************************************************************/ void LCD_set_data(unsigned char *datap,int len) { for (;len>0;len--) SPI_tx_byte(*(datap++), 1); } /**************************************************************************** * 現在の書き込み位置から指定バイトの表示クリア *---------------------------------------------------------------------------- * 入力: unsigned int len * 出力: 無し *---------------------------------------------------------------------------- * 備考: このコマンドはlenの回数分x位置を増やしながら横へ * 1バンク分クリアする *****************************************************************************/ void LCD_clear(unsigned int len) { for (;len>0;len--) SPI_tx_byte(0, 1); } /**************************************************************************** * Data/Command を指定して、LCDに1バイトを送信 *---------------------------------------------------------------------------- * 入力: unsigned char d,int dc * 出力: 無し *---------------------------------------------------------------------------- * 備考: dc = 0 : Command, dc = 1 : Data *****************************************************************************/ void SPI_tx_byte(unsigned char d,int dc) { char Loop; SPI_SCE = 0; if (dc) { SPI_DC = 1; } else { SPI_DC = 0; } for (Loop=0;Loop<8;Loop++){ SPI_DATA = 0; if ((d & (unsigned char)0x80) != 0){ SPI_DATA = 1; } delay_us(3); SPI_CLK = 1; d <<= 1; delay_us(6); SPI_CLK = 0; } SPI_SCE = 1; } /********************************* * G-LCDに一文字表示する * 追加関数:N.Ishii **********************************/ void LCD_char (unsigned char dat){ unsigned char i,chptn; dat -= 0x20; //配列アドレスを計算→ フォントテーブルのトップ[0][5]からスペースコードの20hが格納されている。追記:N.Ishii for(i=0; i<5; i++) { //コラムデータを順に取得して、DDRAMに転送 chptn = chrom[dat][i]; SPI_tx_byte(chptn, 1); //コラムデータを転送 } SPI_tx_byte(0, 1); //文字間隔を空ける } /**************************** * Rom 文字列出力 * 追加関数:N.Ishii *****************************/ void LCD_ROMstr(const char *str){ while(*str) //文字列終端(00)まで継続 LCD_char(*str++); //文字出力しポインタ+1 } /********************************************************************************** * ノキア5110LCDの (x, y)ピクセル座標に点を描画する。 *---------------------------------------------------------------------------------- * 入力: int x, int y * 出力: 無し *---------------------------------------------------------------------------------- * 備考: Y軸は、下側が最小、上側が最大(ノキアLCDのY軸を反転して表示する)。 * 0 <= x <= 83 , 0 <= y <= 47 最大地、最小値を超えている * 場合は、範囲内にクランプされる。 ***********************************************************************************/ void draw_point(int x, int y) { int bank_y; unsigned char pat_y; if (y < 0) { bank_y = LCD_MAX_BANK; // Yの値が負ならば、グラフの最小値にクランプしてプロットする。 pat_y = 0b10000000; // LCDの最大側(下側)を数値の最小とするため、MSBが最小値側。 } else if (y > LCD_MAX_Y) { bank_y = 0; // Yの値が最大値を超えているならば、グラ最大値にクランプしてプロットする。 pat_y = 0b00000001; // LCDの最小側(上側)を数値の最大とするため、LSBが最大値側。 } else { bank_y = LCD_MAX_BANK - (y / 8); // y軸反転位置にバンクを決定 pat_y = 0b10000000 >> (y % 8); // バンク内のMSB側を最小値とすることでY軸表現が下側が0となる } LCD_locate(x, bank_y); // x位置のバンクy LCD_set_data(&pat_y, 1); // バンクyへ8ビットパターンを書き込む } /**************************************************************************** * usec単位ディレイ関数 *---------------------------------------------------------------------------- * 入力: 符号無し16ビット整数 * 出力: 無し *---------------------------------------------------------------------------- * 備考: CLOCK:MIPS of this PIC ******************************************************************************/ //void delay_us(unsigned char usec){ void delay_us(int usec){ // usec = (unsigned char)(CLOCK*usec)/ 10; usec = (int)(CLOCK*usec)/ 10; while(usec) { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); usec--; } } /**************************************************************************** * msec単位ディレイ関数 *---------------------------------------------------------------------------- * 入力: 符号無し16ビット整数 * 出力: 無し *---------------------------------------------------------------------------- * 備考: ******************************************************************************/ //void delay_ms(unsigned char msec){ void delay_ms(int msec){ // unsigned char i; int i; for(i=0; i< msec; i++) delay_us(1000); }