キャラクタLCDをアクセス
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
*[[キャラクタLCDをアクセス]] [#m5789035]
**はじめに [#e7e50907]
>
>Raspberry Pi 3でCentOS7からのキャラクタLCDへのアクセス方...
秋月電子で扱っているI2Cインタフェースかつ3.3V品ということ...
結果的には、まさかこんなものでというぐらい、大変苦労する...
<
**HD44780互換IC系 その1 Sitronix ST7032 [#u0dd2208]
***概要 [#l63c5a03]
>
>キャラクタディスプレイといえば、この系統が主流ですね。往...
今回は、Sitronix ST7032というチップのものです。パラレル、...
#ref(K-08896.jpg,around,zoom)
#ref(ST7032-1.jpg,zoom)
<
***ハードウェア [#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|04|
|I2C SDA.1|03|BGCOLOR(#663300): |SDA|03|
|I2C SCL.1|05|BGCOLOR(#663300): |SCL|02|
<
>
>>
<<
<
***ソフトウェア [#j396b47f]
-概要
>
>Read/Write用の関数を作成してアクセスすることになります。~
たとえば
>>
>>void lcd_init( void );~
int lcd_write_command( char command );~
int lcd_write_data( char data);
<<
>を基本として、各種のコマンドを作成することとします。上記...
>>
>>void lcd_clear( void );~
void lcd_print( int line, char *str );
<<
>位を用意すれば良いでしょう。
<
-実装
>
>テストのつもりでコーディングします。
//------------------------------------------------------...
// ST7032 LCDモジュール(16 x 2) 秋月版 制御TP
// このTPでは、2行表示に対して、これぞれの行に文字を表示...
// 基本的に16文字固定表示でスクロールはしません。
//
// コンパイル方法
// gcc -o i2c_lcd_test_st7032 i2c_lcd_test_st7032.c -l ...
//
// copyright (c) 2016 Kazuhiro WATANABE All right reserv...
// mailto:jj1req@ca.mbn.or.jp
//
//------------------------------------------------------...
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// BCM2835のI2Cクロック周波数の設定値
// BCM2835_I2C_CLOCK_DIVIDER_2500 2500 = 10us = 100 kHz(...
// BCM2835_I2C_CLOCK_DIVIDER_626 622 = 2.504us = 399.36...
// BCM2835_I2C_CLOCK_DIVIDER_15 150 = 60ns = 1.666 MHz ...
// BCM2835_I2C_CLOCK_DIVIDER_148 148 = 59ns = 1.689 MHz
#define CLK_DIV BCM2835_I2C_CLOCK_DIVIDER_2500
//#define CLK_DIV BCM2835_I2C_CLOCK_DIVIDER_148
//#define CLK_DIV BCM2835_I2C_CLOCK_DIVIDER_626
//
// キャラクタ液晶ディスプレーへの接続
#define LCD_ADDRESS 0x3e // Write Address(Write Only)
//
// First Byte of I2C Data
// Co RS 0 0 0 0 0 0
#define LCD_COMMAND 0x00 // Following data is command ...
#define LCD_DATA 0x40 // Following data is data byte w...
//
// Commands
// Function Set
// 0 0 1 DL N DH 0 IS
// DL : Interface data length control bit
// 1: 8-bit bus mode with MPU.
// 0: 4-bit bus mode with MPU.
// When in 4-bit bus mode, it needs to transfer 4-bit...
// N : Display line number control bit
// 1: 2-line display mode is set.
// 0: 1-line display mode.
// DH : Double height font type control bit
// 1: double height mode(5x16 dot),RAM address can onl...
// 0: normal (5x8 dot).
// IS : normal/extension instruction select
// 1: extension instruction be selected (refer extensi...
// 0: normal instruction be selected (refer normal ins...
#define LCD_FUNCTION_SET_NORM 0x38 // 8bit bus, 2 line,...
#define LCD_FUNCTION_SET_EXT 0x39 // 8bit bus, 2 line, ...
//
// Bias selection/Internal OSC frequency adjust, BS will...
// 0 0 0 1 BS F2 F1 F0
// BS: bias selection
// 1: the bias will be 1/4
// 0: the bias will be 1/5
// F2,F1,F0 : Internal OSC frequency adjust, When CLS c...
// F2 F1 F0 3.0V 5.0V
// 0 0 0 122 120
// 0 0 1 131 133
// 0 1 0 144 149
// 0 1 1 161 167
// 1 0 0 183 192
// 1 0 1 221 227
// 1 1 0 274 277
// 1 1 1 347 347
#define LCD_OSC 0x14 // Internal OSC Frequency, BIAS=...
//
// Contrast set(low byte)
// 0 1 1 1 C3 C2 C1 C0
// C3,C2,C1,C0:Contrast set(low byte)
#define LCD_CONTRAST_L 0x73 // Low byte of contrast
//
// Power/ICON control/Contrast set(high byte)
// 0 1 0 1 ION BON C5 C4
// Ion: set ICON display on/off
// 1: ICON display on.
// 0: ICON display off.
// Bon: switch booster circuit, Bon can only be set whe...
// 1: booster circuit is turn on.
// 0: booster circuit is turn off.
// C5,C4 : Contrast set(high byte)
// C5,C4,C3,C2,C1,C0 can only be set when internal fol...
// They can more precisely adjust the input reference ...
// The details please refer to the supply voltage for ...
#define LCD_CONTRAST 0x56 // Power/ICON control/Contrast
//
// Follower control
// 0 1 1 0 FON Rab2 Rab1 Rab0
// Fon: switch follower circuit, Fon can only be set wh...
// 1: internal follower circuit is turn on.
// 0: internal follower circuit is turn off.
// Rab2,Rab1,Rab0 : V0 generator amplified ratio, Rab2,...
#define LCD_FOLLOWER 0x6c
//
// Clear Display
// 0 0 0 0 0 0 0 1
#define LCD_CLEAR 0x01
//
// Display ON/OFF
// 0 0 0 0 1 D C B
// D : Display ON/OFF control bit
// 1: entire display is turned on.
// 0: display is turned off, but display data is remai...
// C : Cursor ON/OFF control bit
// 1: cursor is turned on.
// 0: cursor is disappeared in current display, but I/...
// B : Cursor Blink ON/OFF control bit
// 1: cursor blink is on, that performs alternate betw...
// 0: blink is off.
#define LCD_ON 0x0f
#define LCD_OFF 0x08
//
// Command Recovery Time
//#define LCD_RECOVERY 100LL // 100us
#define LCD_RECOVERY 1000LL // 1000us
#define ON 1
#define OFF 0
//******************************************************...
//* I2Cアクセス時のエラー要因を表示します。
//*
//* Function Name
//* void get_reaosn( bcm2835I2CReasonCodes res, char *st...
//* Arguments
//* bcm2835I2CReasonCodes res error code
//* char str message buffer
//* Return
//* none
//*
//******************************************************...
void get_reaosn( bcm2835I2CReasonCodes res, char *str )
{
switch( res )
{
case BCM2835_I2C_REASON_OK:
strcpy( str, "Success" );
break;
case BCM2835_I2C_REASON_ERROR_NACK:
strcpy( str, "Received a NACK" );
break;
case BCM2835_I2C_REASON_ERROR_CLKT:
strcpy( str, "Received Clock Stretch Timeout" );
break;
case BCM2835_I2C_REASON_ERROR_DATA:
strcpy( str, "Not all data is sent / received" );
break;
default:
strcpy( str, "Unknown error" );
}
}
//******************************************************...
//* LCDモジュールにコマンドの書き込みを行います
//*
//* Function Name
//* int lcd_write_command( char data )
//* Arguments
//* char data byte data
//* Return
//* int res 0: normal end
//* 1: error
//*
//******************************************************...
int lcd_write_command( char data )
{
bcm2835I2CReasonCodes res;
char str[80];
char data_array[2];
data_array[0] = LCD_COMMAND;
data_array[1] = data;
if( res=bcm2835_i2c_write( data_array, 2 ) )
{
get_reaosn( res, str );
printf( "Write error: %s[%d]\n", str, res );
bcm2835_delayMicroseconds( LCD_RECOVERY );
return( 1 );
}
bcm2835_delayMicroseconds( LCD_RECOVERY );
return( 0 );
}
//******************************************************...
//* LCDモジュールにデータの書き込みを行います
//*
//* Function Name
//* int lcd_write_data( char data )
//* Arguments
//* char data byte data
//* Return
//* int res 0: normal end
//* 1: error
//*
//******************************************************...
int lcd_write_data( char data )
{
bcm2835I2CReasonCodes res;
char str[80];
char data_array[2];
data_array[0] = LCD_DATA;
data_array[1] = data;
if( res=bcm2835_i2c_write( data_array, 2 ) )
{
get_reaosn( res, str );
printf( "Write error: %s[%d]\n", str, res );
bcm2835_delayMicroseconds( LCD_RECOVERY );
return( 1 );
}
bcm2835_delayMicroseconds( LCD_RECOVERY );
return( 0 );
}
//******************************************************...
//* LCDモジュールに対して表示のON/OFFを行います
//*
//* Function Name
//* void lcd_on_off( int flag )
//* Arguments
//* flag 0: OFF
//* 1: ON
//* Return
//* none
//*
//******************************************************...
void lcd_on_off( int flag )
{
if( flag ) lcd_write_command( LCD_ON );
else lcd_write_command( LCD_OFF );
}
//******************************************************...
//* LCDモジュールに対して表示のクリアを行います
//*
//* Function Name
//* void lcd_clear( void )
//* Arguments
//* none
//* Return
//* none
//*
//******************************************************...
void lcd_clear( void )
{
lcd_write_command( LCD_CLEAR );
bcm2835_delay( 10 );
}
//******************************************************...
//* 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 ピンの初期化
if( !bcm2835_i2c_begin() )
{
printf( "I2C initialize error!!\n" );
exit(1);
}
// I2C設定
bcm2835_i2c_setSlaveAddress( LCD_ADDRESS );
//bcm2835_i2c_set_baudrate( 50000 );
bcm2835_i2c_setClockDivider( CLK_DIV );
bcm2835_delay( 200 );
// 初期化フェーズ 1
lcd_write_command( LCD_FUNCTION_SET_NORM );
bcm2835_delay( 200 );
// 初期化フェーズ 2
lcd_write_command( LCD_FUNCTION_SET_EXT );
// 初期化フェーズ 3
lcd_write_command( LCD_OSC );
// 初期化フェーズ 4
lcd_write_command( LCD_CONTRAST_L );
// 初期化フェーズ 5
lcd_write_command( LCD_CONTRAST );
// 初期化フェーズ 6
lcd_write_command( LCD_FOLLOWER );
bcm2835_delay( 400 );
// 初期化フェーズ 7
lcd_write_command( LCD_FUNCTION_SET_NORM );
// Display CLEAR & ON
lcd_clear();
lcd_on_off( ON );
}
//******************************************************...
//* I2Cインタフェースを開放します。。
//*
//* Function Name
//* void lcd_close( void )
//* Arguments
//* none
//* Return
//* none
//*
//******************************************************...
void lcd_close( void )
{
bcm2835_i2c_end();
bcm2835_close();
}
//******************************************************...
//* 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 len;
char data;
data = (line * 0x40) | 0x80;
lcd_write_command( data );
for( i=0; i<16; i++)
{
lcd_write_data( 0x20 );
}
data = (line * 0x40) | 0x80;
lcd_write_command( data );
len = strlen(str);
if( len > 16 ) len = 16;
for( i=0; i<len; i++ )
{
lcd_write_data( str[i] );
}
}
int main(int argc, char **argv)
{
lcd_init();
lcd_print( 0, "Minkycute.homeip.net" );
lcd_print( 1, "* I2C LCD 7032 *" );
lcd_close();
return( 0 );
}
<
***テスト [#re19c440]
>
>以下でコンパイルして、実行します。
# gcc -o i2c_lcd_test_st7032 i2c_lcd_test_st7032.c -l bc...
<
>
>※-l rt は[[real-time extensions>http://devlib.symbian.sl...
<
>
>結果はまったく動きません。NACKが返ります。~
実にこまりました。
<
***デバック開始 [#q87c5829]
-汎用ツールでテスト
>
>といことで調査をします。この世界では、有名なi2cdetectで...
BCM2835用のコードがないか、調べます。ありました。~
https://github.com/vanvught/OpenILDA/blob/master/bw_i2cde...
早速コンパイルして実行します。
>※2019-08-10追記:i2c-toolsというrpmパッケージがありまし...
この場合、ドライバー経由になるため、/boot/config.txt に...
i2c_devが存在することをlsmodで確認します。(必要に応じ...
# ./i2cdetect
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
#
>やはり、ツールでもNGです。しかし時々読めます。
# ./i2cdetect
0x3E : 0x7C : Unknown device
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
#
>何かのパラメータがちがうのでしょうか?
+クロックを変えてみます。ボーレート指定でさらに下げたり、...
+10Kプルアップ:NG
+双方向レベル変換:NGです。
<
>
>Google先生に聞いてみます。ありました。~
https://strawberry-linux.com/support/27001/619011~
http://www.takunoko.com/blog/aqm1602xa-rn-gbw%E3%82%92ras...
といことで、なんと、LSIの内蔵PullUp/Downnoほかに、外部で...
根性なしのLCDには厳しいです。~
ということで、抵抗をはずしましょう。でも、抵抗が違うよう...
一応、回路図を調べると、
#ref(bcm2837-1.jpg,zoom)
>R23,R24です。コネクタの近くのA面にありますので、退場して...
<
***結果 [#j0b76f03]
>
>動きました!
>LCD
#ref(LCD_OK-2.jpg,zoom,20%)
<
***ツール化 [#y63d016e]
>
>せっかくなので、コマンドラインより文字を表示できるツール...
<
-コマンド形式
>
lcd_st7032 [-a <addr>] [-i] [-h] <message> [<line#>]
<
-引数/オプション
>
パラメータ
<message> ASCII文字(SJIS:カナ)
<line#> 行番号: 0 or 3
オプション
-a <addr>: I2C上のアドレス(デフォルト:0x3e)
-i: LCDの初期化を行う、LCDを初期化、最初の1回実施すれ...
-h: ヘルプ表示引数:
<
>
>&ref(lcd_st7032.c);
<
**HD44780互換IC系 その2 HD44780/SC1602 LCDモジュール(1...
***I2CExpander [#jc325e57]
>
>Philips社よりI2C接続のパラレルポートICとして、PCF8574が...
また、このICは5V/3.3Vに対応しています。
>ただし、残念ながら、多くのモジュールはLCD本体が5V電源の...
<
***対象モジュール [#q1cc1398]
>
>今回はAmazonで「サインスマート(SainSmart) IIC/I2C/TWI 16...
Amazonに在庫があり、翌日には手に入りました。~
I2C Expander基盤がLCD基盤の金具にショートしそうなこと意外...
>&ref(sainsmart-01.jpg,zoom,20%);
<
***3.3V/5Vレベル変換 [#k57e1337]
>
>秋月電子のPCA9306を使用したモジュールを使用しまし...
<
***PCA9306とLCD制御LSIの接続 [#f88a3077]
>
>PCA9306の8ビット出力とLSIのピンは下表の接続です。
|PCA9306 パラレル入出力|LCD制御LSI信号|h
|D7|D7|
|D6|D6|
|D5|D5|
|D4|D4|
|D3|BackLight|
|D2|E|
|D1|R_W|
|D0|RS|
<
>
>>
>>>
>>>
>>>LCD制御ICは4bitバスモードで接続することになります。
<<<
<<
<
***ソフト [#f1fe6d25]
>
>制御用にソフトを作成します。コマンドの仕様は以下のとおり...
一応、後述する20x4タイプと共用できるよう、4行仕様にしてあ...
<
-コマンド仕様
>
# lcd_exp [-a ] [-i] [-h] <text> [<line#>]
<
-パラメータ・オプション等
>
パラメータ
<text> ASCII文字(SJIS:カナ)
<line#> 行番号: 0 or 3
オプション
-a <addr>: I2C上のアドレス(デフォルト:0x27)
-i: LCDの初期化を行う。LCDを初期化、最初の1回実施すれ...
-h: ヘルプ表示
<
>
>ファイル:&ref(lcd_exp.c);
<
***結果 [#q389bcfa]
>
>動きました
#ref(16x2.jpg,zoom,15%)
<
**HD44780互換IC系 その2 LCDモジュール(20 x 4) + I2CExp...
>
>20x4(4行)タイプをこのICを使用しI2Cバスに接続するLCDモ...
基本、「HD44780互換IC系 その2」と同じでDDRAM(テキスト...
<
***DDRAM [#idf4b1c2]
>
>資料がないため、推測を含みますが以下のようでした。
|LINE#|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|CENTER:ADDR|h
|~|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|...
|CENTER:1|00|01|02|03|04|05|06|07|08|09|0A|0B|0C|0D|0E|0F...
|CENTER:2|40|41|42|43|44|45|46|47|48|49|4A|4B|4C|4D|4E|4F...
|CENTER:3|14|15|16|17|18|19|1A|1B|1C|1D|1E|1F|20|21|22|23...
|CENTER:4|54|55|56|57|58|59|5A|5B|5C|5D|5E|5F|60|61|62|63...
<
***結果 [#w60fc469]
-動かない!
>
>最初の火入れで、何も表示されず、i2cdetectの結果は以下の...
# ./i2cdetect
0x03 : 0x06 : Unknown device
0x04 : 0x08 : Unknown device
0x05 : 0x0A : Unknown device
0x06 : 0x0C : Unknown device
(中略)
0x76 : 0xEC : Unknown device
0x77 : 0xEE : Unknown device
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70: 70 71 72 73 74 75 76 77
#
>つまり、いつもACKが返ってますね。~
で調べると、Expander基盤のSDAピンがLCDモジュールの金具と...
#ref(short.jpg,zoom,40%)
>とりあえず、コネクタを外し、基盤を浮かせた状態で再度半田...
>&ref(remove.jpg,zoom,15%);
>&ref(rebuild.jpg,zoom,20%);
<
-再度挑戦でOK!
>
>今度は動きました。
#ref(2004-ok.jpg,zoom,40%)
<
お疲れ様でした。
終了行:
*[[キャラクタLCDをアクセス]] [#m5789035]
**はじめに [#e7e50907]
>
>Raspberry Pi 3でCentOS7からのキャラクタLCDへのアクセス方...
秋月電子で扱っているI2Cインタフェースかつ3.3V品ということ...
結果的には、まさかこんなものでというぐらい、大変苦労する...
<
**HD44780互換IC系 その1 Sitronix ST7032 [#u0dd2208]
***概要 [#l63c5a03]
>
>キャラクタディスプレイといえば、この系統が主流ですね。往...
今回は、Sitronix ST7032というチップのものです。パラレル、...
#ref(K-08896.jpg,around,zoom)
#ref(ST7032-1.jpg,zoom)
<
***ハードウェア [#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|04|
|I2C SDA.1|03|BGCOLOR(#663300): |SDA|03|
|I2C SCL.1|05|BGCOLOR(#663300): |SCL|02|
<
>
>>
<<
<
***ソフトウェア [#j396b47f]
-概要
>
>Read/Write用の関数を作成してアクセスすることになります。~
たとえば
>>
>>void lcd_init( void );~
int lcd_write_command( char command );~
int lcd_write_data( char data);
<<
>を基本として、各種のコマンドを作成することとします。上記...
>>
>>void lcd_clear( void );~
void lcd_print( int line, char *str );
<<
>位を用意すれば良いでしょう。
<
-実装
>
>テストのつもりでコーディングします。
//------------------------------------------------------...
// ST7032 LCDモジュール(16 x 2) 秋月版 制御TP
// このTPでは、2行表示に対して、これぞれの行に文字を表示...
// 基本的に16文字固定表示でスクロールはしません。
//
// コンパイル方法
// gcc -o i2c_lcd_test_st7032 i2c_lcd_test_st7032.c -l ...
//
// copyright (c) 2016 Kazuhiro WATANABE All right reserv...
// mailto:jj1req@ca.mbn.or.jp
//
//------------------------------------------------------...
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// BCM2835のI2Cクロック周波数の設定値
// BCM2835_I2C_CLOCK_DIVIDER_2500 2500 = 10us = 100 kHz(...
// BCM2835_I2C_CLOCK_DIVIDER_626 622 = 2.504us = 399.36...
// BCM2835_I2C_CLOCK_DIVIDER_15 150 = 60ns = 1.666 MHz ...
// BCM2835_I2C_CLOCK_DIVIDER_148 148 = 59ns = 1.689 MHz
#define CLK_DIV BCM2835_I2C_CLOCK_DIVIDER_2500
//#define CLK_DIV BCM2835_I2C_CLOCK_DIVIDER_148
//#define CLK_DIV BCM2835_I2C_CLOCK_DIVIDER_626
//
// キャラクタ液晶ディスプレーへの接続
#define LCD_ADDRESS 0x3e // Write Address(Write Only)
//
// First Byte of I2C Data
// Co RS 0 0 0 0 0 0
#define LCD_COMMAND 0x00 // Following data is command ...
#define LCD_DATA 0x40 // Following data is data byte w...
//
// Commands
// Function Set
// 0 0 1 DL N DH 0 IS
// DL : Interface data length control bit
// 1: 8-bit bus mode with MPU.
// 0: 4-bit bus mode with MPU.
// When in 4-bit bus mode, it needs to transfer 4-bit...
// N : Display line number control bit
// 1: 2-line display mode is set.
// 0: 1-line display mode.
// DH : Double height font type control bit
// 1: double height mode(5x16 dot),RAM address can onl...
// 0: normal (5x8 dot).
// IS : normal/extension instruction select
// 1: extension instruction be selected (refer extensi...
// 0: normal instruction be selected (refer normal ins...
#define LCD_FUNCTION_SET_NORM 0x38 // 8bit bus, 2 line,...
#define LCD_FUNCTION_SET_EXT 0x39 // 8bit bus, 2 line, ...
//
// Bias selection/Internal OSC frequency adjust, BS will...
// 0 0 0 1 BS F2 F1 F0
// BS: bias selection
// 1: the bias will be 1/4
// 0: the bias will be 1/5
// F2,F1,F0 : Internal OSC frequency adjust, When CLS c...
// F2 F1 F0 3.0V 5.0V
// 0 0 0 122 120
// 0 0 1 131 133
// 0 1 0 144 149
// 0 1 1 161 167
// 1 0 0 183 192
// 1 0 1 221 227
// 1 1 0 274 277
// 1 1 1 347 347
#define LCD_OSC 0x14 // Internal OSC Frequency, BIAS=...
//
// Contrast set(low byte)
// 0 1 1 1 C3 C2 C1 C0
// C3,C2,C1,C0:Contrast set(low byte)
#define LCD_CONTRAST_L 0x73 // Low byte of contrast
//
// Power/ICON control/Contrast set(high byte)
// 0 1 0 1 ION BON C5 C4
// Ion: set ICON display on/off
// 1: ICON display on.
// 0: ICON display off.
// Bon: switch booster circuit, Bon can only be set whe...
// 1: booster circuit is turn on.
// 0: booster circuit is turn off.
// C5,C4 : Contrast set(high byte)
// C5,C4,C3,C2,C1,C0 can only be set when internal fol...
// They can more precisely adjust the input reference ...
// The details please refer to the supply voltage for ...
#define LCD_CONTRAST 0x56 // Power/ICON control/Contrast
//
// Follower control
// 0 1 1 0 FON Rab2 Rab1 Rab0
// Fon: switch follower circuit, Fon can only be set wh...
// 1: internal follower circuit is turn on.
// 0: internal follower circuit is turn off.
// Rab2,Rab1,Rab0 : V0 generator amplified ratio, Rab2,...
#define LCD_FOLLOWER 0x6c
//
// Clear Display
// 0 0 0 0 0 0 0 1
#define LCD_CLEAR 0x01
//
// Display ON/OFF
// 0 0 0 0 1 D C B
// D : Display ON/OFF control bit
// 1: entire display is turned on.
// 0: display is turned off, but display data is remai...
// C : Cursor ON/OFF control bit
// 1: cursor is turned on.
// 0: cursor is disappeared in current display, but I/...
// B : Cursor Blink ON/OFF control bit
// 1: cursor blink is on, that performs alternate betw...
// 0: blink is off.
#define LCD_ON 0x0f
#define LCD_OFF 0x08
//
// Command Recovery Time
//#define LCD_RECOVERY 100LL // 100us
#define LCD_RECOVERY 1000LL // 1000us
#define ON 1
#define OFF 0
//******************************************************...
//* I2Cアクセス時のエラー要因を表示します。
//*
//* Function Name
//* void get_reaosn( bcm2835I2CReasonCodes res, char *st...
//* Arguments
//* bcm2835I2CReasonCodes res error code
//* char str message buffer
//* Return
//* none
//*
//******************************************************...
void get_reaosn( bcm2835I2CReasonCodes res, char *str )
{
switch( res )
{
case BCM2835_I2C_REASON_OK:
strcpy( str, "Success" );
break;
case BCM2835_I2C_REASON_ERROR_NACK:
strcpy( str, "Received a NACK" );
break;
case BCM2835_I2C_REASON_ERROR_CLKT:
strcpy( str, "Received Clock Stretch Timeout" );
break;
case BCM2835_I2C_REASON_ERROR_DATA:
strcpy( str, "Not all data is sent / received" );
break;
default:
strcpy( str, "Unknown error" );
}
}
//******************************************************...
//* LCDモジュールにコマンドの書き込みを行います
//*
//* Function Name
//* int lcd_write_command( char data )
//* Arguments
//* char data byte data
//* Return
//* int res 0: normal end
//* 1: error
//*
//******************************************************...
int lcd_write_command( char data )
{
bcm2835I2CReasonCodes res;
char str[80];
char data_array[2];
data_array[0] = LCD_COMMAND;
data_array[1] = data;
if( res=bcm2835_i2c_write( data_array, 2 ) )
{
get_reaosn( res, str );
printf( "Write error: %s[%d]\n", str, res );
bcm2835_delayMicroseconds( LCD_RECOVERY );
return( 1 );
}
bcm2835_delayMicroseconds( LCD_RECOVERY );
return( 0 );
}
//******************************************************...
//* LCDモジュールにデータの書き込みを行います
//*
//* Function Name
//* int lcd_write_data( char data )
//* Arguments
//* char data byte data
//* Return
//* int res 0: normal end
//* 1: error
//*
//******************************************************...
int lcd_write_data( char data )
{
bcm2835I2CReasonCodes res;
char str[80];
char data_array[2];
data_array[0] = LCD_DATA;
data_array[1] = data;
if( res=bcm2835_i2c_write( data_array, 2 ) )
{
get_reaosn( res, str );
printf( "Write error: %s[%d]\n", str, res );
bcm2835_delayMicroseconds( LCD_RECOVERY );
return( 1 );
}
bcm2835_delayMicroseconds( LCD_RECOVERY );
return( 0 );
}
//******************************************************...
//* LCDモジュールに対して表示のON/OFFを行います
//*
//* Function Name
//* void lcd_on_off( int flag )
//* Arguments
//* flag 0: OFF
//* 1: ON
//* Return
//* none
//*
//******************************************************...
void lcd_on_off( int flag )
{
if( flag ) lcd_write_command( LCD_ON );
else lcd_write_command( LCD_OFF );
}
//******************************************************...
//* LCDモジュールに対して表示のクリアを行います
//*
//* Function Name
//* void lcd_clear( void )
//* Arguments
//* none
//* Return
//* none
//*
//******************************************************...
void lcd_clear( void )
{
lcd_write_command( LCD_CLEAR );
bcm2835_delay( 10 );
}
//******************************************************...
//* 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 ピンの初期化
if( !bcm2835_i2c_begin() )
{
printf( "I2C initialize error!!\n" );
exit(1);
}
// I2C設定
bcm2835_i2c_setSlaveAddress( LCD_ADDRESS );
//bcm2835_i2c_set_baudrate( 50000 );
bcm2835_i2c_setClockDivider( CLK_DIV );
bcm2835_delay( 200 );
// 初期化フェーズ 1
lcd_write_command( LCD_FUNCTION_SET_NORM );
bcm2835_delay( 200 );
// 初期化フェーズ 2
lcd_write_command( LCD_FUNCTION_SET_EXT );
// 初期化フェーズ 3
lcd_write_command( LCD_OSC );
// 初期化フェーズ 4
lcd_write_command( LCD_CONTRAST_L );
// 初期化フェーズ 5
lcd_write_command( LCD_CONTRAST );
// 初期化フェーズ 6
lcd_write_command( LCD_FOLLOWER );
bcm2835_delay( 400 );
// 初期化フェーズ 7
lcd_write_command( LCD_FUNCTION_SET_NORM );
// Display CLEAR & ON
lcd_clear();
lcd_on_off( ON );
}
//******************************************************...
//* I2Cインタフェースを開放します。。
//*
//* Function Name
//* void lcd_close( void )
//* Arguments
//* none
//* Return
//* none
//*
//******************************************************...
void lcd_close( void )
{
bcm2835_i2c_end();
bcm2835_close();
}
//******************************************************...
//* 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 len;
char data;
data = (line * 0x40) | 0x80;
lcd_write_command( data );
for( i=0; i<16; i++)
{
lcd_write_data( 0x20 );
}
data = (line * 0x40) | 0x80;
lcd_write_command( data );
len = strlen(str);
if( len > 16 ) len = 16;
for( i=0; i<len; i++ )
{
lcd_write_data( str[i] );
}
}
int main(int argc, char **argv)
{
lcd_init();
lcd_print( 0, "Minkycute.homeip.net" );
lcd_print( 1, "* I2C LCD 7032 *" );
lcd_close();
return( 0 );
}
<
***テスト [#re19c440]
>
>以下でコンパイルして、実行します。
# gcc -o i2c_lcd_test_st7032 i2c_lcd_test_st7032.c -l bc...
<
>
>※-l rt は[[real-time extensions>http://devlib.symbian.sl...
<
>
>結果はまったく動きません。NACKが返ります。~
実にこまりました。
<
***デバック開始 [#q87c5829]
-汎用ツールでテスト
>
>といことで調査をします。この世界では、有名なi2cdetectで...
BCM2835用のコードがないか、調べます。ありました。~
https://github.com/vanvught/OpenILDA/blob/master/bw_i2cde...
早速コンパイルして実行します。
>※2019-08-10追記:i2c-toolsというrpmパッケージがありまし...
この場合、ドライバー経由になるため、/boot/config.txt に...
i2c_devが存在することをlsmodで確認します。(必要に応じ...
# ./i2cdetect
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
#
>やはり、ツールでもNGです。しかし時々読めます。
# ./i2cdetect
0x3E : 0x7C : Unknown device
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
#
>何かのパラメータがちがうのでしょうか?
+クロックを変えてみます。ボーレート指定でさらに下げたり、...
+10Kプルアップ:NG
+双方向レベル変換:NGです。
<
>
>Google先生に聞いてみます。ありました。~
https://strawberry-linux.com/support/27001/619011~
http://www.takunoko.com/blog/aqm1602xa-rn-gbw%E3%82%92ras...
といことで、なんと、LSIの内蔵PullUp/Downnoほかに、外部で...
根性なしのLCDには厳しいです。~
ということで、抵抗をはずしましょう。でも、抵抗が違うよう...
一応、回路図を調べると、
#ref(bcm2837-1.jpg,zoom)
>R23,R24です。コネクタの近くのA面にありますので、退場して...
<
***結果 [#j0b76f03]
>
>動きました!
>LCD
#ref(LCD_OK-2.jpg,zoom,20%)
<
***ツール化 [#y63d016e]
>
>せっかくなので、コマンドラインより文字を表示できるツール...
<
-コマンド形式
>
lcd_st7032 [-a <addr>] [-i] [-h] <message> [<line#>]
<
-引数/オプション
>
パラメータ
<message> ASCII文字(SJIS:カナ)
<line#> 行番号: 0 or 3
オプション
-a <addr>: I2C上のアドレス(デフォルト:0x3e)
-i: LCDの初期化を行う、LCDを初期化、最初の1回実施すれ...
-h: ヘルプ表示引数:
<
>
>&ref(lcd_st7032.c);
<
**HD44780互換IC系 その2 HD44780/SC1602 LCDモジュール(1...
***I2CExpander [#jc325e57]
>
>Philips社よりI2C接続のパラレルポートICとして、PCF8574が...
また、このICは5V/3.3Vに対応しています。
>ただし、残念ながら、多くのモジュールはLCD本体が5V電源の...
<
***対象モジュール [#q1cc1398]
>
>今回はAmazonで「サインスマート(SainSmart) IIC/I2C/TWI 16...
Amazonに在庫があり、翌日には手に入りました。~
I2C Expander基盤がLCD基盤の金具にショートしそうなこと意外...
>&ref(sainsmart-01.jpg,zoom,20%);
<
***3.3V/5Vレベル変換 [#k57e1337]
>
>秋月電子のPCA9306を使用したモジュールを使用しまし...
<
***PCA9306とLCD制御LSIの接続 [#f88a3077]
>
>PCA9306の8ビット出力とLSIのピンは下表の接続です。
|PCA9306 パラレル入出力|LCD制御LSI信号|h
|D7|D7|
|D6|D6|
|D5|D5|
|D4|D4|
|D3|BackLight|
|D2|E|
|D1|R_W|
|D0|RS|
<
>
>>
>>>
>>>
>>>LCD制御ICは4bitバスモードで接続することになります。
<<<
<<
<
***ソフト [#f1fe6d25]
>
>制御用にソフトを作成します。コマンドの仕様は以下のとおり...
一応、後述する20x4タイプと共用できるよう、4行仕様にしてあ...
<
-コマンド仕様
>
# lcd_exp [-a ] [-i] [-h] <text> [<line#>]
<
-パラメータ・オプション等
>
パラメータ
<text> ASCII文字(SJIS:カナ)
<line#> 行番号: 0 or 3
オプション
-a <addr>: I2C上のアドレス(デフォルト:0x27)
-i: LCDの初期化を行う。LCDを初期化、最初の1回実施すれ...
-h: ヘルプ表示
<
>
>ファイル:&ref(lcd_exp.c);
<
***結果 [#q389bcfa]
>
>動きました
#ref(16x2.jpg,zoom,15%)
<
**HD44780互換IC系 その2 LCDモジュール(20 x 4) + I2CExp...
>
>20x4(4行)タイプをこのICを使用しI2Cバスに接続するLCDモ...
基本、「HD44780互換IC系 その2」と同じでDDRAM(テキスト...
<
***DDRAM [#idf4b1c2]
>
>資料がないため、推測を含みますが以下のようでした。
|LINE#|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|CENTER:ADDR|h
|~|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|...
|CENTER:1|00|01|02|03|04|05|06|07|08|09|0A|0B|0C|0D|0E|0F...
|CENTER:2|40|41|42|43|44|45|46|47|48|49|4A|4B|4C|4D|4E|4F...
|CENTER:3|14|15|16|17|18|19|1A|1B|1C|1D|1E|1F|20|21|22|23...
|CENTER:4|54|55|56|57|58|59|5A|5B|5C|5D|5E|5F|60|61|62|63...
<
***結果 [#w60fc469]
-動かない!
>
>最初の火入れで、何も表示されず、i2cdetectの結果は以下の...
# ./i2cdetect
0x03 : 0x06 : Unknown device
0x04 : 0x08 : Unknown device
0x05 : 0x0A : Unknown device
0x06 : 0x0C : Unknown device
(中略)
0x76 : 0xEC : Unknown device
0x77 : 0xEE : Unknown device
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70: 70 71 72 73 74 75 76 77
#
>つまり、いつもACKが返ってますね。~
で調べると、Expander基盤のSDAピンがLCDモジュールの金具と...
#ref(short.jpg,zoom,40%)
>とりあえず、コネクタを外し、基盤を浮かせた状態で再度半田...
>&ref(remove.jpg,zoom,15%);
>&ref(rebuild.jpg,zoom,20%);
<
-再度挑戦でOK!
>
>今度は動きました。
#ref(2004-ok.jpg,zoom,40%)
<
お疲れ様でした。
ページ名: