//パラレルポートLCD表示プログラミング
//4bit mode
//DB4 = BIT0,BASEPORT
//DB5 = BIT1,BASEPORT
//DB6 = BIT2,BASEPORT
//DB7 = BIT3,BASEPORT
//E = /BIT1,BASEPORT+2
//R/W = BIT2,BASEPORT+2
//RS = /BIT3,BASEPORT+2
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>
#include <time.h>
#define BASEPORT 0x378
//#define BASEPORT 0x278
//#define BASEPORT 0x3BC
#define BIT0 1
#define BIT1 2
#define BIT2 4
#define BIT3 8
#define BIT4 16
#define BIT5 32
#define BIT6 64
#define BIT7 128
#define POWER BIT4|BIT5|BIT6|BIT7
#define clear_disp send_lcd(BIT0,0);uwait(1640)
#define change_line send_lcd(BIT7|0x40,0)
void uwait(int);
void init_lcd(void);
void e_control(void);
void e_rs_control(void);
void send_lcd(unsigned char,unsigned char);
void put_data(unsigned char);
void str_data(char*);
int main(int argc,char* argv[]){
int i;
ioperm(0x80,1,1);
ioperm(BASEPORT,3,1);
init_lcd();
if(argc>1)str_data(argv[1]);
else str_data("LINUX LCD Display software.");
return 0;
}
//マイクロ秒単位でウェイトを行う
void uwait(int utime){
//ポート0x80にアクセスすると1マイクロ秒かかる
for(;utime>0;utime--)outb(0,0x80);
}
//LCD 初期化
void init_lcd(void){
outb_p(POWER,BASEPORT); //power on
outb_p(BIT1|BIT3,BASEPORT+2); //E = R/W = RS = 0
outb_p(BIT0|BIT1|POWER,BASEPORT); //DB4 = DB5 = 1
uwait(15000); //wait 15 m
e_control();
uwait(5000); //wait 4.1 ms
e_control();
uwait(100); //wait 100 us
e_control();
//4bit mode
outb_p(BIT1|POWER,BASEPORT);
e_control();
//function set
send_lcd(BIT5|BIT3,0);
//display set
send_lcd(BIT3|BIT2,0);
//display on
send_lcd(BIT0,0);
uwait(1640); //wait 1.64 ms
//entry mode = increment with display shift
send_lcd(BIT2|BIT1,0);
}
//LCD ヘ転送
void send_lcd(unsigned char value,unsigned char offset){
outb_p((value>>4)|POWER,BASEPORT+offset);
e_control();
outb_p((value&0xF)|POWER,BASEPORT+offset);
e_control();
}
//LCD ヘ転送
void put_data(unsigned char value){
outb_p((value>>4)|POWER,BASEPORT);
e_rs_control();
outb_p((value&0xF)|POWER,BASEPORT);
e_rs_control();
}
//文字列転送
void str_data(char* string){
char i,j,len;
clear_disp;
len=strlen(string);
for(i=0;i<len;i++){
if(i==16)change_line;
if(string[i]<0x10)put_data(' ');
else put_data(string[i]);
}
}
void e_control(void){
uwait(10);
outb_p(BIT3,BASEPORT+2); //E = 1
uwait(10);
outb_p(BIT1|BIT3,BASEPORT+2); //E = 0
uwait(10);
}
void e_rs_control(void){
uwait(10);
outb_p(0,BASEPORT+2); //E = RS = 1
uwait(10);
outb_p(BIT1|BIT3,BASEPORT+2); //E = RS = 0
uwait(10);
}
ioperm(BASEPORT,3,1)は<unistd.h>で宣言されており、BASEPORT(0x3BC or 0x378 or 0x278)ポートから3ポートを使いますよと伝達している。