トップページ > 電子工作インデックス > テトリス > 10. LCD制御関数

10. LCD制御関数

グローバル変数のscoreとhigh_scoreを読んで、それを液晶ディスプレイ (Liquid Crystal Display、以下LCD) に出力する関数です。scoreは1列消去関数のところで書きかえています。 LCDは秋月さんで売っているキャラクタ2行のものを使用しています。4ビットモードです。

ハードの仕様についてですが、今回はH8のポート6を使うことにしました。 ビット0〜3が4ビットデータ出力ピン、ビット4は表示する文字データなのかLCDに対する 制御データなのかを知らせるRS(Resiser Select)ピン、ビット6は書き込みタイミングを知らせる E(Enable)ピンとしています。ビット5を使っていないのは、製作途中に誤って破壊してしまったから なので、特に意味があってやっているわけではありません(汗)

準備(1) データ送信関数

4ビットデータを出力し、Eピンを"0"→"1"とするとデータが書き込まれます。 この際、RSピンが"0"なら制御信号、"1"なら文字データ(ASCIIコード)とみなされます。


//********************************************************************
//文字データ(8ビット)を受け取って、液晶に1文字表示させる関数

void lcd_char_trans(char data)
{

 //転送データの写しを作っておきます。
 cahr data_temp;
 data_temp = data;

 //文字データなので、RSピンは"1"にしておきます。
 P6.DR.BIT.B4 = 1;  
 p6.DR.BIT.B6 = 0;

 //先に上位4ビットを出力します。
 data = data >> 4;
 data = data&0x0f;

 P6.DR.BYTE = data;

 //Eピンの立ち上がりで書き込み
 P6.DR.BIT.B6 = 1
 lcd_wait();
 P6.DR.BIT.B6 = 0;


 //念のためウェイト入れときます。
 lcd_wait();



 //次は下位4ビットを出力。
 data_temp = (data_temp & 0x0f)

 P6.DR.BYTE = data_temp;
 
 //Eピンの立ち上がりで書き込み
 P6.DR.BIT.B6 = 1
 lcd_wait();
 P6.DR.BIT.B6 = 0;


 //念のためウェイト入れときます。
 lcd_wait();




}



//********************************************************************
//lcdをコントロールするデータを送る関数です。
//実際のところ下位4ビットのみしか効かないのですが…。

void lcd_data_trans(char data)
{

 //制御データなので、RSピンは"0"にしておきます。
 P6.DR.BIT.B4 = 0;  
 p6.DR.BIT.B6 = 0;

 
 P6.DR.BYTE = data;

 //Eピンの立ち上がりで書き込み
 P6.DR.BIT.B6 = 1
 lcd_wait();
 P6.DR.BIT.B6 = 0;

 //念のためウェイト入れときます。
 lcd_wait();

}

//********************************************************************

準備(2) 文字列送信関数

配列に文字列データを入れて、それを渡します。前述のlcd_char_trans()関数を使っています。 このLCDは1文字送信するごとに、自動で文字の横座標を1インクリメントしてくれるので、 いろいろ難しいことを考えないで使うことができます。


//********************************************************************
//文字列(配列に格納したもの)を受けて、それを表示します。
//前もってposition()関数で表示開始位置を指定しておく必要があります。

void lcd_string_out(char *string)           
{
 
 //文字列の最後(ヌル文字)までループ
 while(*string != '\0')
 {
  //1文字表示関数を呼び出します。
  lcd_char_trans(*str);
  
  //次の文字を読み込みます。(配列はアドレスの値が連続しているから…。)
  str++;
 }
} 
//********************************************************************

準備(3) 文字を表示する位置を決める関数



//********************************************************************
//文字の表示開始位置を決める関数

//yに0x08を入れると1行目が選択され、0x0cを入れると2行目が選択されます
//yについては関数を呼び出す側で調整してください…。
//xはただ数を入れるだけでOKです。

void lcd_position(int y,int x)
{
 P6.DR.BYTE=0;
 lcd_data_trans(y);
 lcd_data_trans(x);
  
 lcd_wait();
}
//********************************************************************

準備(4) 画面全消去関数




//********************************************************************
void lcdclear(void)
{
 P6.DR.BYTE=0;
 lcd_data_trans(0);
 lcd_data_trans(1);

}
//********************************************************************

準備(5) LCD初期化関数(4ビットモード用)

付属のデータシートの通りですので特筆事項はありません…。main関数の最初の部分で 呼び出して、初期設定をします。

//********************************************************************

void lcdini(void)
{
  lcd_data_trans(3);
  lcd_data_trans(3);
  lcd_data_trans(3);
  lcd_data_trans(2);
  lcd_data_trans(2);
  lcd_data_trans(8);
  lcd_data_trans(0);
  lcd_data_trans(0x0c);
  lcd_data_trans(0);
  lcd_data_trans(6);
}
//********************************************************************

準備(6) lcd_wait()関数


//********************************************************************
//単なる時間稼ぎ関数です。

void lcd_wait(void)
{
 int t = 1000;
 while(t--);
}

//********************************************************************




ソースコード


//********************************************************************
//ハードウェアの仕様

//液晶はポート6につながっています。

//1〜4番目のピン(P6.DR.BIT.B0〜P6.DR.BIT.B3) → 液晶のデータ
//5番目のピン(P6.DR.BIT.B4) → RSピン
//6番目のピン (P6.DR.BIT.B5) → Eピン

//********************************************************************
//液晶にscoreを表示する関数


int score_out(void)
{
 
 //ハイスコアを更新
 if(highscore<score) high_score = score;

 //計算用にデータを写しておきます
 unsigned long h_temp = highscore;
 unsigned long s_temp = score;

 //LCD表示文字列用の配列を作ります。
 char string1[8];
 char string2[8]; 

 //high_scoreとscoreに記録された数値を文字列に直します。
 //基本アルゴリズム:10で割った余りを配列に格納→10で割る…を繰り返す。 
 for(i=0;i<8;i++)
 {

  //<注意>配列の0番目の要素から順に、一の位、十の位…と入っていきます。
  string1[i] = (char)(h % 10);
  string2[i] = (char)(s % 10);

  h_temp /=10;
  s_temp /=10;
 
 }

 //----------------------------------------------------

 //前のデータを消します。
 lcdclear();

 //----------------------------------------------------
 //一行目にhigh_scoreを表示
 
 lcd_position(0x08,0x00);
 out("max  :");
 for(i=8;i>=0;i--)
 {
  lcdo(s1[i]+'0');
 }

 //-----------------------------------------------------
 //二行目にscoreを表示

 lcd_position(0x0c,0x00);
 out("score:");
 for(i=8;i>=0;i--)
 {
  lcdo(s2[i]+'0');
 }
}     

//********************************************************************
  



前へ   テトリスTOP