I2C接続液晶モジュール AE-AQM1602Aを
PICで使ってみた
AE-AQM1602Aをアッセンブラで制御してみる
安価に仕入れた、パラレル接続の液晶モジュールは部品箱にあるのですが、
制御ポートを多く必要なのと、くっきり光る7セグと比較して見づらいのとで、
いまだに手付かずのままでした・・・
今回、I2C接続と言う事で、制御線が2本で済む事から弄ってみる事にしました。
また、実験に使用したPICは16F1823です。
参考文献
AE-AQM1602A資料 秋月電子
PIC16F1823日本語データシート 第25章MSSPモジュール
C言語用 I2C通信ライブラリ i2c_lib2.c 後閑哲也氏ホームページより
安価に仕入れた、パラレル接続の液晶モジュールは部品箱にあるのですが、
制御ポートを多く必要なのと、くっきり光る7セグと比較して見づらいのとで、
いまだに手付かずのままでした・・・
今回、I2C接続と言う事で、制御線が2本で済む事から弄ってみる事にしました。
また、実験に使用したPICは16F1823です。
参考文献
AE-AQM1602A資料 秋月電子
PIC16F1823日本語データシート 第25章MSSPモジュール
C言語用 I2C通信ライブラリ i2c_lib2.c 後閑哲也氏ホームページより
↑ 回路図と言うほどの物では無いですが
プルアップ抵抗は配線していません
変換基板上の抵抗を使用しています
基本的な送信フロー(7ビットアドレス)
①MSSPモジュールの起動
↓
②スタートコンディション出力
↓
③LCDアドレス+WRITE=7CH送信
↓
④LCDからのACK確認
↓
⑤8ビットデータ出力
↓
⑥LCDからのACK確認
↓
⑦ストップコンディション出力
⑧再度送信があるなら、②に行く
ソースファイル
PIC16F1823_I2C_TEST01.asm
使用ツール
MPLAB'X IDE
MPLAB'X IPE
PICKIT3
2015年9月30日追記
ソースプログラム修正しました
理由
削除し忘れのゴミが存在
それにより、文字化けする事がある
コマンドワード送信フロー
①スタートコンディション送信
②LCDアドレス、7CH送信
③コントロールバイト送信
④データバイト送信
⑤次のコマンドワード、あるいは
ストップコンディション送信
LCD画面表示位置アドレスに対して、
コマンド含む、送信データ
1桁目 16桁目
1行目 80H 81H ・・・ 8FH
2行目 C0H C1H ・・・ CFH
上記数値は、コマンド80H+アドレス
PICでI2Cインターフェイスモジュールを利用する
PIC16F1823にはMSSPモジュールと言う物が搭載されています。
このモジュールを使用するしかありません。
PIC16F1705にはオープンドレイン設定がありますので、別な方法ができるかも
当局にとってI2Cインターフェイス使用は初めてなので、欲張らない事にしました。
まずは、「マスタモードで送信する」これを目標にプログラム作成します。
今回はこのMSSPモジュールを利用して、I2C通信の実験してみます。
その通信相手に、今回の液晶モジュールを使用する事としました。
まずは、PIC16F1823MSSPモジュールの記載を読む事が先決ですが・・・
読み始めると、眠くなって居眠りばかりこいてしまいます・・・ (^_^;)
また、後閑哲也氏のHPにあった、C言語用I2C通信ライブラリを参考にしました。
これはPIC16FシリーズMSSP用のライブラリなので、目的にぴったりです。
これを参考にアッセンブラソースに変更して、I2C用低レベルルーチンとしました。
関連SFRについて
RC0がSCL、RC1がSDAとなります。
今回の実験はマスター送信だけなので、それほど設定箇所は無いです。
(1)ポートの設定
PORTC、RC0とRC1はデジタル入力と設定します
つまり、TRISCはセット、ANSELCはクリアとします。
また、シリアルポートはオープンドレインとなります。
信号ラインにはプルアップ抵抗が必要です。
今回はAE-AQM1602付属の変換基板上の10KΩのプルアップ抵抗を利用しています
よって、見かけ上はいきなりポートに接続しただけに見えます。
(2)使用するMSSP関連SFRの設定概要
1)SSP1STAT
bit2 R/Wビットは 「R_NOT_W」と記載します(D/Aビットも同じ)
ソース例 BTFSC SSP1STAT,R_NOT_W
bit0 BF 1バイト送信完了のフラグとしてチェック
2)SSP1CON1
bit5 SSP1ENビットをセットします
bit3-0 SSP1Mビットは「1000]I2Cマスターモード
3)SSP1CON2
bit0 SEN スタートコンディションを発生します
bit6 ACKSTAT 送信完了後のACK返信を受信したかのフラグ
bit2 PEN ストップコンディションを発生します
4)SSP1CON3
デフォルト値のままで、今回は使用していません
5)SSP1MSK
今回は使用していません
6)SSP1ADD
ボーレート100KHZなので、4FHを設定します
7)SSP1BUF
8ビットの送信データを入力します。
書込むと送信開始します。
8)PIR1
今回割込みは使用していませんが、SSP1IFビット を参照します
MSSP制御 低レベルサブルーチン
まずは手始めに、今回はマスターモードで送信する事を行います。
そのため、MSSPモジュールの必要な所のみを弄ってみました。
プログラム詳細は、ソースファイルを参照して下さい。
(1)MSSP_MAS:MSSPモジュール マスターモード初期化サブルーチン
1)SSP1CON1 =28H(00101000B)を設定、これにより各ビットは下記となります
WCOL=0、SSPOV=0、SSP1EN=1、CKP=0、SSP1M=1000
2)SSP1ADD=4FHを設定
ボーレートを100KHZに設定
3)MSSPモジュールのアイドル状態待ち
(2)MSSP_IDLE:MSSPモジュールがアイドル状態になるまで待ちます
マニュアルに記してありますが、「R/WビットとSEN,RSEN,PEN,RCEN,ACKENの
どれかとOR演算するとMSSP1がアイドルかどうかが分かる」
これをそのまま実践しています。
(3)STARTCON:スタートコンディションを送信します
1)SSP1CON2のSEN=1とします。
送信が終了すると、SEN=0となるので、それを待ちます
(4)SEND_BYTE:データを送信します
1)SSP1BUFに8ビットデータを書き込むと送信開始します
SSP1STAT BF=1となります
2)SSP1STATのBFビットを監視し、送信終了を待つ
BF=0となるまで待つ
3)アイドル状態待ち
(5)STOPCON:ストップコンディションを送信
1)SSP1CON2のPEN=1とします
送信が終了するとPEN=0となるので、それを待ちます
その他
今回は単機能で他の重そうな併用処理も無く、単純に処理していますが、、
送受万能なルーチンとするには、割込みも必要かと思われます
PIC16F1823にはMSSPモジュールと言う物が搭載されています。
このモジュールを使用するしかありません。
PIC16F1705にはオープンドレイン設定がありますので、別な方法ができるかも
当局にとってI2Cインターフェイス使用は初めてなので、欲張らない事にしました。
まずは、「マスタモードで送信する」これを目標にプログラム作成します。
今回はこのMSSPモジュールを利用して、I2C通信の実験してみます。
その通信相手に、今回の液晶モジュールを使用する事としました。
まずは、PIC16F1823MSSPモジュールの記載を読む事が先決ですが・・・
読み始めると、眠くなって居眠りばかりこいてしまいます・・・ (^_^;)
また、後閑哲也氏のHPにあった、C言語用I2C通信ライブラリを参考にしました。
これはPIC16FシリーズMSSP用のライブラリなので、目的にぴったりです。
これを参考にアッセンブラソースに変更して、I2C用低レベルルーチンとしました。
関連SFRについて
RC0がSCL、RC1がSDAとなります。
今回の実験はマスター送信だけなので、それほど設定箇所は無いです。
(1)ポートの設定
PORTC、RC0とRC1はデジタル入力と設定します
つまり、TRISCはセット、ANSELCはクリアとします。
また、シリアルポートはオープンドレインとなります。
信号ラインにはプルアップ抵抗が必要です。
今回はAE-AQM1602付属の変換基板上の10KΩのプルアップ抵抗を利用しています
よって、見かけ上はいきなりポートに接続しただけに見えます。
(2)使用するMSSP関連SFRの設定概要
1)SSP1STAT
bit2 R/Wビットは 「R_NOT_W」と記載します(D/Aビットも同じ)
ソース例 BTFSC SSP1STAT,R_NOT_W
bit0 BF 1バイト送信完了のフラグとしてチェック
2)SSP1CON1
bit5 SSP1ENビットをセットします
bit3-0 SSP1Mビットは「1000]I2Cマスターモード
3)SSP1CON2
bit0 SEN スタートコンディションを発生します
bit6 ACKSTAT 送信完了後のACK返信を受信したかのフラグ
bit2 PEN ストップコンディションを発生します
4)SSP1CON3
デフォルト値のままで、今回は使用していません
5)SSP1MSK
今回は使用していません
6)SSP1ADD
ボーレート100KHZなので、4FHを設定します
7)SSP1BUF
8ビットの送信データを入力します。
書込むと送信開始します。
8)PIR1
今回割込みは使用していませんが、SSP1IFビット を参照します
MSSP制御 低レベルサブルーチン
まずは手始めに、今回はマスターモードで送信する事を行います。
そのため、MSSPモジュールの必要な所のみを弄ってみました。
プログラム詳細は、ソースファイルを参照して下さい。
(1)MSSP_MAS:MSSPモジュール マスターモード初期化サブルーチン
1)SSP1CON1 =28H(00101000B)を設定、これにより各ビットは下記となります
WCOL=0、SSPOV=0、SSP1EN=1、CKP=0、SSP1M=1000
2)SSP1ADD=4FHを設定
ボーレートを100KHZに設定
3)MSSPモジュールのアイドル状態待ち
(2)MSSP_IDLE:MSSPモジュールがアイドル状態になるまで待ちます
マニュアルに記してありますが、「R/WビットとSEN,RSEN,PEN,RCEN,ACKENの
どれかとOR演算するとMSSP1がアイドルかどうかが分かる」
これをそのまま実践しています。
(3)STARTCON:スタートコンディションを送信します
1)SSP1CON2のSEN=1とします。
送信が終了すると、SEN=0となるので、それを待ちます
(4)SEND_BYTE:データを送信します
1)SSP1BUFに8ビットデータを書き込むと送信開始します
SSP1STAT BF=1となります
2)SSP1STATのBFビットを監視し、送信終了を待つ
BF=0となるまで待つ
3)アイドル状態待ち
(5)STOPCON:ストップコンディションを送信
1)SSP1CON2のPEN=1とします
送信が終了するとPEN=0となるので、それを待ちます
その他
今回は単機能で他の重そうな併用処理も無く、単純に処理していますが、、
送受万能なルーチンとするには、割込みも必要かと思われます
LCDモジュール制御 AQM1602 詳細はマニュアルを参照して下さい
これは16桁2行の液晶表示器で3.3V~5Vで使用できます。
今回はPICと同様に5Vで使用しています。
(1)コマンドワード
LCDのコマンドに関しては、2バイト(コマンドワード)で構成されています。
1つのコマンドワードはコントロールバイト+データバイトで構成されます。
1)コントロールバイト
80H:次に続くバイトはLCDのインストラクションコード(注1)
C0H:次に続くバイトはLCDの表示アスキーコード
注1)連続送信用コマンドになっているが、これでSTOPしても今の所何も起きていない
2)データバイト(抜粋)
a)インストラクションコード (注2)
01H:クリアディスプレイ、16桁2行すべてが20H(SP)で置き換わります
80H~:DDRAMアドレスを指定
80H~8FHは1行目のアドレス(2行モードの場合)
C0H~CFHは2行目のアドレス(2行モードの場合)
注2)このインストラクションコードは多数あり、多機能です。
それらの詳細はマニュアルを参照して下さい
この2つのコードは今回のLCDイニシャライズ ルーチン適用後、
使用可能なコードの内の2つです。
b)LCD表示データ
20H~7FHは英文字コード、A1H~DFHはカナ文字コード、
その他のアドレスは色々・・・
3)画面表示位置アドレス(DDRAMアドレス)
(2)表示ルーチン
1)INIT_LCD:LCD初期化 以下の順番で処理 ソース及びマニュアル参照
a)パワーオン・ウエイト 100ms
b)38H:ノーマル・ファンクション、データ長は8ビットモード
c)39H:拡張ファンクション、データ長は8ビットモード
d)14H:内部クロック周波数 1/5バイアス 380KHZ
e)78H:コントラスト設定(電源電圧により調整必要)
f)56H:電源アイコンコントラスト設定(表示されない)
g)6AH:フォロア制御(電源電圧により調整必要)
h)ウエイト 300ms
i)38H:ノーマル・ファンクション、データ長は8ビットモード
j)0CH:ディスプレイ オン
k)01H:クリアディスプレイ
l)ウエイト 5ms
2)CLRLCD:クリアディスプレイ
3)PUTW:Wレジスタのアスキーコード一文字を画面に表示
表示位置アドレスは、変数「DSP_ADR」に設定
4)PUTL1:LABELで指定された文字列を1行目に表示(注3)
LABELのアドレスは変数MSAD0、MSAD1に収納してコール
例)
MOVLW LOW LABEL (注4)
MOVWF MSAD0
MOVLW HIGH LABEL (注4)
MOVWF MSAD1
CALL PUTL1
----
LABEL DT ”ABCDEF”
DW 00H
5)PUTL2:LABELで指定された文字列を2行目に表示(注3)
注3)LABELについて
文字列は16文字までで、文字列の最後に00Hを付加する事(エンドコード)
注4)HIGH、LOWはPICの命令ではなく、アッセンブラ疑似命令です
これは16桁2行の液晶表示器で3.3V~5Vで使用できます。
今回はPICと同様に5Vで使用しています。
(1)コマンドワード
LCDのコマンドに関しては、2バイト(コマンドワード)で構成されています。
1つのコマンドワードはコントロールバイト+データバイトで構成されます。
1)コントロールバイト
80H:次に続くバイトはLCDのインストラクションコード(注1)
C0H:次に続くバイトはLCDの表示アスキーコード
注1)連続送信用コマンドになっているが、これでSTOPしても今の所何も起きていない
2)データバイト(抜粋)
a)インストラクションコード (注2)
01H:クリアディスプレイ、16桁2行すべてが20H(SP)で置き換わります
80H~:DDRAMアドレスを指定
80H~8FHは1行目のアドレス(2行モードの場合)
C0H~CFHは2行目のアドレス(2行モードの場合)
注2)このインストラクションコードは多数あり、多機能です。
それらの詳細はマニュアルを参照して下さい
この2つのコードは今回のLCDイニシャライズ ルーチン適用後、
使用可能なコードの内の2つです。
b)LCD表示データ
20H~7FHは英文字コード、A1H~DFHはカナ文字コード、
その他のアドレスは色々・・・
3)画面表示位置アドレス(DDRAMアドレス)
(2)表示ルーチン
1)INIT_LCD:LCD初期化 以下の順番で処理 ソース及びマニュアル参照
a)パワーオン・ウエイト 100ms
b)38H:ノーマル・ファンクション、データ長は8ビットモード
c)39H:拡張ファンクション、データ長は8ビットモード
d)14H:内部クロック周波数 1/5バイアス 380KHZ
e)78H:コントラスト設定(電源電圧により調整必要)
f)56H:電源アイコンコントラスト設定(表示されない)
g)6AH:フォロア制御(電源電圧により調整必要)
h)ウエイト 300ms
i)38H:ノーマル・ファンクション、データ長は8ビットモード
j)0CH:ディスプレイ オン
k)01H:クリアディスプレイ
l)ウエイト 5ms
2)CLRLCD:クリアディスプレイ
3)PUTW:Wレジスタのアスキーコード一文字を画面に表示
表示位置アドレスは、変数「DSP_ADR」に設定
4)PUTL1:LABELで指定された文字列を1行目に表示(注3)
LABELのアドレスは変数MSAD0、MSAD1に収納してコール
例)
MOVLW LOW LABEL (注4)
MOVWF MSAD0
MOVLW HIGH LABEL (注4)
MOVWF MSAD1
CALL PUTL1
----
LABEL DT ”ABCDEF”
DW 00H
5)PUTL2:LABELで指定された文字列を2行目に表示(注3)
注3)LABELについて
文字列は16文字までで、文字列の最後に00Hを付加する事(エンドコード)
注4)HIGH、LOWはPICの命令ではなく、アッセンブラ疑似命令です
今回はここまでです
無線関連で7セグLEDの代わりに使う用途では、こんな最低限のルーチンでも、
何とか使えるのではと思っていますが・・・
LCDのコマンドは多機能なのですが、2行では中途半端な感じがします。
せめて16桁16行程度あれば、キーボードでも接続して、「パソコン」としても遊べそう
I2C接続のモジュールが秋月やAitendoで何故か増えていますが・・・
その中には面白そうなモジュールもありますので、見ているだけではつまらない。
MSSPモジュールに対しては、何とか最初の突破口を開けられましたので、
今後、I2C接続の安価で面白そうなモジュールを入手してみたいと思います。
そして、それらをモチーフに色々動作実験等を楽しんでみたいと思います。
結果的には、基本制御の低レベルルーチンを少しずつ整備していきたいと思います。
と言う訳で、続きます・・・ 多分 (^_^;)
追記(2017年3月)
制御プログラム群の小変更およびXC対応してみました
詳細は下記
「XC8用AQM1602制御関数を作ってみる」
無線関連で7セグLEDの代わりに使う用途では、こんな最低限のルーチンでも、
何とか使えるのではと思っていますが・・・
LCDのコマンドは多機能なのですが、2行では中途半端な感じがします。
せめて16桁16行程度あれば、キーボードでも接続して、「パソコン」としても遊べそう
I2C接続のモジュールが秋月やAitendoで何故か増えていますが・・・
その中には面白そうなモジュールもありますので、見ているだけではつまらない。
MSSPモジュールに対しては、何とか最初の突破口を開けられましたので、
今後、I2C接続の安価で面白そうなモジュールを入手してみたいと思います。
そして、それらをモチーフに色々動作実験等を楽しんでみたいと思います。
結果的には、基本制御の低レベルルーチンを少しずつ整備していきたいと思います。
と言う訳で、続きます・・・ 多分 (^_^;)
追記(2017年3月)
制御プログラム群の小変更およびXC対応してみました
詳細は下記
「XC8用AQM1602制御関数を作ってみる」