ホーム

電子工作

腕ロボット

二足歩行ロボット

無線コントローラ

工作機械

電子工作動画

自作ソフト(C言語)

Webページ作成

Javascriptゲーム

FLASHとは!

自学自習のテキスト

その他

16×2液晶表示
 2015年1月〜3月
プレイステーション2のでロボットを操縦できたら・・・・・と思い、ネットを調べているうちに ワイヤレスコントローラからのレスポンスが返ってくるとか・・・・。
それを「16×2文字LCD表示器」に表示させようと思い立ちました。
以下はその顛末です。

左が取扱説明書の一部とその回路図です。

16文字 x 2行分の英数字、記号、カタカナ文字等を表示できる液晶表示器の制御回路です。
1文字5×7ドット で表示します。液晶表示器の型名はSC1602BSLです。 CPUからのデータ通信は8BITモードと4BITモードがありますが、この回路ではD4〜D7の4BIT分をポート6の0〜4BITに接続してあります。
D0〜D3はGNDに接続していますので、4BITモードを使用することになります。
RS,E,RWの各端子は制御用です。
VO端子は液晶表示のコントラスト調整用で、10kΩの可変抵抗によって最適のコントラストに調整します。



液晶モニタに表示したものです。












以下はそのためのC言語プログラムです。
メインルーチンではタイマー関係の関数と表示するメイン部分だけで、液晶表示の関数はまとめて「lcd1.h」 に入っています。
以前の「Rikiya」さんのプログラムでは、液晶表示関連のプログラムがこんな風に ヘッダーファイルとして別ファイルになっていませんでした。
このバージョンではこんな風に別ファイルになっていて非常に見やすくなっています。
殆どは「Rikiya」さんからのパクリですが、一部僕なりにアレンジしています。
/******************************************************/
/* 16×2液晶モニタに表示させるプログラム           */
/******************************************************/
void itu0_wait_init(void);
void itu0_wait(int msec);
/******************************************************/
#include "3048f.h"
#include "lcd1.h"
/* 待ち時間発生初期化 *********************************/
void itu0_wait_init(void){
	/*ITU0、1のクロックを8分週 3125:1ms、4687.5:1.5ms、6250:2ms、62500:20ms*/
	ITU0.TCR.BYTE = 0x03;	/* ITU0、TCNTクリア禁止 clock 1/8 */
	ITU1.TCR.BYTE = 0x03;
	/* ITU1、TCNTクリア禁止 clock 1/8 */
	ITU.TSTR.BIT.STR0 = 0;	/* ITU0 TCNTカウント停止 */
	ITU.TSTR.BIT.STR1 = 0;	/* ITU1 TCNTカウント停止 */
	return;
}
/* 待ち時間発生 引数に必要なミリ秒を指定する*************/
void itu0_wait(int msec){
	ITU.TSTR.BIT.STR1 = 1;	/* ITU1 TCNTカウント開始 */
	ITU1.TCNT = 0;
    	while(ITU1.TCNT <3125*msec);/*msec second経過するまで待つ*/
	ITU.TSTR.BIT.STR1 = 0;	/* ITU1 TCNTカウント停止 */
	return;
}
void main(void){
	lcd_init();	/* lcd液晶表示器の初期化 */
	lcd_locate(0,0);		/* カーソル位置の指定*/
	lcd_print("Spring is come.");	/* 文字列の表示 */
	lcd_locate(0,1);		/* カーソル位置の指定*/
	lcd_print("Ready GO!!");	/* 文字列の表示 */
	while(1)	{;}
}

次は液晶表示関連の関数が入っている「lcd1.h」です。
最初の4行に「#define」で使うポートが定義されているので、自分なりのポートに変えたいとき は非常に便利です。
僕の場合は、ポート6を使っているのでご覧のようにしています。
前述のように、この部分は「Rikiya」さんが作ったものなので、最初の4行は彼の制作の証を残しています。
/********************************************************/
/* TekuRobo工作室                            2010/05/12 */
/* 汎用的な関数を収めたヘッダファイル                   */
/********************************************************/
/* 液晶表示lcd利用関数 ******************************* */
#define LCD_PORT_DDR	P6.DDR
#define LCD_RS			P6.DR.BIT.B4
#define LCD_E			P6.DR.BIT.B5
#define LCD_DATA		P6.DR.BYTE

void lcd_init(void);
void lcd_write8(char str);
void lcd_write4(char str,char rs);
void lcd_locate(char x,char y);
void lcd_print(char *str);
void lcd_clear(void);
void lcd_shift_disp(char dir);
void lcd_shift_cursor(char dir);

/* lcdのリセット動作 **********************************/

void lcd_init(void){
	
	itu0_wait_init();
	LCD_PORT_DDR = 0xFF;	/* 全BIT出力モード*/
	itu0_wait(15);		/* 15mS待機*/
	lcd_write8(0x03);	/* X,X,E,RS,7,6,5,4 = 0000 0011*/
	itu0_wait(5);		/* 5mS待機*/
	lcd_write8(0x03);	/* X,X,E,RS,7,6,5,4 = 0000 0011*/
	itu0_wait(1);		/* 1mS待機*/
	lcd_write8(0x03);	/* X,X,E,RS,7,6,5,4 = 0000 0011*/
	lcd_write8(0x02);	/* X,X,E,RS,7,6,5,4 = 0000 0010*/
				/* function set 4BIT MODE */
	lcd_write4(0x28,0);	/* 7,6,5,4, 3,2,1,0 = 0010 1000*/
				/* 4BIT,2lines,5x7dots font*/
	lcd_write4(0x0E,0);	/* 7,6,5,4, 3,2,1,0 = 0000 1000*/
				/* Display off*/
	lcd_write4(0x01,0);	/* 7,6,5,4, 3,2,1,0 = 0000 0001*/
				/* Clear Display*/
	lcd_write4(0x06,0);	/* 7,6,5,4, 3,2,1,0 = 0000 0110*/ 
				/* Increment, Don't Display Shift*/
	return;
}
/* lcdの全端子を直接操作する ****************************/
void lcd_write8(char str){	
	LCD_DATA = str;		/* strをLCD_DATAに出力*/
	LCD_E = 1;		/* LCD E-BITを1とする*/
	itu0_wait(1);		/* 1mS待機*/
	LCD_E = 0;		/* LCD E-BITを0としこのタイミングで書き込む*/
	itu0_wait(1);		/* 1mS待機*/
	return;
}
/* lcdに4bitデータを2度に分けて書き込む ****************************/
/* str:文字列、rs = 1:データ 0:コマンド*/
void lcd_write4(char str,char rs){ 
	char dummy = str;
	char status = 0;
    LCD_E = 0;			/* E信号の強制OFF*/
	switch (rs){
		case 1:			/* rs = 1 データ*/
			LCD_RS = 1;	/* LCD_RS-BITを1とする*/
			break;
		case 0:			/* rs = 0 コマンド*/
			LCD_RS = 0;	/* LCD_RS-BITを0とする*/
			break;
	default:			/* それ以外の場合(誤った設定の場合)*/
			LCD_RS = 1;	/* LCD_RS-BITを1とする*/
	}
	/*上位4BIT 7,6,5,4の転送*/
	dummy = dummy>>4;		/* 上位4BITを下位4BITにシフトする*/
	dummy &= 0x0F;			/* 上位4BITをマスクする*/
	status = LCD_DATA & 0xF0;	/* E,RS信号以外をマスク*/
	LCD_DATA = status | dummy;	/* statusとdummyの合成を出力*/
	LCD_E = 1;			/* LCD E-BITを1とする*/
	itu0_wait(1);			/* 1mS待機*/
	LCD_E = 0;			/* LCD E-BITを0としこのタイミングで書き込む*/
	itu0_wait(1);			/* 1mS待機*/
	/*下位4BIT 3,2,1,0の転送*/	
	dummy = str;
	dummy &= 0x0F;			/* 上位4BITをマスクする*/
	status = LCD_DATA & 0xF0;	/* E,RS信号以外をマスク*/
	LCD_DATA = status | dummy;	/* statusとdummyの合成を出力*/
	LCD_E = 1;			/* LCD E-BITを1とする*/
	itu0_wait(1);			/* 1mS待機*/
	LCD_E = 0;			/* LCD E-BITを0としこのタイミングで書き込む*/
	itu0_wait(1);			/* 1mS待機*/
	return;
}
/** lcd書き込み位置指定 x:0,y:0 *******************/
/* 0x80 (1000 0000) アドレス設定コマンド*/
/* 0x40 (0100 0000) 2行目の指定*/
void lcd_locate(char x,char y){
	lcd_write4(0x80+x+y*0x40,0);
	return;
}
/* lcdへの文字列書き込み *************************/
void lcd_print(char *str){
	while(*str != 0){		/* 文字列の最後eof(0)を検出*/ 
		lcd_write4(*str,1);	/* 文字データの書き込み */
		str++;			/* 次の文字に移動 */
	}
	return;
}
/* lcd表示のクリア *******************************/
void lcd_clear(void){
	lcd_write4(0x01,0);		/* 7,6,5,4, 3,2,1,0 = 0000 0001*/
	return;
}
/* lcd表示のシフト *******************************/
/* dir = 'l'or'L':左 'r'or'R':右 */
void lcd_shift_disp(char dir){
	switch (dir){
		case 'l':
		case 'L':
			lcd_write4(0x18,0);/* 7,6,5,4, 3,2,1,0 = 0001 1000*/
			break;
		case 'r':
		case 'R':
			lcd_write4(0x1C,0);/* 7,6,5,4, 3,2,1,0 = 0001 1100*/
			break;
		default:
			break;
	}
	return;
}
/* lcdカーソルのシフト **************************/
/* dir = 'l'or'L':左 'r'or'R':右 */
void lcd_shift_cursor(char dir){
	switch (dir){
		case 'l':
		case 'L':
			lcd_write4(0x10,0);/* 7,6,5,4, 3,2,1,0 = 0001 0000*/
			break;
		case 'r':
		case 'R':
			lcd_write4(0x14,0);/* 7,6,5,4, 3,2,1,0 = 0001 0100*/
			break;
		default:
			break;
	}
	return;
}