免責事項

注意、免責事項について
・高電圧、大電流その他高エネルギを扱う実験を行う際にはくれぐれも安全に配慮し、細心の注意を払って行うようにしてください。
・当ブログの記事を参考にして発生した損害についてFEL研究室はいかなる責任も負えませんでご了承ください。

AkitukiLCD.asm

//2016/10/10
//http://fellaboratory.blogspot.jp/
//I2C液晶駆動テスト
//I2CのSCLを5ピン、SDAを6ピンに接続
//Send_Data/Send_Commandサブルーチンではdata0に入れたデータを送ってくれる

.INCLUDE "tn13def.inc"

.DEF data = R16
.DEF temp = R17
.DEF data0 = R18
.DEF count = R19
.DEF delay = R20
.DEF delay2 = R21
.EQU sclpin = 0//SCLはPB0につなげた
.EQU sdapin = 1//SDAはPB1につなげた
.EQU lcdadd = 0x7C//LCDのI2Cアドレス


//マクロ定義
//===================================
.MACRO SCL_HIGH
CBI DDRB,sclpin
.ENDMACRO

.MACRO SCL_LOW
SBI DDRB,sclpin
.ENDMACRO

.MACRO SDA_HIGH
CBI DDRB,sdapin
.ENDMACRO

.MACRO SDA_LOW
SBI DDRB,sdapin
.ENDMACRO
//===================================

.ORG$0000
//割り込みベクタ分岐(Resetしか使わない)
RJMP Reset//リセット

.CSEG

Init_Data://初期化用のデータテーブル作成
.DB 0x38,0x39,0x14,0x73,0x56,0x69,0x38,0x01,0x0C,0x00

Reset:
LDI ZL,low(Init_Data*2)//データテーブルのアドレスを読み込んでおく
LDI ZH,high(Init_Data*2)

LDI count,8//カウンタ初期値読み込み
LDI temp,((0<<DDB0)|(0<<DDB1)|(1<<DDB2)|(1<<DDB3)|(1<<DDB4)|(1<<DDB5))
//5,6ピンはHiインピーダンスで使用
//DDBnに0を書くとHiインピーダンス、1を書くとLow
CLR temp
OUT PORTB,temp//PORTBはクリア
Initialize://初期化
SDA_LOW//スタートコンディション
SCL_LOW
Init_Delay1://LCD安定待ちディレイ
LDI delay,0x80
Init_Delay2:
LDI delay2,0xFF
Init_Delay3:
DEC delay2
BRNE Init_Delay3
DEC delay
BRNE Init_Delay2

//ここから初期化処理
LDI data,lcdadd//まずスレーブアドレスを送る
RCALL Send
Initialize1:
LPM data0,Z+//data0にデータテーブルから引っ張ってくる
LPM temp,Z//テンポラリには次のデータをロードする
CPI temp,0
/*コマンドに0x00は存在しないためデータテーブルの最後に0x00を判定用に入れて最後まで
データテーブルを読み込んだか判断している
最後の1個手前になったらコントールバイトを変えるためにループから脱出
Z+なので順番に繰り返していくと勝手に初期化が終わっている
*/
BREQ Initialize_END//最後まで読んでたら初期化終了
LDI data,0x80//コントロールバイトに0x80を送る
RCALL Send
MOV data,data0//データを送る
RCALL Send
RJMP Initialize1//繰り返す
Initialize_END:
LDI data,0x00//最後のコマンドは0x00で送る
RCALL Send
MOV data,data0
RCALL Send
RCALL Send_Data_Stop//ストップコンディションを出すサブルーチン

Main://メイン文字表示
LDI data0,'F'
RCALL Send_Data

LDI data0,'E'
RCALL Send_Data

LDI data0,'L'
RCALL Send_Data

LDI data0,'ケ'
RCALL Send_Data

LDI data0,'ン'
RCALL Send_Data

LDI data0,'キ'
RCALL Send_Data

LDI data0,'ュ'
RCALL Send_Data

LDI data0,'ウ'
RCALL Send_Data

LDI data0,'シ'
RCALL Send_Data

LDI data0,'ツ'
RCALL Send_Data

LDI data0,(0x80+0x40)//改行
RCALL Send_Command

LDI data0,'b'
RCALL Send_Data

LDI data0,'y'
RCALL Send_Data

LDI data0,'K'
RCALL Send_Data

LDI data0,'K'
RCALL Send_Data

LDI data0,'T'
RCALL Send_Data
Loop:
RJMP Loop


Send_Command://data0レジスタに贈りたいコマンドを入れておく
SDA_LOW//スタートコンディション生成
SCL_LOW
Send_Command0:
LDI data,lcdadd//まずスレーブアドレスを送る
RCALL Send
Send_Command1:
LDI data,0x00
RCALL Send//次にコントロールバイト0x00を送信
Send_Command2:
MOV data,data0
RCALL Send
Send_Command_END:
RJMP Send_Data_Stop

Send_Data://data0レジスタに贈りたいコマンドを入れておく
Send_Data_Start://スタートコンディション生成
SDA_LOW
SCL_LOW
Send_Data_0:
LDI data,lcdadd//まずスレーブアドレスを送る
RCALL Send
Send_Data1:
LDI data,0x40//続いてコントロールバイトに0x40を送る
RCALL Send
Send_Data2:
MOV data,data0//受け取ったデータを送る
RCALL Send
Send_Data_Stop://ストップコンディションを生成
SCL_HIGH
SDA_HIGH
RET

//===================================
//8bitデータ送信サブルーチンここから

Send://最上位から順番に8bit送る
LSL data//左シフトさせてキャリーが出たら最下位(だったbit)は1、出なければ0
BRCS Send_1//キャリーが出てたら送信データは1
Send_0://0を送る時
SDA_LOW//SDAをLowにしておく
RJMP Send1
Send_1://1を送る時
SDA_HIGH//SDAをHiにしておく
Send1:
SCL_HIGH//クロック立ち上げ
Check_clk://クロックが立ち上がっているか確認
SBIS PINB,sclpin//SCLがHiならば1命令スキップして通常動作
RJMP Check_clk//LowならSCLがHiになるまで繰り返す(クロスストレッチ)
SCL_LOW//クロック立ち下げ
SDA_LOW//データ立ち下げ
DEC count//countをチェック
BRNE Send//8bit送信し終わったら↓へ
LDI count,8//countを元に戻しておく
Check_ACK://ACKが返って来てるか確認
SDA_HIGH//SDAはHighにしておく
SCL_HIGH//クロック立ち上げ
SBIC PINB,sdapin//クロックの立ち上がりでACKがLowになっていればOK
RJMP error//ダメかも…
SCL_LOW//クロック立ち下げ
SDA_LOW//データも一旦立ち下げ

Delay0://待ち時間作るよ
LDI delay,0x20
Delay1:
LDI delay2,0x20
Delay_2:
DEC delay2
BRNE Delay_2
DEC delay
BRNE Delay1
RET

error://ACKが返って来なかった時(本当はエラー処理を書く)
RJMP error//面倒なんで強制停止(無限ループ)
RET
//===================================
//8bitデータ送信サブルーチンおしまい

0 件のコメント:

コメントを投稿

何かあればお気軽にどうぞ。