*[[キャラクタLCDをアクセス]] [#m5789035] **はじめに [#e7e50907] > >Raspberry Pi 3でCentOS7からのキャラクタLCDへのアクセス方法をまとめました。~ 過去の資産(秋月のLCD)が何個jかありますので、これらのアクセスについて記します。 < **HD44780互換IC系 [#u0dd2208] ***概要 [#l63c5a03] > >パラレルバスインタフェースといえばこの系統が主流ですね。往年の68系バスに接続するインタフェース仕様です。~ 8ビット以外に4ビットでのアクセスが可能ですが、どうしてもData(4)+E+R/W*RSで最低、7本のインタフェースが必要になります。 #ref(SC1602BSLB.jpg,around,zoom) #ref(sc1602bslb_pin_assign.jpg,zoom) < ***基本方針 [#cd5f269c] > >ピン数の節約のため、4bitモードででアクセスし必要なソフトはCで作成することにします。 < ***ハードウェア [#m86d0dca] -ピンアサイン > >まず、ピンの割り当てですが、他の機能と併用されていないピンを使用することにします。~ 電源はRaspberryPiの3.3Vを使用します。PINのラッチアップ等を避けるため、同一電源とします。 |>|Raspberry Pi| |>|LCD |h |Signal|Pin#|BGCOLOR(#663300): |Signal|Pin#| |3V3|01,17|BGCOLOR(#663300): |3V3|01| |GND|34,39|BGCOLOR(#663300): |GND|02| | | |BGCOLOR(#663300): |VO(contrast)|03| |GPIO 21|40|BGCOLOR(#663300): |E|06| |GPIO 22|15|BGCOLOR(#663300): |R/_W|05| |GPIO 23|16|BGCOLOR(#663300): |RS|04| |GPIO 24|18|BGCOLOR(#663300): |D4|11| |GPIO 25|22|BGCOLOR(#663300): |D5|12| |GPIO 26|37|BGCOLOR(#663300): |D6|13| |GPIO 27|13|BGCOLOR(#663300): |D7|14| < > -PullUp/Pulldown < > >信号の衝突を避けるため、R/_W、EはPulldownを行います。~ また、コントラスト調整(VO)は20kΩのVRにより電位を調整するようにします。 < ***ソフトウェア [#j396b47f] -概要 > >Read/Write用の関数を作成してアクセスすることになります。~ たとえば >> >>void lcd_init( void );~ void lcd_write( int mode, int data );~ int lcd_read( int mode, init data ); << >基本として、各種のコマンドを作成することとします。上記の関数を利用して >> >>void lcd_set_position( int x, int y );~ void lcd_put_char( int char );~ void lcd_clear( void );~ void lcd_print( int line, char *str ); << >位を用意すれば良いでしょう。~ 実際はリード系のコマンドは不要と思いますが。 < -実装 > >テストのつもりでコーディングします。 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HD44780/SC1602 LCDモジュール(16 x 2) 秋月版 制御TP // このTPでは、2行表示に対して、これぞれの行に文字を表示します。 // 基本的に16文字固定表示でスクロールはしません。カーソルも表示しません。 // // コンパイル方法 // gcc -o lcd_test lcd_test.c -l bcm2835 // // copyright (c) 2016 Kazuhiro WATANABE All right reserved. // mailto:jj1req@ca.mbn.or.jp // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include <bcm2835.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // キャラクタ液晶ディスプレーへの接続 #define LCD_E 21 #define LCD_R_W 22 #define LCD_RS 23 #define LCD_DB4 24 #define LCD_DB5 25 #define LCD_DB6 26 #define LCD_DB7 27 //****************************************************************************** //* LCDモジュールに対してストローブをかけます(E端子ストローブ) //* //* Function Name //* void lcd_strobe( void ) //* Arguments //* none //* Return //* none //* //****************************************************************************** void lcd_strobe( void ) { bcm2835_delayMicroseconds( 1LL ); bcm2835_gpio_write( LCD_E, HIGH ); bcm2835_delayMicroseconds( 1LL ); bcm2835_gpio_write( LCD_E, LOW ); } //****************************************************************************** //* LCDモジュールに対して表示のクリアを行います //* //* Function Name //* void lcd_clear( void ) //* Arguments //* none //* Return //* none //* //****************************************************************************** void lcd_clear( void ) { // Display OFF 0000 1000 bcm2835_gpio_write( LCD_DB7, LOW ); bcm2835_gpio_write( LCD_DB6, LOW ); bcm2835_gpio_write( LCD_DB5, LOW ); bcm2835_gpio_write( LCD_DB4, LOW ); bcm2835_gpio_write( LCD_RS, LOW ); bcm2835_gpio_write( LCD_R_W, LOW ); lcd_strobe(); bcm2835_gpio_write( LCD_DB7, HIGH ); lcd_strobe(); bcm2835_delayMicroseconds( 40LL ); // Display clear 0000 0001 bcm2835_gpio_write( LCD_DB7, LOW ); lcd_strobe(); bcm2835_gpio_write( LCD_DB4, HIGH ); lcd_strobe(); // Entry Mode set 0000 0110 bcm2835_gpio_write( LCD_DB4, LOW ); lcd_strobe(); bcm2835_gpio_write( LCD_DB6, HIGH ); bcm2835_gpio_write( LCD_DB5, HIGH ); lcd_strobe(); bcm2835_delayMicroseconds( 40LL ); } //****************************************************************************** //* LCDモジュールに対して初期化を行います //* //* Function Name //* void lcd_init( void ) //* Arguments //* none //* Return //* none //* //****************************************************************************** void lcd_init( void ) { // ライブラリ初期化 if( !bcm2835_init() ) { printf( "bcm2835 library initialize error!!\n" ); exit(1); } // I/O ピンの初期化 bcm2835_gpio_fsel( LCD_DB4, BCM2835_GPIO_FSEL_INPT ); bcm2835_gpio_set_pud( LCD_DB4, BCM2835_GPIO_PUD_UP ); bcm2835_gpio_fsel( LCD_DB5, BCM2835_GPIO_FSEL_INPT ); bcm2835_gpio_set_pud( LCD_DB5, BCM2835_GPIO_PUD_UP ); bcm2835_gpio_fsel( LCD_DB6, BCM2835_GPIO_FSEL_INPT ); bcm2835_gpio_set_pud( LCD_DB6, BCM2835_GPIO_PUD_UP ); bcm2835_gpio_fsel( LCD_DB7, BCM2835_GPIO_FSEL_INPT ); bcm2835_gpio_set_pud( LCD_DB7, BCM2835_GPIO_PUD_UP ); bcm2835_gpio_fsel( LCD_RS, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_set_pud( LCD_RS, BCM2835_GPIO_PUD_DOWN ); bcm2835_gpio_write( LCD_RS, LOW ); bcm2835_gpio_fsel( LCD_R_W, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_set_pud( LCD_R_W, BCM2835_GPIO_PUD_DOWN ); bcm2835_gpio_write( LCD_R_W, LOW ); bcm2835_gpio_fsel( LCD_E, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_set_pud( LCD_E, BCM2835_GPIO_PUD_DOWN ); bcm2835_gpio_write( LCD_E, LOW ); // 初期化フェーズ1 bcm2835_gpio_write( LCD_DB7, LOW ); bcm2835_gpio_write( LCD_DB6, LOW ); bcm2835_gpio_write( LCD_DB5, HIGH ); bcm2835_gpio_write( LCD_DB4, HIGH ); bcm2835_gpio_write( LCD_E, HIGH ); lcd_strobe(); bcm2835_delay( 5 ); // 初期化フェーズ2 lcd_strobe(); bcm2835_delayMicroseconds( 100LL ); // 初期化フェーズ3 lcd_strobe(); // 初期化フェーズ4 bcm2835_gpio_write( LCD_DB4, LOW ); lcd_strobe(); // ファンクション設定( 2 Line 5×10 dots) lcd_strobe(); bcm2835_gpio_write( LCD_DB7, HIGH ); bcm2835_gpio_write( LCD_DB6, HIGH ); lcd_strobe(); bcm2835_delayMicroseconds( 40LL ); // 通常のクリア処理 lcd_clear(); } //****************************************************************************** //* LCDモジュールにデータ/コマンドの書き込みを行います //* //* Function Name //* void lcd_write( int rs, unsigned char data ) //* Arguments //* int rs register select 0:command, 1: data //* unsigned char data byte data //* Return //* none //* //****************************************************************************** void lcd_write( int rs, unsigned char data ) { bcm2835_gpio_write( LCD_R_W, LOW ); bcm2835_gpio_write( LCD_RS, rs ); bcm2835_gpio_write( LCD_DB7, (data >> 7) & 0x01 ); bcm2835_gpio_write( LCD_DB6, (data >> 6) & 0x01 ); bcm2835_gpio_write( LCD_DB5, (data >> 5) & 0x01 ); bcm2835_gpio_write( LCD_DB4, (data >> 4) & 0x01 ); lcd_strobe(); bcm2835_gpio_write( LCD_DB7, (data >> 3) & 0x01 ); bcm2835_gpio_write( LCD_DB6, (data >> 2) & 0x01 ); bcm2835_gpio_write( LCD_DB5, (data >> 1) & 0x01 ); bcm2835_gpio_write( LCD_DB4, data & 0x01 ); lcd_strobe(); bcm2835_delayMicroseconds( 40LL ); } //****************************************************************************** //* LCDモジュールに文字列を表示します。 //* //* Function Name //* void lcd_print( int line, char *str ) //* Arguments //* int line target position 0:first line, 1:second line //* char *str string data //* Return //* none //* //****************************************************************************** void lcd_print( int line, char *str ) { int i; int data; data = (line * 0x40) || 0x80; lcd_write( 0, data ); for( i=0; i<16; i++) { lcd_write( 1, 0x20 ); } data = (line * 0x40) || 0x80; lcd_write( 0, data ); for( i=0; i<strlen(str); i++ ) { lcd_write( 1, (unsigned char)str[i] ); } } int main(int argc, char **argv) { lcd_init(); lcd_print( 0, "test123" ); lcd_print( 1, "########" ); return( 0 ); } < ***テスト [#re19c440] > >サンプルのLEDチカチカがありますので、テストします。~ LEDはGPIO-17(コネクタP1の11)に接続し、1秒間隔で点滅(ON:500ms、OFF:500ms)します。 # cd examples/ # cd blink/ # gcc blink.c -o blink_led -l rt -l bcm2835 # ./blink_led < > >※-l rt は[[real-time extensions>http://devlib.symbian.slions.net/belle/GUID-E21287EF-7211-590B-A1E3-E0B37069FCB2.html]]です。(RTカーネルではないので、意味ないかもしれませんが) < お疲れ様でした。