お世話になっております。
現在、RL78/G14と、LCD(型番AQM1602XA-RN-GBW)で、i2c通信を行おうとしておりますが、
初期化と文字表示の段階にて苦労しております。
ブレークをかけると、下記の★印をつけた、『while (i2c_flag == 0) ; /* 送信完了待ち */』から先へ進みません。
(LCDデータシート)akizukidenshi.com/.../AQM1602_rev2.pdf
↑のURLによると、このLCDで初期化をするには、下記の
『0x38, 0x39, 0x14, 0x73, 0x56, 0x6C, 0x38, 0x01, 0x0C』
という数値をそれぞれ表記される時間を挟んで送信する必要があるとのことです。
絵解きマイコンCのDVD-ROMのサンプルコード↓
(D:\03_サンプル・プログラム\第12章\リスト13-16_c08-i2c1)を参考に、下記のコードを組みました。
メインファイル内以外、ファイルの中は変更していません。
お聞きしたいことは
①考え方や使用する関数等、前提の考え方や方針は正しいか。
②配列から一つずつ文字を取り出すにはどう改良するべきか。
③フラグが1を通らない原因について(そもそもブラックボックスになっているので特定が難しい?)
です。
【作成関数(mainファイル)】--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void sendInitData(void) { uint8_t lcd_init_data[] = {0x38, 0x39, 0x14, 0x73, 0x56, 0x6C, 0x38, 0x01, 0x0C}; /*初期化送信データ*/ int i;
for (i = 0; i < sizeof(lcd_init_data); i++) { /*一つずつ取り出し*/ while(0 == delay_flag); /*割り込み(インターバルタイマ)で200ms経過で立つフラグ*/ delay_flag = 0; /*通ったらフラグを0に戻す*/ R_IICA0_Master_Send(0x3e, &lcd_init_data[i], 9, 1); /* 1つのデータをI2C送信実行 */ }★while (i2c_flag == 0) ; /* 送信完了待ち */ R_IICA0_StopCondition(); /* I2C通信終了 */ while (SPD0 == 0) ; /* ストップ・コンディション検出待ち */ i2c_flag = 0;}
【mainファイルend】-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
③フラグが1を通らない原因について
についてです。
長々と申し訳ございません。
お手数ですが、どうぞ、よろしくお願いいたします。
すみません、この段階は解決いたしました。
続いて文字表示についてですが、
akizukidenshi.com/.../AQM1602_rev2.pdf
を参考に、ADDRアドレスと、表示したい文字コードを
R_IICA0_Master_Send(0x00 << 1, lcd_init_data, 1, 1); という風に入力しました。
0x00は液晶の一番恥じっこで、cd_init_data変数の中身は、'A'を表示させる"0x41"です。
【コーディング内容】---------------------------------------------------------------------------------------
void i2c_send_byte(void) {uint8_t lcd_init_data[] = {0x41};i2c_flag = 0;R_IICA0_Master_Send(0x00 << 1, lcd_init_data, 1, 1); // I2C送信★while (i2c_flag == 0) ; // 送信完了待ちR_IICA0_StopCondition(); // I2C通信終了while (SPD0 == 0) ; // ストップ・コンディション検出待ち}
という関数をつくりましたが、★while (i2c_flag == 0) ; // 送信完了待ち
で止まっています。
第一引数のビットシフトを外しても同様の結果でした。
チョコです。
R_IICA0_Master_Sendの第1引数は、スレーブ・アドレスなので、0x00はあり得ません。
ここは、0x3E<<1にしないといけません。また、LCDの制御は、以下のようにPDFに書かれています。
スレーブ・アドレスに続けて、単一データか複数データの書き込みビット(Co)、コマンドかデータの判別用のビットを指定するビット(RS)を指定するバイトを送信します。その後に実際のデータを送信します。
以下のような2バイトのデータが基本です。
ここらは、以下の表に書かれています。これが基本です。
ここで、下に示す上側の赤く囲んだSet DDRAMaddressで書き込みたい位置(アドレス)を指定します。このときRSは0にしてコマンドにします。(Coは0にしておきます。)
その後、下側の赤で囲んだWrite data to RAMで書き込みたいデータを書き込みます。この時Coは0,RSは1にします。
2バイト目が表示したいデータになります。
LCDの制御については、古いサンプルコードですが、以下に示すものが参考になります。
https://community-ja.renesas.com/cafe_rene/m/sample_program/277
このサンプルコードは、RL78/G10の簡易IICですが、ここには説明のPDFがあります。そこには、型名は異なりますが、LCDの制御方法もいかのように書かれています。
以上
チョコ様
ありがとうございます、確認しました。
月曜日にオフィスにおいてあるボードで確認しますので、
それまで手が付けられませんが、また進捗があったら報告します。
どうもありがとうございます。
改めて記述内容を確認させていただきました。
すみません、チョコさんの内容を確認したところ、どうやら初期化のコーディングも
間違っていたみたいなので、やり直しました。
前提の確認なのですが、初期化についてのコーディングについて、
下記の内容は最初に0x00+("0x38~"0x0c")を順番に送信するものになっています。
連続で送る場合はCoを1、最後に0ということでしたが、こちらではコーディングは不適切でしょうか。
(0~7要素目までは"0x80"で送信、8の送信時に"0x00"送信?)
いかんせん初期化に成功したのかしていないのかでLCDに反応がないので、いささか確認に苦戦しております。
i2c_flagとストップコンディションはブレークをいれるときちんと止まるので通っており、
ブレークをしない場合は関数内は全て通ってクリアできております。
※time_flagは200ms経過で"1"になる自作フラグです。
【初期化関数】--------------------------------------------------------------------------------------
void acc_data_send(void){uint8_t lcd_init_data[] = {0x38, 0x39, 0x14, 0x73, 0x56, 0x6C, 0x38, 0x01, 0x0C};uint8_t i;
i2c_flag = 0;
for (i = 0; i < 9; i++){uint8_t data_to_send[2] = {0x00, lcd_init_data[i]}; // 共通のプレフィックスを追加
while (0 == time_flag);time_flag = 0;R_IICA0_Master_Send(0x3e << 1, data_to_send, 2, 1); // 2バイト送信}
while (i2c_flag == 0); /* 送信完了待ち */R_IICA0_StopCondition(); /* I2C通信終了 */while (SPD0 == 0); /* ストップ・コンディション検出待ち */
}
【ここまで】------------------------------------------------------------------------------------------
>下記の内容は最初に0x00+("0x38~"0x0c")を順番に送信するものになっています。
>連続で送る場合はCoを1、最後に0ということでしたが、こちらではコーディングは不適切でしょうか。
使用しているLCDが異なるので、処理は異なっています。使用しているのは、ACM1602NI-FLW-FBW-M01で、Voを外部から供給するタイプです。古い型のLCDなので、Coビットはなく、ファンクションセットコマンドのISビットもありません。以下のような簡単なものでしかありません。
AQM1602XA-RN-GBWであれば、初期化はコマンドとして、RSビットを0にしたデータに続けて、初期化コマンドを1バイトずつ時間をおいて書き込むだけです。
>(0~7要素目までは"0x80"で送信、8の送信時に"0x00"送信?)
コマンドは処理に時間が必要なので、この方法は避けた方がいいでしょう。
返信ありがとうございます。
>AQM1602XA-RN-GBWであれば、初期化はコマンドとして、RSビットを0にしたデータに続けて、初期化コマンドを1バイトずつ時間をおいて書き込むだけです。
とのことですが、『Rsビットを0にしたデータに続けて』という部分について、これは1バイト目のデータ(私のコードでいうところの、"0x00"部分)とは別の記述方法になるという事でしょうか。その場合、それはどのようにして、初期化コマンド前にセットするのでしょうか。
>『Rsビットを0にしたデータに続けて』という部分について、これは1バイト目のデータ(私のコードでいうところの、"0x00"部分)とは別の記述方法になるという事でしょうか。
いいえ、同じことです。下に示すのが、スレーブ・アドレスにつづけて、書き込みの基本的な方法です。
これで、RSビットが0ならコントロール・バイトは0x00になります。これに続けて、書き込みたいコマンドの2バイト構成になるだけです。
只今初期化に成功しました。画面、点灯いたしました。
しつこく質問してしまいすみませんでした。大変助かりました。
これから文字表記のコーディングをいたしますが、ここからは自分でやってみようと思います。
どうもありがとうございました。