*[[キャラクタ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カーネルではないので、意味ないかもしれませんが)
<

お疲れ様でした。

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS