数字程度の簡単な表示であれば 7 セグメント LED で十分かもしれませんが、アルファベットを表示したり表示する文字が多い場合には、7 セグメント LED で頑張ろうとすると余計に苦労することになります。こういったケースでは、16桁×2行表示程度の LCD を用いると便利です。
起動してみたところ。画面に"
Hello.
"と表示するだけ。ここを基点にセンサを接続したり色々遊べそう。
LCD ユニットに対してデータを送るには、決められた手順でポートを操作します。簡単に書けば;
これらの手順は別段、何かのクロックに同期する必要などないので、お手軽にプログラムを書くことができます。
また、手順 2. では 8 本のポートに 8 ビット分のデータをセットしていますが、これだとデータ線が 8 本も必要になりますが、PIC のように入出力ポートが少ないデバイスを使用する場合、使用するポート数はできるだけ節約したいものです。TC1602 には、4 ビットのデータを 2 回に分けて送受信できるモードが用意されているので、これを使わない手はありません。データ送信の操作を余分に行う分、プログラムが複雑になり、また処理時間を要しますが、これはデータ送信部分を関数化して対処します。また処理時間については、高々ミリ秒オーダーの話ですので、リアルタイム性能を要求されない範囲においては、問題になるようなことはありません。
#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); }
Hello.
"と表示します