PIC ことはじめ ~ LCD を使ってみる

Posted by
ぴろり
Posted at
2013/05/26 13:00
Trackbacks
関連記事 (0)
Post Comment
コメントできます
Category
電子工作 カテゴリ
カバーイメージ

 数字程度の簡単な表示であれば 7 セグメント LED で十分かもしれませんが、アルファベットを表示したり表示する文字が多い場合には、7 セグメント LED で頑張ろうとすると余計に苦労することになります。こういったケースでは、16桁×2行表示程度の LCD を用いると便利です。

このエントリーをはてなブックマークに追加  

 起動してみたところ。画面に"Hello."と表示するだけ。ここを基点にセンサを接続したり色々遊べそう。

準備

 LCD ユニットに対してデータを送るには、決められた手順でポートを操作します。簡単に書けば;

  1. LCD の R/W ポートを L (書き込み)にする
  2. LCD の DB0DB7 ポートに送信したいデータをセットする
  3. LCD の E ポートを L→H→L と切り替える
  4. LCD は H→L の立下りエッジのタイミングで、DB0DB7 ポートを読み取る

 これらの手順は別段、何かのクロックに同期する必要などないので、お手軽にプログラムを書くことができます。
 また、手順 2. では 8 本のポートに 8 ビット分のデータをセットしていますが、これだとデータ線が 8 本も必要になりますが、PIC のように入出力ポートが少ないデバイスを使用する場合、使用するポート数はできるだけ節約したいものです。TC1602 には、4 ビットのデータを 2 回に分けて送受信できるモードが用意されているので、これを使わない手はありません。データ送信の操作を余分に行う分、プログラムが複雑になり、また処理時間を要しますが、これはデータ送信部分を関数化して対処します。また処理時間については、高々ミリ秒オーダーの話ですので、リアルタイム性能を要求されない範囲においては、問題になるようなことはありません。

材料

  • TC1602E LCD ユニット ... マルツで購入。事実上標準の SC1602 という文字表示液晶の互換品なので、ネット上に情報が豊富。
  • PIC16F84A ... LCD ユニットの制御はデジタル I/O だけで行えるので、手元にあった適当な PIC を使ってみる。LCD の制御に最低でも出力 6 ピンを要するので、8 ピン PIC では厳しいかもしれない。

回路図

回路図
BSch3V用回路図データ

説明

  • PIC と LCD の結線は、データ線×4本(RB4RB7)、制御線×2本(RB0RB1)の合計 6 本
  • VR は液晶のコントラスト調整用ボリュームです

ソースコード

#include <pic.h>

#define MHz 000000
#define _XTAL_FREQ      (10MHz)

__CONFIG (
      FOSC_HS       // High Speed Crystal/Resonator
    & WDTE_OFF      // Watchdog Timer: OFF
    & PWRTE_OFF     // Power-up Timer: OFF
    & CP_OFF        // Code Protection: OFF
);

/************************************************************************
    LCD 制御用関数群
************************************************************************/
// LCD と PIC との接続ポートのマッピング
#define LCD_PORT_RS     RB0
#define LCD_PORT_E      RB1

#define LCD_PORT_DB4    RB4
#define LCD_PORT_DB5    RB5
#define LCD_PORT_DB6    RB6
#define LCD_PORT_DB7    RB7

// LCD に 4 ビット分のデータを送信する
static void LcdPut4b (char RS, char data)
{
    LCD_PORT_E = 0;             // Enable Off
    LCD_PORT_RS = RS;           // Control Register

    LCD_PORT_DB4 =  data       & 1;
    LCD_PORT_DB5 = (data >> 1) & 1;
    LCD_PORT_DB6 = (data >> 2) & 1;
    LCD_PORT_DB7 = (data >> 3) & 1;

    LCD_PORT_E = 1;             // Enable On
    NOP ();                     // Wait
    LCD_PORT_E = 0;             // Enable Off
}

// 1 バイトのデータを 2 回に分けて送信する
static void LcdPut (char RS, char data)
{
    LcdPut4b (RS, data >> 4);   // 先ず上位 4 ビットを送信
    LcdPut4b (RS, data     );   // 次に下位 4 ビットを送信
}

#define LCD_PUT_CTRL    0
#define LCD_PUT_DATA    1
// 1 バイトの制御データを送信する
static void LcdCtrl (char ctrl) { LcdPut (LCD_PUT_CTRL, ctrl); }
// 1 バイトの文字データを送信する
static void LcdData (char data) { LcdPut (LCD_PUT_DATA, data); }

// 液晶の初期化
static void LcdInitialize (void)
{
    // 電源投入後、しばらく待つ
    __delay_ms (15);

    // LCD の初期状態がわからないので、強制的に 8bit 通信モードにするオマジナイ
    LcdPut4b (LCD_PUT_CTRL, 0b0011); __delay_ms (5);
    LcdPut4b (LCD_PUT_CTRL, 0b0011); __delay_us (100);
    LcdPut4b (LCD_PUT_CTRL, 0b0011); __delay_ms (5);
    // これで確実に 4bit 通信モードに設定できる
    LcdPut4b (LCD_PUT_CTRL, 0b0010); __delay_us (40);

    // 2lines, 5x8dots
    LcdCtrl (0b00101000); __delay_us (40);
    // Display On, Cursor On, Blink On
    LcdCtrl (0b00001111); __delay_us (40);
    // Clear Display
    LcdCtrl (0b00000001); __delay_ms (5);
    // Entry Mode
    LcdCtrl (0b00000110); __delay_us (40);
    // カーソル位置を設定
    LcdCtrl (0b10000000); __delay_us (40);
}
    
/************************************************************************
    LCD 制御用関数群
************************************************************************/
// PIC の初期化
static void Initialize (void)
{
    TRISB = 0;      //とりあえず全部のポートをデジタル出力に
}

// main
void main (void)
{
    Initialize ();
    LcdInitialize ();
    
    // テスト文字列表示
    LcdData ('H'); __delay_us (40);
    LcdData ('e'); __delay_us (40);
    LcdData ('l'); __delay_us (40);
    LcdData ('l'); __delay_us (40);
    LcdData ('o'); __delay_us (40);
    LcdData ('.'); __delay_us (40);

    while (1);
}

説明

  • 起動すると LCD に"Hello."と表示します
  • LCD へ 4 ビット分のデータを送信する手順をカプセル化しています(LcdPut4b)
  • 4 ビットでデータを扱うのは面倒なので、1 バイト分のデータを送信する手順をカプセル化しています(LcdPut)
  • 制御モードと通常モード(?)でデータを送信するための関数を用意しています(LcdCtrlLcdData)
  • データ送信後のウェイトを含めて関数化したりと色々考えられますが、そのあたりは好みで
このエントリーをはてなブックマークに追加  


更新履歴

Updated at
2013/05/27 07:45
更新メモ
r7 準備セクションを修正

この記事を読んだ人はこんな記事も読んでいます記事リコメンデーションについて

カバー画像:PIC ことはじめ ~ 7 セグメント LED を使う

関連記事/トラックバック

関連記事/トラックバックはまだありません

この記事にトラックバックを送るには?

コメントを投稿する

 
 (必須, 匿名可, 公開, トリップが使えます)
 (必須, 匿名可, 非公開, Gravatar に対応しています)
 (必須)
スパム コメント防止のため「投稿確認」欄に ランダムな数字 CAPTCHAについて を入力してから送信してください。お手数ですがご協力のほど宜しくお願いいたします。