紆余曲折ありつつ、最終的にはなんとか表示できたので、ハマったところのメモを残しておきます。
- CodeWarrior (Processor Expert) の設定で入力する I2C スレーブアドレスは 0x7C ではなく 0x3E
- 0x3E は 0x7C >> 1。アドレス部と Read/Write 部を独立して扱っているので、シフトしておく必要があります。
- 初期設定例だと表示されない
- コントラストの設定(初期化手順 4 番目)を例の 0x70 から 0x7f に変更すると見えるようになりました。
- 供給している電源電圧の問題かもしれません。電源入力には FRDM-KL25Z の 5V 出力端子からの電圧を TA48033S で 3.3V にして使用しました。
- 初期化コマンド間で Wait する
- 長い時間が指定されている Wait の時間は 26.3uS ということで、特に気にしないで連続でコマンドを発行しても発行にかかる時間で Wait 時間がまかなえるかと思ったのですが、たまに通信に失敗することがありました。他の原因かもしれませんが、とりあえずコマンドの間に長めの Wait(1ms) を入れることで安定しました。
また、Control Byte の Co が若干わかりにくかったのですが、表示したい文字列を送る場合は 0 にして、それ以外の場合はコマンド1つ毎に STOP コンディションを発生させれ Co は 0 でも 1 でも良い、という扱いで良さそうです。コマンド間で Wait も必要なようですし。
仕様書には「データを複数送る場合 Co = 1 で、」とありますが、これは間違いですね。少なくとも Co = 0 にして文字列を送ることはできました。
(※ I2CMasterHelper_***、BusyWait は別の場所で定義した関数なので、このままでは使えませんが、参考程度に。)
#include "AQM0802A.h" #include "I2CMasterHelper.h" #include "PE_Types.h" #include "PE_Error.h" #include <stdio.h> #include <string.h> // co = 0 : Last Control byte to be sent. Only a stream of data bytes is allowed to follow. // co = 1 : Another Control byte will follow the data byte (unless a STOP condition is received) // rs = 0 : Send Command // rs = 1 : Send Data static byte ControlByte(bool co, bool rs){ return (co << 7) | (rs << 6); } static void SendCommand(byte cmd){ byte data[2]; data[0] = ControlByte(FALSE, FALSE); data[1] = cmd; I2CMasterHelper_SendBlock(data, 2, LDD_I2C_SEND_STOP); I2CMasterHelper_WaitSendComplete(); BusyWaitMS(1); } void AQM0802A_Init(){ // 0x0011_1000 : DL = 1 : 8bit-bus mode, N = 1 : 2-line display mode, DH = 0 : font size is 5 x 8, IS = 0 : normal instruction SendCommand(0x38); // IS = 1 SendCommand(0x39); // Internal OSC frequency : 1/4 bias SendCommand(0x14); // Contrast Set : 000 SendCommand(0x7f); // Power/ICON/Contrast control : ICON display off, Booster circuit on, contrast 10 SendCommand(0x56); // Follower control : follower circuit on, follower amplified ratio = 100 SendCommand(0x6C); // wait 200ms for power stable BusyWaitMS(200); SendCommand(0x38); // Display on, cursor off, cursor blink off SendCommand(0x0C); // Clear display SendCommand(0x01); // TODO: wait 1.08ms BusyWaitMS(2); } // first line address is 0x00 ~ 0x07 // second line address is 0x40 ~ 0x47 void AQM0802A_DisplayChr(byte addr, char ch){ // Test for now; byte data[4]; // Set Address data[0] = ControlByte(TRUE, FALSE); data[1] = 0x80 | addr; // the first bit is always 1. // Set Character data[2] = ControlByte(FALSE, TRUE); data[3] = ch; I2CMasterHelper_SendBlock(data, 4, LDD_I2C_SEND_STOP); I2CMasterHelper_WaitSendComplete(); } void AQM0802A_DisplayStr(bool secondline, char* str){ byte data[11]; byte length = strlen(str); if(length > 8){ length = 8; } // Set Address data[0] = ControlByte(TRUE, FALSE); data[1] = 0x80 | ((secondline == TRUE)?0x40:0x00); // the first bit is always 1. // Set data data[2] = ControlByte(FALSE, TRUE); memcpy(data + 3, str, length); I2CMasterHelper_SendBlock(data, length + 3, LDD_I2C_SEND_STOP); I2CMasterHelper_WaitSendComplete(); } void AQM0802A_ClearDisplay(){ SendCommand(0x01); }
0 件のコメント:
コメントを投稿