//---------------------------------------------------------------------------
// Project: ノキア5110LCD駆動用 液晶表示器制御
// Language: Wiz-C,Ver14.00A
// MCU: PIC16F886
// Clock: 8MHz osc resonator
// Power: DC 3V動作
// 内容: NOKIA5110 液晶表示器制御
// Topページ右下に動作サンプル写真あり。
//---------------------------------------------------------------------------
// ピンアサイン:(電源・クリスタル・7LED等の配線は省略)
//
// PIC-16F886-8MHz
// PORT番号 MODE
// RA0 =
// RA1 =
// RA2 =
// RA4 =
// RA5 =
// RA6 =
// RA7 =
//
// RB0 =
// RB1 =
// RB2 =
// RB3 =
// RB4 =
// RB5 =
// RB6 =
// RB7 =
//
// RC0 = I/O SPI_SCE
// RC1 = I/O SPI_DATA
// RC2 = I/O SPI_CLK
// RC3 = I/O
// RC4 = I/O SPI_RES
// RC5 = I/O SPI_DC
// RC6 =
// RC7 =
//---------------------------------------------------------------------------
#include <P16F886.H>
#include "Nokia5110.h"
#include <Delays.h> // Wait
//■コンフィグの設定
#__config 0x20E4 // set config GP4,5 are port ,internal 4M clock 0x30c4
//■マクロの定義
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
//-------------------------------------------------------------------------
static bit LED @ PORTBIT(PORTB, 0); //TEST PIN LED
//■関数および変数の宣言---------------------------------------------------
void main(void);
void Initialise(void);
void print_graph(void);
//-------------------------------------------------------------------------
/* 「試作版」の3文字上半分 */
const unsigned char font_ondoH[] =
{
0x08,0xAA,0xAA,0xAA,0xAA,0x08,0x10,0x90,
0x90,0x90,0x10,0xFF,0x10,0x12,0x14,0x00,
0x40,0x30,0xFC,0x03,0x40,0x20,0x10,0x0C,
0x0B,0xF8,0x88,0x88,0x88,0x88,0x08,0x00,
0x00,0xFF,0x10,0x10,0x1F,0x10,0x00,0xFE,
0x22,0xE2,0x22,0x22,0x22,0xE2,0x02,0x00,
};
/* 「試作版」の3文字下半分 */
const unsigned char font_ondoL[] =
{
0x00,0x7C,0x44,0x44,0x7C,0x00,0x20,0x20,
0x3F,0x10,0x10,0x01,0x1E,0x20,0x78,0x00,
0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,
0x00,0x7F,0x04,0x04,0x04,0x04,0x00,0x00,
0x70,0x0F,0x01,0x01,0x7F,0x40,0x30,0x0F,
0x40,0x21,0x16,0x08,0x16,0x21,0x40,0x00,
};
/* グラフィック 4段(8dot) X 6Byt */
unsigned char const charkuta_pix[4][48]=
{
{/* 1 段目*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0x42,0x24,0x38,0x10,
0x10,0x08,0x0F,0x04,0x04,0x04,0x04,0x04,
0x07,0x04,0x0C,0x08,0x08,0x08,0x18,0x10,
0x3E,0x31,0x20,0x60,0xC0,0xA0,0x30,0x18,
0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
},
{/* 2 段目*/
0x00,0x00,0x00,0xE0,0x10,0xC8,0x78,0x18,
0x04,0x02,0x01,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x06,
0x1C,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,
},
{/* 3 段目*/
0x00,0x00,0x00,0x01,0x3E,0xC3,0x1C,0x16,
0x0A,0x26,0x1C,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x07,0x07,0x03,0x00,0x00,0x00,
0x00,0x00,0x02,0x02,0x06,0x06,0x06,0x04,
0x04,0x9C,0x5C,0xC4,0x44,0x80,0x00,0x00,
0x80,0xC1,0xC1,0x41,0x22,0x1C,0x00,0x00,
},
{/* 4 段目*/
0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x0E,
0x18,0x78,0x5C,0xD4,0x94,0x94,0xB4,0xA4,
0xA4,0xAC,0xA8,0xB8,0xF0,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0xC3,0x44,0x44,0x67,0x30,0x14,0x0B,0x0C,
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
},
};
//-------------------------------------------------------------------------
//■メイン関数です (Nokia_main.c)
//-------------------------------------------------------------------------
void
main(void)
{
int x, y;
unsigned char c;
Initialise();
LCD_init();
LCD_locate(0,0);
LCD_clear(LCD_WIDTH * LCD_BANKS);
//-------
//ASCII 文字列を位置指定して表示 (文字列, X , Y) */
LCD_locate(0,0);
LCD_clear(5 * 6);
//
print_asc("12345",0,0); // 整数, X, Y
print_asc("67890",0,1); // 整数, X, Y
print_asc("{ M }",0,2); // 整数, X, Y
print_asc("Test",0,3); // 整数, X, Y
print_asc("$'(*/",0,4); // 整数, X, Y
print_asc("A9BCD",0,5); // 整数, X, Y
// 漢字・グラフィック表示 */
print_graph();
// グラフのX,Y軸表示 */
c = 0xff;
x = LCD_MAX_X - GRAPH_HIST_MAX - 2; // 83 - 48 - 2 = x
// Y縦線を表示
for (y = 0; y < 6; y++) {
LCD_locate(x, y);
LCD_set_data(&c, 1);
//LCD_locate(x + GRAPH_HIST_MAX + 1, y);
//LCD_set_data(&c, 1);
}
do{ // LED点 Loop
LED = 0;
Wait(500);
LED = 1;
Wait(500);
}while(1);
}
//-------------------------------------------------------------------------
// 試作版漢字 & グラフィックス表示
//-------------------------------------------------------------------------
void
print_graph(void)
{
int col;
int r;
unsigned char *pc;
// 「試作版漢字」を表示 */
LCD_locate(36, 0);
pc = (unsigned char *)font_ondoH;
LCD_set_data(pc, 48);
LCD_locate(36, 1);
pc = (unsigned char *)font_ondoL;
LCD_set_data(pc, 48);
// グラフィック */
for(r=0;r<4;r++){
LCD_locate(36, 2+r); // Y= 8dot X 4Byt
pc = (unsigned char *)(charkuta_pix[r]);
LCD_set_data(pc, 48); // X= 8dot X 6Byt
}
}
//-------------------------------------------------------------------------
// PIC insharaiz
//-------------------------------------------------------------------------
void
Initialise(void)
{
OSCCON = 0x71; // 内蔵オシレータの周波数を8MHzに設定 / 0x71=8MHz 0x61=4MHz
//----OSCILLATOR TUNING REGISTER (ADDRESS 90h)
OSCTUNE = 0x00; //011111 = Maximum frequency
//000000 = Center frequency.
//100000 = Minimum frequency
OPTION_REG = 0x00;
// bit5=1:CVREF = (VR<3:0>/24) * VDD bit5=0:CVREF = VDD/4 + (VR<3:0>/32) * VDD
TRISA = 0b00000000;
TRISB = 0b00000000;
TRISC = 0b00000000; // PORTC入出力方向レジスタ書き込み 追加
PORTA = 0;
PORTB = 0;
PORTC = 0;
}
// MAIN END
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// ノキア5110LCD駆動用 液晶表示器制御ライブラリーです (Nokia5110.c)
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
#include <P16F886.H>
#include "Nokia5110.h"
#include <Delays.h> // Wait
//--------------------------------
/* 数字 */
unsigned char const font_num[10][5]=
{
{ /* 0 */
0b01111100,
0b10000010,
0b10000010,
0b10000010,
0b01111100,
},
{ /* 1 */
0b00000000,
0b00000100,
0b11111110,
0b00000000,
0b00000000,
},
{ /* 2 */
0b11000100,
0b10100010,
0b10010010,
0b10010010,
0b10011100,
},
{ /* 3 */
0b01000100,
0b10010010,
0b10010010,
0b10010010,
0b01111100,
},
{ /* 4 */
0b00011000,
0b00010100,
0b00010010,
0b11111110,
0b00010000,
},
{ /* 5 */
0b01011110,
0b10010010,
0b10010010,
0b10010010,
0b01100010,
},
{ /* 6 */
0b01111100,
0b10010010,
0b10010010,
0b10010010,
0b01100100,
},
{ /* 7 */
0b00000010,
0b00000010,
0b11100010,
0b00010010,
0b00001110,
},
{ /* 8 */
0b01101100,
0b10010010,
0b10010010,
0b10010010,
0b01101100,
},
{ /* 9 */
0b00001100,
0b10010010,
0b10010010,
0b10010010,
0b01111100,
},
};
/* キャラクター */
unsigned char const ASCII[][5] =
{
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c \
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f →
};
//--------------------------------
// 5110LCD初期設定 */
//--------------------------------
void
LCD_init(void)
{
SPI_RES = 0; // LCD リセット指令
delay_us(); // 2uS LCD リセット保持
delay_us(); // 2uS LCD リセット保持
delay_us(); // 2uS LCD リセット保持
SPI_RES = 1; // LCD リセット指令
SPI_DC = 0; // 初期設定
SPI_SCE = 0; // LCD チップイネーブル
SPI_CLK = 0; // 初期設定
SPI_tx_byte(0b00100000 | 1, 0); // H=1 */ // H = 1
SPI_tx_byte(0b00000100 | 1, 0); // TC=1 (0-3) */ // TC = 1 (0-3)
SPI_tx_byte(0b00010000 | 3, 0); // Bias=4 (0-7) */ // Bais = 3 (0-7)
SPI_tx_byte(0b10000000 | 58, 0);// Vop=85 (0-127) コントラスト設定 */ // Vop = 68 (0-127) コントラスト設定
SPI_tx_byte(0b00100000 | 0, 0); // H=0, horizontal addressing */ // H = 0, Horizontal addressing
SPI_tx_byte(0b00001000 | 4, 0); // DisplayMode Normal=4 */ // Display Mode Normal = 4
SPI_tx_byte(0b01000000 | 0, 0); // Set Y=0 (0-5) */ // Set Y = 0 (0-5)
SPI_tx_byte(0b10000000 | 0, 0); // Set X=0 (0-83) */
}
//--------------------------------
// LCD 書込み位置をXYに設定 */
//--------------------------------
void
LCD_locate(unsigned char x,unsigned char y)
{
SPI_tx_byte(0b01000000 | y, 0);
SPI_tx_byte(0b10000000 | x, 0);
}
//--------------------------------
// 現書込ポジションから指定バイトのデータ列書込み */
//--------------------------------
void
LCD_set_data(unsigned char *datap,int len)
{
for (;len>0;len--)
SPI_tx_byte(*(datap++), 1);
}
//--------------------------------
// 現書込ポジションから指定バイトの表示クリア */
//--------------------------------
void
LCD_clear(unsigned int len)
{
for (;len>0;len--)
SPI_tx_byte(0, 1);
}
//-------------------------------
// NJM3711ポート出力関数
//-------------------------------
void
SPI_tx_byte(unsigned char d,int dc)
{
unsigned char cnt;
SPI_SCE = 0; // チップ・イネーブル */
SPI_DC = dc; // コマンド/データを指定す
for (cnt = 0; cnt < 8; cnt++) {
if ((d & 0b10000000) != 0) {
SPI_DATA = 1;
} else {
SPI_DATA = 0;
}
delay_us(); //2uS
SPI_CLK = 1;
d = d << 1;
delay_us(); //2uS
delay_us(); //2uS
SPI_CLK = 0;
}
SPI_SCE = 1;
}
//--------------------------------
// Wait 8MHz=2uS */
//--------------------------------
void
delay_us(void)
{
#pragma asm
MOVLW 1 ;8MHzOSC=2uS
MOVWF ACC
W500u_LOOP
DECFSZ ACC,F
GOTO W500u_LOOP
#pragma asmend
}
//--------------------------------
// 文字単位で位置を指定して正の整数を表示 (整数, X , Y) */
//--------------------------------
void
print_num(int n, int col, int y_bank)
{
int r;
unsigned char *pc;
do {
r = n % 10; // 1番下の桁の値を計算 */
n = n / 10;
LCD_locate(col*6, y_bank); // 表示位置を計算 */
pc = (unsigned char *)(font_num[r]);
LCD_set_data(pc, 5); // 1番下の桁の値に対応する文字を表示 */
--col;
} while (n > 0); // 全ての桁を表示するまで繰り返し */
}
//--------------------------------
// ASCII 文字列を位置指定して表示 (文字列, X , Y) */
//--------------------------------
void
print_asc(unsigned char *data, int x_bank, int y_bank)
{
int r, col=0;
unsigned char *pc;
do {
r = *data++ - 0x20; // 1番下の桁の値を計算 */
LCD_locate((col++*6)+x_bank*6, y_bank); // 表示位置を計算 */
pc = (unsigned char *)(ASCII[r]);
LCD_set_data(pc, 5); // 1番下の桁の値に対応する文字を表示 */
} while (*data); // 全ての桁を表示するまで繰り返し */
}
//--------------------------------
// (x, y)ピクセル座標に点を描画 */
//--------------------------------
void
draw_point(int x, int y)
{
int bank_y;
unsigned char pat_y;
if (y < 0) {
bank_y = LCD_MAX_BANK;
pat_y = 0b10000000;
} else if (y > LCD_MAX_Y) {
bank_y = 0;
pat_y = 0b00000001;
} else {
bank_y = LCD_MAX_BANK - (y / 8);
pat_y = 0b10000000 >> (y % 8);
}
LCD_locate(x, bank_y); // x位置のバンクy
LCD_set_data(&pat_y, 1); // バンクyへ8ビットパターンを書き込む
}
LIVE END
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// Nokia5110 グラフィック液晶表示器用ライブラリ ヘッダ (Nokia5110.h)
// ポートの定義
// 関数プロトタイプ
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
extern void LCD_init(void);
extern void LCD_locate(unsigned char x,unsigned char y);
extern void LCD_set_data(unsigned char *datap,int len);
extern void LCD_clear(unsigned int len);
extern void SPI_tx_byte(unsigned char d,int dc);
extern void delay_us(void);
//
extern void print_num(int n, int col, int y_bank);
extern void print_asc(unsigned char *data, int col, int y_bank);
extern void draw_point(int x, int y);
//extern void print_unitdeg(void);
//---ここでポートを指定する。--------------------------
#define PORT PORTC //SET PORT=A,B,C,D,E
//-----------------------------------------------------
#define LCD_WIDTH 84
#define LCD_HEIGHT 48
#define LCD_BANKS 6 // (LCD_HEIGHT/8)
#define LCD_MAX_X 83 // (LCD_WIDTH - 1)
#define LCD_MAX_Y 47 // (LCD_HEIGHT - 1)
#define LCD_MAX_BANK 5
#define GRAPH_HIST_MAX 48
//--GLCD Control PORT & BIT 設定------------------------
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
static bit SPI_SCE @ ((unsigned)&PORT*8+0);
static bit SPI_DATA @ ((unsigned)&PORT*8+1);
static bit SPI_CLK @ ((unsigned)&PORT*8+2);
static bit SPI_DC @ ((unsigned)&PORT*8+5);
static bit SPI_RES @ ((unsigned)&PORT*8+4);
//---------------------------------------------------------------------------
// Project: SG12864A(128X64) GLCD Controi
// Language: Wiz-C,Ver14.00A
// MCU: PIC16F877
// Clock: 20MHz osc
// EEPROM: 24LC64 (I2C)
// 内容: SG12864A(128X64)制御
// Topページ右下に動作サンプル写真あり。
//---------------------------------------------------------------------------
// PORT番号
// RA0 =
// RA1 =
// RA2 =
// RA3 =
//
// RD0 = DB0
// RD1 = DB1
// RD2 = DB2
// RD3 = DB3
// RD4 = DB4
// RD5 = DB5
// RD6 = DB6
// RD7 = DB7
//
// RB0 = D/I(RS)
// RB1 = R/W
// RB2 = E
// RB3 = CS1
// RB4 = CS2
// RB5 = /RST
// RB6 =
// RB7 =
//
// RC0 =
// RC1 =
// RC2 =
// RC3 = LED
// RC4 = _SDA
// RC5 = _SCL
// RC6 =
// RC7 =
//---------------------------------------------------------------------------
#include <P16F877.h>
#include "sg12864Lib.h"
#include <Delays.h> // Wait
#include <maths.h> // Randam 数値発生
//■コンフィグの設定----------------------
#__config 0x3F72 //Setting of the configuration bit
//■マクロの定義--------------------------
#define X0 3
#define Y0 3
//#define PI 3.141592654f
#define NODES 20
#define SIDE 6
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
static bit LED @ PORTBIT(PORTC, 3); //TEST PIN LED
// 2次元立体グラフ描画関数 ---------------*/
int i, j, px, py, x, y, z;
float zf, xf, yf, sf;
struct{
int x;
int y;
} edge[NODES], prev;
//■関数および変数の宣言---------------------------------------------------
void main(void);
void Initialise(void);
void D2Graph(int Hight);
void WriteEEData(int, char );
//-------------------------------------------------------------------------
//■メイン関数です (glcd_main.c)
//-------------------------------------------------------------------------
void
main(void)
{
int i, j, SW, index;
Initialise();
lcd_Init();
do{
lcd_Clear(0);
// グラフィックの曲線表示 1画面 0,0-64,128
/*
for(i=0;i<3;i++)
D2Graph(10*i);
*/
// グラフィックの表示 1画面 0,0-64,128
lcd_Image(0x7E0, 0, 8, 0, 128);
//lcd_Image(0x3d0, 0, 8, 0, 128);
Wait(5000);
// グラフィックの表示 2画面 0,0-64,128
lcd_Image(0x3D0, 0, 8, 0, 128);
//lcd_Image(0x3d0, 0, 8, 0, 128);
Wait(5000);
// グラフィックの表示 3画面 0,0-64,128
lcd_Image(0xBF0, 0, 8, 0, 128);
//lcd_Image(0x3d0, 0, 8, 0, 128);
Wait(5000);
// グラフィックの表示 4画面 0,0-64,128
lcd_Image(0x31000, 0, 8, 0, 128);
//lcd_Image(0x3d0, 0, 8, 0, 128);
Wait(5000);
// 斜め直線の表示
lcd_Clear(0); // 全クリア
for(i=0; i<64; i++){
lcd_Pixel(i,i,1); // CS1側
lcd_Pixel(64+i, i,1); // CS2側
}
Wait(3000);
// 斜め直線白抜き表示
lcd_Clear(0xFF); // 全部黒
for(i=0; i<64; i++){
lcd_Pixel(i,i,0);
lcd_Pixel(64+i, i,0);
}
Wait(3000);
// ASCII文字全表示 16文字/行
lcd_Clear(0); // 文字表示テスト/行
for(j=0; j<8; j++){
for(i=0; i<16; i++){
index = j*16+i+0x20;
lcd_Char(j, i, index);
}
}
Wait(3000);
// ASCII文字全表示 18文字/行
lcd_Clear(0); // クリア
for(j=0; j<8; j++){
for(i=0; i<18; i++){
index = j*18+i+0x50;
lcd_Char1(j, i, index); // 文字表示制御
}
}
Wait(3000);
// カタカナ表示
lcd_Clear(0);
lcd_Str(0, 0, "アイウエオカキクケコワヲン"); // Wiz-Cはカタカナがコンパイルできない。
lcd_Str(2, 3, "アイウエオカキクケコワヲン");
//Wait(3000);
// 直線交差
//lcd_Clear(0);
lcd_Line(0,20, 127, 20);
lcd_Line(50,0, 50, 63);
//スクロール表示
lcd_Scroll(100);
Wait(3000);
// 文字列の表示テスト
lcd_Clear(0);
lcd_Str(0, 0, "Hello World!!");
lcd_Str(2, 0, "Graphic LCD Test!");
Wait(3000);
// 直線箱書き
lcd_Clear(0);
i = 0;
for(j=0; j<32; j+=2){
lcd_Line(j,j, 127-j, j);
lcd_Line(j,j, j, 63 -j);
lcd_Line(127-j,63-j, 127-j,j);
lcd_Line(128-j,63-j, j,63-j);
Wait(100);
}
Wait(3000);
//
//
//do{
LED = 0;
Wait(500);
LED = 1;
Wait(500);
}while(1);
}
//-------------------------------------------------------------------------
// 2次元立体グラフ描画関数 -うまく動作しません-
// z(x,y) = 1/(1+SQRT(x2+y2))*COS(SQRT(x2+y2))
// (-3*PI< x,y < 3*PIの範囲)
// zの最大値をPOTで変更する
//-------------------------------------------------------------------------
void
D2Graph(int Hight) {
lcd_Line(X0, 3, X0, 63); // z axis
lcd_Line(X0-3, Y0, 123, Y0); // x axis
lcd_Line(X0-2, Y0-2, X0+60, Y0+60); // y axis
for(j=0; j<NO j++){
edge[j].x = X0 + j*SIDE/2;
edge[j].y = Y0 + j*SIDE/2;
}
for(i=0; i<NODES; i++){
x = i * SIDE;
xf = (6 * PI / 200) * (float)(x-100);
prev.y = Y0;
prev.x = X0 + x;
for(j=0; j<NODES; j++){
y = j * SIDE;
yf = (6 * PI /200) * (float)(y -100);
sf = sqrt(xf * xf + yf * yf);
zf = 1/(1+sf) * cos(sf);
z = zf * Hight;
px = X0 + x + y/2;
py = Y0 + z + y/2;
lcd_Pixel(px, py, 1);
lcd_Line(px, py, prev.x, prev.y);
lcd_Line(px, py, edge[j].x, edge[j].y);
prev.x = px;
prev.y = py;
edge[j].x = px;
edge[j].y = py;
}
}
}
//-------------------------------------------------------------------------
// 初期処理 16F877
//-------------------------------------------------------------------------
void
Initialise(void)
{
PORTA=0; // ポート(A)CLEAR
PORTB=0; // ポート(B)CLEAR
PORTC=0; // ポート(C)CLEAR
PORTD=0; // ポート(D)CLEAR
PORTE=0; // ポート(E)CLEAR
TRISA=0x0; // Aポートを読みビット以外出力 TRISA=XXX00000
TRISB=0x0; // Bポートを読みビット以外出力 TRISB=00000000
TRISC=0x0; // Cポートを読みビット以外出力 TRISC=00000000
TRISD=0x0; // Dポートを読みビット以外出力 TRISD=00000000
TRISE=0x0; // Eポートを読みビット以外出力 TRISE=XXXXX000
}
// MAIN END
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// SG12864A(128X64) LCD Controi ライブラリー です (glcd_lib.c)
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
#include <P16F877.h>
#include "sg12864Lib.h"
#include <Delays.h> // Wait
#include <datalib.h> //I2C
//-------------------------------------------------------------------------
// データ出力関数
//-------------------------------------------------------------------------
void
lcd_Write(char cs, char code, char DIflag)
{
int data;
LCD_RW = 0; // write mode
if(cs==1){
LCD_CS1 = 0; LCD_CS2 = 1;
}else{
LCD_CS2 = 0; LCD_CS1 = 1;
}
//data = (int)code;
LCD_DATA = code;
if (DIflag == 0)
LCD_DI = 1; // 表示データの場合
else
LCD_DI = 0; // コマンドデータの場合
Delay1u(1); // 1usec
LCD_E = 1; // strobe out
Delay1u(1); // pulse width 1usec
LCD_E = 0; // reset strobe
LCD_CS1 = 1;
LCD_CS2 = 1;
LCD_RW = 1;
Delay1u(5);
}
//-------------------------------------------------------------------------
// データ読み出し関数
//-------------------------------------------------------------------------
char lcd_Read(char cs){
int data;
LCD_TRIS = 0xFF; // chane to input mode
LCD_RW = 1; // set read mode
if(cs==1){ // CS1 or CS2?
LCD_CS1 = 0; LCD_CS2 = 1;
}else{
LCD_CS2 = 0; LCD_CS1 = 1;
}
LCD_DI = 1; // set data mode
Delay1u(1); // 1usec delay
LCD_E = 1; // strobe out
Delay1u(1); // pulse width 1usec
LCD_E = 0; // reset strobe
Delay1u(3); // wait 3usec
data = LCD_DATA%3b.html // input data
Delay1u(1); // wait 1usec
LCD_CS1 = 1; // reset CS
LCD_CS2 = 1;
LCD_TRIS = 0x00; // back to output mode
return((char)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){
Wait(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=<colum<=127?
Xpos = Xpos-64; // shift 64 dot
cs = 1;
}
else
cs = 2;
page = (char)(7-Ypos/8); // set page
lcd_Write(cs, 0xB8+page, 1);
lcd_Write(cs, 0x40+Xpos, 1); // set colum
data = lcd_Read(cs)%3b.html // get current data
lcd_Write(cs, 0x40+Xpos, 1); // set colum ????
data = lcd_Read(cs)%3b.html // get current data ????
pos =1; // set bit position
count = (char)(7-Ypos%8); // set bit
for(i=0; i<count; i++) // caluculate 2^n
pos *= 2;
lcd_Write(cs, 0x40+Xpos, 1); // back address
if(On==1) // set or reset bit
lcd_Write(cs, data | pos, 0); // set 1
else
lcd_Write(cs, data & ~pos, 0); // set 0
}
}
//-------------------------------------------------------------------------
// 直線描画関数
//-------------------------------------------------------------------------
#define abs(a) (((a)>0) ? (a) : -(a))
void lcd_Line(int x0, int y0, int x1, int y1)
{
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;
/// 直線を点で描画
for(x=x0; x<x1; x++) {
if(steep) lcd_Pixel(y,x,1); else lcd_Pixel(x,y,1);
error += deltay;
if((error << 1) >= 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
EEPROM_read(letter-0x20, 5);
for(i=0; i<5; i++)
//lcd_Write(cs, Font[letter-0x20][i], 0);
lcd_Write(cs, eep_buf[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
EEPROM_read(letter-0x20, 5);
for(i=0; i<5; i++)
lcd_Write(cs, eep_buf[i], 0);
//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(int add, int x, int y, int x1, int y1)
{
char cs, Xpos;
int page, colum;
for(page=x; page<y; page++){ // y-y1 0-8
for(colum=x1; colum<y1; colum++){ // x1-x 0-128
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);
EEPROM_read(add+(page*(y1-x1))+colum, 1); // 1回リード
//EEPROM_read(0x3d0+(page*128)+colum, 1); // 1回リード
lcd_Write(cs, eep_buf[0], 0);
//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);
Wait(delay);
}
}
//-------------------------------------------------------------------------
// Communication I2C RX
//-------------------------------------------------------------------------
void EEPROM_read(unsigned int EEPROM_add, unsigned char byt)
{
unsigned char address;
BYTE AddrLo; //I2C EEPROM address-Low word buf
BYTE AddrHi; //I2C EEPROM address-High word buf
AddrHi=(EEPROM_add*byt)/256;
AddrLo=(EEPROM_add*byt)%256;
QuickStop();
IIWrite(0xA0,IISTART|IIACK);
IIWrite(AddrHi,IIACK);
IIWrite(AddrLo,IIACK);
PORTC|=(1<<_SCL);
IIWrite(0xA1,IISTART|IIACK);
for (address=0;address<byt;address++){
TRISC|=(1<<_SDA);
eep_buf[address]=IIRead(IIACK);
}
}
//-------------------------------------------------------------------------
// Wait
//-------------------------------------------------------------------------
void Delay1u(int t) // WaitUs()を呼び出す条件で使う
{
while(t--){
Delay200n();
}
}
//-------------------------------------------------------------------------
// Wait 20MHz=800nS
//-------------------------------------------------------------------------
void Delay200n(void)
{
#pragma asm
MOVLW 1
MOVWF ACC
W500u_LOOP
DECFSZ ACC,F
GOTO W500u_LOOP
#pragma asmend
}
// LIVE END
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// グラフィック液晶表示器用ライブラリ ヘッダ (sg12864Lib.h)
// ポートの定義
// 関数プロトタイプ
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
extern void lcd_Write(char cs, char code, char DIflag);
extern char lcd_Read(char cs);
extern void lcd_Init(void);
extern void lcd_Clear(char data);
extern void lcd_Pixel(int Xpos, int Ypos, char On);
extern void lcd_Char(char line, char colum, int letter);
extern void lcd_Char1(char line, char colum, int letter);
extern void lcd_Str(char line, char colum, char *s);
extern void lcd_Line(int x0, int y0, int x1, int y1);
extern void lcd_Scroll(int delay);
//extern void lcd_Image(char *ptr);
extern void lcd_Image(int ptr, int x, int y, int x1, int y1);
extern void Delay200n(void);
extern void Delay1u(int t);
extern void EEPROM_read(unsigned int EEPROM_add, unsigned char byt);
//---ここでポートを指定する---------------
#define PORT PORTB //SET PORT=A,B,C,D,E
#define LCD_DATA PORTD //SET PORT=A,B,C,D,E
#define LCD_TRIS TRISD
//LCD Control PORT & BIT 設定-------------
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
//#define LCD_STROBE ((LCD_E = 1),(LCD_E=0))
static bit LCD_DI @ ((unsigned)&PORT*8+0); //* GLCDのRS端子*/
static bit LCD_RW @ ((unsigned)&PORT*8+1); //* GLCDのRW端子*/
static bit LCD_E @ ((unsigned)&PORT*8+2); //* GLCDのE端子*/
static bit LCD_CS1 @ ((unsigned)&PORT*8+3); //* GLCDのCS1端子*/
static bit LCD_CS2 @ ((unsigned)&PORT*8+4); //* GLCDのCS2端子*/
static bit LCD_RST @ ((unsigned)&PORT*8+5); //* GLCDのPST端子*/
// eeprom read buf 20byt
static unsigned char eep_buf[20]; // I2C バッファ用
//----------I2C-通信設定---Wiz-C専用-----------
const BYTE PICIO=&PORTC;
const BYTE _SDA=4;
const BYTE _SCL=5;