I2C接続LCD

| ピン | 信号名 | 意味 |
| 1 | VCC | 5V |
| 2 | GND | GND |
| 3 | VO | コントラスト |
| 4 | RS | 1:制御、0:データ |
| 5 | R/W | 1で読み、0で書き込み |
| 6 | E(stb) | データ同期用パルス |
| 7−10 | BD0-DB3 | 下位データ |
| 11−14 | BD4-BD7 | 上位データ |


文字位置指定:<lcdda><1><x><y><0> ;x=1..16 y=1,2 文字列表示 :<lcdda><2><char_1>..<char_n><0> クリア :<lcdda><3><0>
//I2C Slave
//Display to LCD
//SD1602:16chara * 2
//LCD data:DB7:14> RB3,DB6:13> RB2,DB5:12> RB1,DB4:11> RB0
//LCD E:6>RA0,RW:5>RA1,RS:4>RA2,
//send address:<lcdda><1><x><y><0>
//send string :<lcdda><2><char_1>..<char_n><0>
//clear lcd:<lcdda><3><0>
//send command:<lcdda><4><command><para><0>
#include <16F873A.h>
#include <stdlib.h>
#fuses HS,NOWDT,NOLVP,NOBROWNOUT
#use delay(clock = 20000000)
//#use I2c(slave,sda=PIN_C4,scl=PIN_C3,address=0x74,no_stretch,FORCE_HW)//address must be EvenNumber
#use I2c(slave,sda=PIN_C4,scl=PIN_C3,address=0x74,no_stretch,FORCE_HW)
#define LineMax 16
//LCD connection
//#byte db = 6 // PORTB address
#define Amode 0xF0 //Aport I/O
#define rs PIN_A2 //chip select
#define rw PIN_A1 //read/write
#define stb PIN_A0 //E strobe
void outchbuf(int i);
void lcd_init();//-------- initialize
void lcd_ready();//------- busy check
void lcd_cmd(cmd);//------ send command
void lcd_data(string);//-- display string
void lcd_clear(); //------ clear display
int lcd_status(); //
int ch2;
int state,done;
int cp,lpcnt;
int alt;
int ddcm;
char chbuf[17]={2,'w','a','t','i','n','g','\0'};
#INT_SSP
void ssp_interupt (){
output_toggle(PIN_C7);
state=i2c_isr_state();
//output_high(PIN_A3);//backLight on
if(state>=0x80){//addrs match with master read
}
else if(state >0){//adrs match with master write
ch2=i2c_read();
chbuf[cp++]=ch2;
if(cp > LineMax) cp--;
if (ch2=='\0') {
//output_toggle(PIN_A3);//check
cp=0;
done=1;
}
}
}
void main (){
delay_ms(200);
cp=0;
alt=0;
done=0;
lpcnt=0;
output_low(stb);
output_low(rs);
lcd_init();//set 4bit mode
lcd_clear();
enable_interrupts(INT_SSP); //SSP割り込みを許可
enable_interrupts(GLOBAL); //全ての割り込みを許可
lcd_cmd(0x80);//1 line
lcd_data("helloo");
lcd_cmd(0xC0);//2 line
lcd_data("wait");
while (1) {
//lcd_cmd(0x80);//1 line
//lcd_data("hello");
if(done){
switch(chbuf[0]){
case 1:ddcm=0x80 + chbuf[1]-1;//firstLine
if (chbuf[2]==2) ddcm += 0x40;
lcd_cmd(ddcm);//行アドレス
break;
case 2 ://文字列
outchbuf(1);
break;
case 3:lcd_cmd(0x1);//clear
break;
case 4:lcd_cmd(chbuf[1]);
outchbuf(2);
break;
//done=0;
}
} //if
//lpcnt++;
done=0;
delay_ms(10);
}
}
void outchbuf(int i){
while(chbuf[i] != 0){
lcd_data(chbuf[i]);
i++;
}
}
//lcd command out for init
void lcd_incmd(int cmd){
//db = cmd; //mode command
output_b(cmd);
output_low(rw); //set write
output_low(rs); //set rs low
output_high(stb); //strobe
output_low(stb);
delay_us(100);
}
//initialize LCD
//set 4bit mode
void lcd_init(){
delay_ms(15);
lcd_incmd(0x30); //8bit mode set
delay_ms(5);
lcd_incmd(0x30); //8bit mode set
delay_ms(5);
lcd_incmd(0x30); //8bit mode set
delay_ms(5);
lcd_incmd(0x20); //4bit mode set
delay_ms(5);
lcd_cmd(0x2C); //DL=0 4bit mode
lcd_cmd(0x08); //display off C=D=B=0
lcd_cmd(0x0C); //display on C=D=1 B=0
lcd_cmd(0x06); //entry I/D=1 S=0
//delay_ms(2);
while(bit_test(lcd_status(),7));
}
//send data to LCD
void lcd_data(int asci){
//db = asci>>4 ; //set upper data
output_b(asci>>4);
output_low(rw); //set write
output_high(rs); //set rs high
output_high(stb); //strobe
output_low(stb);
//db = asci; //set lower data
output_b(asci);
output_high(stb); //strobe
output_low(stb);
//delay_us(50);
while(bit_test(lcd_status(),7));//check busy
}
//read status
int lcd_status(){
int high,low;
set_tris_b(Amode | 0x0F); //set input mode
output_low(rs);
output_high(rw);//read mode
output_high(stb);
//high=db & 0xF;//input A ,read upper
high=input_b()&0XF;
output_low(stb);
delay_us(10);
output_high(stb);
//low=db & 0xF; //inputA ,read lower
low=input_b()&0XF;
output_low(stb);
set_tris_b(Amode);
return(high<<4 | (low)); //return status
}
//send command
void lcd_cmd(int cmd){
//db = cmd>>4 ; //set upper data & set PA4=0
output_b(cmd>>4 );
output_low(rw); //set write
output_low(rs); //set rs low
output_high(stb); //strobe
output_low(stb);
//db = cmd; //set lower data
output_b(cmd );
output_high(stb); //strobe
output_low(stb);
while(bit_test(lcd_status(),7));
}
// clear display clear function
void lcd_clear(){
lcd_cmd(1); //initialize command
//delay_ms(10);
lcd_cmd(2);
while(bit_test(lcd_status(),7));
}
//////////////////////////////////////////////////
// I2Cマスターテストプログラム //
//LCD制御
//I2Cデバイスアドレスは0x74
//コマンド
//send address:<lcdda><1><x><y><0>
//send string :<lcdda><2><char_1>..<char_n><0>
//clear lcd:<lcdda><3><0>
//send command:<lcdda><4><command><para><0>
//マスタの回路は、C4,C3をI2C接続
//ポートB、A0 をLED表示(動作確認用)
#include <16f873a.h>
#include <stdlib.h>
//#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock = 20000000)
#use i2c(MASTER,sda=PIN_C4,scl=PIN_C3,FORCE_HW)
//メイン関数/////////////////////////////////////////
#define lcddva 0x74
int i,val;
int tm,num;
int32 loopcnt;
char moji1[]="Hai:";
char moji2[]="num :";
char numbuf[6];
char lbuf[15];
void main(){
val=0;
tm=0;
loopcnt=0;
//set_tris_c(0x99); //RB 7-4:IN 3-0:OUT
output_float(PIN_C3); //I2C pin float
output_float(PIN_C4); //I2C pin float
//Cポートに出力する場合、set_tris_c()が必要
delay_ms(300); //wait for Client up
i2c_start(); //clear
i2c_write(lcddva);
i2c_write(3);
i2c_write(0);
i2c_stop();
delay_ms(50);
while(1){
output_toggle(PIN_A0);//動作確認
i2c_start(); //clear
i2c_write(lcddva);
i2c_write(3);
i2c_write(0);
i2c_stop();
delay_ms(100);
//-----------------------------------
itoa(loopcnt,10,numbuf);
strcpy(lbuf,moji1);
strcat(lbuf,numbuf);
i2c_start();
i2c_write(lcddva);
i2c_write(1);//コマンド
i2c_write(4);//x
i2c_write(1);//y
i2c_write(0);
i2c_stop();
delay_ms(10);
itoa(loopcnt,10,numbuf);
strcpy(lbuf,moji2);
strcat(lbuf,numbuf);
i2c_start();
i2c_write(lcddva);
i2c_write(2 );
for(i=0;i<=strlen(lbuf);i++){
i2c_write(lbuf[i] );
//delay_ms(1);
}
//i2c_write(0);
i2c_stop();
delay_ms(20);
//------------------------------------
i2c_start();
i2c_write(lcddva);
i2c_write(1);//コマンド
i2c_write(2);//x
i2c_write(2);//y
i2c_write(0);;
i2c_stop();
delay_ms(10);
i2c_start();
i2c_write(lcddva);
i2c_write(2 );
for(i=0;i<=strlen(lbuf);i++){
i2c_write(lbuf[i] );
//delay_ms(1);
}
i2c_stop();
delay_ms(20);
//------------------------------------
i2c_start();
i2c_write(lcddva);
i2c_write(1);//コマンド
i2c_write(12);//x
i2c_write(2);//y
i2c_write(0);;
i2c_stop();
delay_ms(10);
i2c_start();
i2c_write(lcddva);
i2c_write(2 );
for(i=0;i<=strlen(moji1);i++){
i2c_write(moji1[i] );
}
i2c_stop();
delay_ms(10);
loopcnt++;
delay_ms(400);
}
}