PIC16F877AにLCDをつなぐ

PIC16F877AにGPSをつなぐ前にデバッグのためにLCDをつないだ。
以前、PIC18F2550につないだのでそれを参考にしようと思ったけど、回路図も残してなかった。
ソースコードはあったのでそのソースコードをPIC16F877A向けに書き換えた。
PIC時計に使えるようにわざとポートAを使っています。

PIC16F877AにLCDをつなぐ

PIC16F877AにLCDをつなぐ


回路図
PIC16F877A-LCDの回路図

PIC16F877A-LCDの回路図

ソースコードは以下の3つ。
main.c

#include <pic.h>

__CONFIG(XT & WDTDIS & PWRTEN & BOREN & LVPDIS & UNPROTECT);

#include "lcdlib16.h"

void main()
{
	// ポートの設定
	ADCON1 = 0x06;	// ポートAをデジタルへ
	TRISA = 0x00;	// 全部出力
	TRISB = 0xFE;	// 0 出力
	RB0 = 0;
	// LCD初期化
	lcd_init();
	lcd_clear();
	lcd_str("Hello World!");
	for (char i = 0; i < 10; i++) {
		__delay_ms(100);
	}
	lcd_clear();

	while (1) {
		RB0 = !RB0;
		if (RB0) {
			lcd_str("LED OFF");
		} else {
			lcd_str("LED ON");
		}
		for (char i = 0; i < 10; i++) {
			__delay_ms(100);
		}
		lcd_clear();
	}
}

lcdlib16.h
__delay_us, __delay_ms関数のために_XTAL_FREQにクロック周波数を定義しました。

#include <pic.h>

#define _XTAL_FREQ	4000000

// LCDポート設定
#define LCD_DATA	PORTA	// 4ビットデータの出力ポート
#define LCD_RS		RA0		// RS信号
#define LCD_E		RA1		// E(STB)信号

// LCD関数プロトタイピング
void lcd_out(char code, char flag);
void lcd_data(char asci);
void lcd_cmd(char cmd);
void lcd_goto(unsigned char y, unsigned char x);
void lcd_clear(void);
void lcd_init(void);
void lcd_str(const char *str);

lcdlib.c

#include "lcdlib16.h"

// データ出力サブ関数
void lcd_out(char code, char flag)
{
	// 上位4ビットを出力
//	LCD_DATA = (LCD_DATA & 0x0F) | (code & 0xF0);
	LCD_DATA = (LCD_DATA & 0x03) | ((code & 0xF0) >> 2);
//	LCD_DATA = (LCD_DATA & 0xF0) | ((code & 0xF0) >> 4);

	if (flag == 0) {
		LCD_RS = 1;
	} else {
		LCD_RS = 0;		// コマンドデータの場合
	}
	__delay_us(1);		// pulse width
	LCD_E = 1;			// strobe out
	__delay_us(1);		// pulse width
	LCD_E = 0;			// reset strobe
}

// 1文字表示関数
void lcd_data(char asci)
{
	lcd_out(asci, 0);		// 上位4ビット出力
	lcd_out(asci << 4, 0);	// 下位4ビット出力
	__delay_us(50);			// 50μsec待ち
}

// コマンド出力関数
void lcd_cmd(char cmd)
{
	lcd_out(cmd, 1);		// 上位4ビット出力
	lcd_out(cmd << 4, 1);	// 下位4ビット出力
	if ((cmd & 0x03) != 0) {
		__delay_ms(2);		// 2msec待ち
	} else {
		__delay_us(50);		// 50μsec待ち
	}
}

// 行移動関数
void lcd_goto(unsigned char y, unsigned char x)
{
	char cmd;
	switch (y) {
	case 1:  cmd = 0xC0; break;
	case 2:  cmd = 0x94; break;
	case 3:  cmd = 0xD4; break;
	default: cmd = 0x80; break;
	}
	lcd_cmd(cmd+x);
}

// 全消去関数
void lcd_clear(void)
{
	lcd_cmd(0x01);			// 初期化コマンド出力
	__delay_ms(15);			// 15msec待ち
}

// 文字列出力関数
void lcd_str(const char *str)
{
	while (*str != 0x00) {
		lcd_data(*str);
		str++;
	}
}

// 初期化関数
void lcd_init(void)
{
	__delay_ms(30);			// 30msec待ち
	lcd_cmd(0x03);			// 8bit mode set
	__delay_ms(5);
	lcd_cmd(0x03);			// 8bit mode set
	__delay_ms(1);
	lcd_cmd(0x03);			// 8bit mode set
	__delay_ms(1);
	lcd_cmd(0x02);			// 4bit mode set
	__delay_ms(1);
	lcd_cmd(0x28);			// DL=0 4bit mode, N=1 2lines, F=0 5x7 font
//	lcd_cmd(0x24);			// DL=0 4bit mode, N=0 1line,  F=1 5x10 font
	__delay_ms(1);
	lcd_cmd(0x08);			// display off D=C=B=0
	lcd_cmd(0x0C);			// display on D=1 C=B=0
//	lcd_cmd(0x0D);			// display on D=C=1 B=0
//	lcd_cmd(0x0F);			// display on D=C=B=1
	lcd_cmd(0x06);			// entry I/D=1 S=0
	lcd_cmd(0x02);			// cursor home
	lcd_clear();
}
カテゴリー: PIC, 回路, 部品 タグ: , , , , , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください