AQM0802A は I2C通信の 2行表示 LCDである
動作は 3.3Vになるので、双方向バッファを使う
ATmega328 を使う
I2C通信LCDは アルドィーノ等での 動作プログラムサンプルはネットでよく見かけるが、
直接 AVRでコントロールしている例が見つからないので 自分で作る
AQM0802LCDは、変換基板があるので使った方がよいだろう。
SDLとSCLは どちらかの基板で プルアップしておく。
RESET端子は VCCに接続しておく。(RESET=XRESETB)
プログラム
LCDは 最初に初期設定を行う
その後、表示させる場所をきめて、表示データを送る
開始条件を設定し、LCDアドレスーー> コマンドーー>データーー> 終了
このように動作させる
//メインプログラム
aqm_put_str("430M SSB");
aqm_position(2,1);
aqm_put_str("30W");
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
イニシャルプログラム
void AQM_ID(void)
{
/* 開始条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTA) |(1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
TWDR=0x7C; //AQM0802 アドレス
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x00; //00 コマンド
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x38; //Funvtion set
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x39; //Function SET
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x14; //OSC frecency
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x73; //3.3V=0x73 5V=0x7A
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x56; //3.3V=0x56 5v=0x54
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x6C; //Fllow control
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_ms(20);
TWDR=0x38; //Function set
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x0C; //Disp ON
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x01; //Clear Disp
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
/* 停止条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTO) |(1<<TWEN);
//終了したので 受信モードに入る
wait_ms(2);
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
結構イニシャルは長いが、最初に設定する
次は データの表示を行う
表示場所の設定は
TWDR=0x7C; //AQM0802A アドレス
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x80; //行設定 コマンド
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0xC0; //2行目 (80|40)=C0
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
ーーーーーーーーー
2行目が 何故 0XC0 になるかは下記になる
0x80 と 0x40 のアンドを取って 2行目の最初は 0XC0になる
下記の Void は、 文字表示、カーソル移動。数値の表示 ASCコード表記のプログラムである
一応これだけあれば、LCD表示はできる
*-----------------------------------------------------------*/
/* AQM08 LCD 文字列表示 */
/* 引数: char *str : 文字列の先頭ポインタ */
/*-----------------------------------------------------------*/
void aqm_put_str(char *str)
{
/* 開始条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTA) |(1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
TWDR=0x7C; //AQM0802A アドレス
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x40; //表示 コマンド
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
while(*str != 0) {
TWDR=*str; //C
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
str++;
}
/* 停止条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTO) |(1<<TWEN);
wait_ms(2);
}
// AQM0802A カーソルポジション ----------------------
void aqm_position(char tx ,char ty)
{
switch(ty){
case 0: ty = 0x00; break;
case 1: ty = 0x40; break;
// case 2: ty = 0x14; break;
// case 3: ty = 0x54; break;
}
TWCR = (1<<TWINT)|(1<<TWSTA) |(1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
TWDR=0x7C; //AQM0802A アドレス
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x80; //行設定 コマンド
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=(0x80 | (tx + ty)); //2行目 (80|40)=C0
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
/* 停止条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTO) |(1<<TWEN);
wait_ms(2);
}
//----- AQM0802 ASC表示----------------------
void aqm_asc(unsigned short data ) // ASC 表示
{
unsigned char temp;
unsigned char temp1;
temp1 = data & 0x0F;
temp = data >> 4;
if(temp > 9){temp=temp-9,(temp |= 0x40);
}else{(temp |= 0x30);}
if(temp1 > 9){temp1=temp1-9,(temp1 |= 0x40);
}else{(temp1 |= 0x30);}
/* 開始条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTA) |(1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
TWDR=0x7C; //AQM0802A アドレス
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x40; //表示 コマンド
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=(temp); //
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=(temp1); //
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
/* 停止条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTO) |(1<<TWEN);
wait_ms(2);
}
//----AQM0802A 数値表示---------------------------------
void aqm_dataout( unsigned short data ) // 数値データをLCDに表示する関数)
{ // 表示出来る数値は 受け取る引数unsigned short dataのデータ型範囲
unsigned char temp; // unsigned char :( 0-255), unsigned short:(0-65535), unsigned long :(0-4294967295)
char strtemp[ 5 ]; // 文字コードの格納変数を定義
int i, k;
i=0; // unsigned charのとき:strtemp[ 3 ] (3桁), unsigned short:strtemp[ 5 ](5桁)
// unsigned long:strtemp[ 10 ](10桁)
do { //
temp = data % 10; // 下位の桁から数字を抽出
strtemp[i++] = temp + '0'; // 数字を文字コードに変換
} while (( data /= 10 ) != 0); // 数値の桁数までループ
i--; //
/* 開始条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTA) |(1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
TWDR=0x7C; //AQM0802A アドレス
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
TWDR=0x40; //表示 コマンド
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
for( k=i; k>=0; k-- ) { // 上位の桁から順次
// lcd_put_8bit( strtemp[k]); // 数値文字を表示
TWDR=(strtemp[k]); //
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); //;TWINT=1まで待機
wait_us(27);
}
/* 停止条件送出*/
TWCR = (1<<TWINT)|(1<<TWSTO) |(1<<TWEN);
wait_ms(2); //
}