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

