LCDモジュール ACM1602NI(I2C接続) を制御するライブラリ

Dependents:   scan2 BoxController

Committer:
orivant
Date:
Mon Dec 19 05:36:47 2016 +0000
Revision:
12:b5829a58bbaf
Parent:
11:e0849411adfa
?????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
orivant 0:c7da9183f23a 1 /** LCDモジュール ACM1602NI を制御するクラスの定義
orivant 0:c7da9183f23a 2 */
orivant 0:c7da9183f23a 3 #include "LcdAcm1602ni.h"
orivant 0:c7da9183f23a 4
orivant 0:c7da9183f23a 5 const uint8_t LcdAcm1602ni::LINE_HEAD_ADDR_TBL[LINE_COUNT] = {0x00, 0x40}; //!< 行の先頭アドレス
orivant 0:c7da9183f23a 6
orivant 0:c7da9183f23a 7 /** コンストラクタ
orivant 0:c7da9183f23a 8 */
orivant 0:c7da9183f23a 9 LcdAcm1602ni::LcdAcm1602ni(PinName pinSDA, PinName pinSCL)
orivant 0:c7da9183f23a 10 :m_pinSDA(pinSDA)
orivant 0:c7da9183f23a 11 ,m_pinSCL(pinSCL)
orivant 0:c7da9183f23a 12 ,m_i2c(pinSDA, pinSCL)
orivant 11:e0849411adfa 13 ,m_isMyI2c(true)
orivant 11:e0849411adfa 14 ,m_currentLineNo(0)
orivant 11:e0849411adfa 15 ,m_currentCharaNo(0)
orivant 11:e0849411adfa 16 ,m_displayVisible(true)
orivant 11:e0849411adfa 17 ,m_cursorVisible(false)
orivant 11:e0849411adfa 18 ,m_blinkEnable(false)
orivant 11:e0849411adfa 19 {
orivant 11:e0849411adfa 20 m_i2c.frequency(I2C_MAX_FREQUENCY);
orivant 11:e0849411adfa 21 }
orivant 11:e0849411adfa 22 LcdAcm1602ni::LcdAcm1602ni(I2C& i2c)
orivant 11:e0849411adfa 23 :m_pinSDA(NC)
orivant 11:e0849411adfa 24 ,m_pinSCL(NC)
orivant 11:e0849411adfa 25 ,m_i2c(i2c)
orivant 11:e0849411adfa 26 ,m_isMyI2c(false)
orivant 0:c7da9183f23a 27 ,m_currentLineNo(0)
orivant 0:c7da9183f23a 28 ,m_currentCharaNo(0)
orivant 0:c7da9183f23a 29 ,m_displayVisible(true)
orivant 0:c7da9183f23a 30 ,m_cursorVisible(false)
orivant 0:c7da9183f23a 31 ,m_blinkEnable(false)
orivant 0:c7da9183f23a 32 {
orivant 0:c7da9183f23a 33 }
orivant 0:c7da9183f23a 34 /** デストラクタ
orivant 0:c7da9183f23a 35 */
orivant 0:c7da9183f23a 36 LcdAcm1602ni::~LcdAcm1602ni()
orivant 0:c7da9183f23a 37 {
orivant 0:c7da9183f23a 38 }
orivant 0:c7da9183f23a 39
orivant 0:c7da9183f23a 40
orivant 0:c7da9183f23a 41 /** 初期化
orivant 0:c7da9183f23a 42 */
orivant 0:c7da9183f23a 43 void LcdAcm1602ni::initialize()
orivant 0:c7da9183f23a 44 {
orivant 0:c7da9183f23a 45 uint8_t command;
orivant 9:96baac039a90 46
orivant 9:96baac039a90 47 // 画面クリア(00000001 = 0x01)
orivant 9:96baac039a90 48 writeCommand(0x01);
orivant 9:96baac039a90 49 wait_us(2160);
orivant 0:c7da9183f23a 50
orivant 0:c7da9183f23a 51 // ファンクション設定(0011[8bitモード]1[2行モード]0[文字5x8表示モー]00 = 00111000 = 0x38)
orivant 0:c7da9183f23a 52 writeCommand(0x38);
orivant 0:c7da9183f23a 53 wait_us(53);
orivant 0:c7da9183f23a 54
orivant 0:c7da9183f23a 55 // ディスプレイ表示
orivant 0:c7da9183f23a 56 command = calcDisplayControlByteData();
orivant 0:c7da9183f23a 57 writeCommand(command);
orivant 0:c7da9183f23a 58 wait_us(53);
orivant 0:c7da9183f23a 59
orivant 9:96baac039a90 60 // データ書き込み後アドレス加算モード設定(0000011[インクリメント]0 = 00000110 = 0x06)
orivant 9:96baac039a90 61 writeCommand(0x06);
orivant 9:96baac039a90 62 wait_us(53);
orivant 9:96baac039a90 63
orivant 0:c7da9183f23a 64 }
orivant 0:c7da9183f23a 65
orivant 0:c7da9183f23a 66
orivant 0:c7da9183f23a 67 /** 1文字描画
orivant 0:c7da9183f23a 68 */
orivant 0:c7da9183f23a 69 void LcdAcm1602ni::putc(char c)
orivant 0:c7da9183f23a 70 {
orivant 0:c7da9183f23a 71 // 1文字書き込み
orivant 0:c7da9183f23a 72 writeData(c);
orivant 0:c7da9183f23a 73 // カーソル位置管理処理
orivant 0:c7da9183f23a 74 bool ret = incCursorPos();
orivant 0:c7da9183f23a 75 if (ret) {
orivant 0:c7da9183f23a 76 // 復帰・改行が発生したのでカーソル位置変更
orivant 0:c7da9183f23a 77 uint8_t addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo);
orivant 0:c7da9183f23a 78 writeCommand(0x80 | addr);
orivant 0:c7da9183f23a 79 }
orivant 0:c7da9183f23a 80 }
orivant 0:c7da9183f23a 81 /** 文字列描画
orivant 0:c7da9183f23a 82 */
orivant 0:c7da9183f23a 83 void LcdAcm1602ni::puts(const char* pStr)
orivant 0:c7da9183f23a 84 {
orivant 0:c7da9183f23a 85 uint8_t addr;
orivant 0:c7da9183f23a 86 bool ret;
orivant 0:c7da9183f23a 87 const char* pt = pStr;
orivant 0:c7da9183f23a 88 bool stayLocate = false;
orivant 0:c7da9183f23a 89 while (*pt) {
orivant 0:c7da9183f23a 90 const char &c = *pt;
orivant 0:c7da9183f23a 91 if (c == '\r') {
orivant 0:c7da9183f23a 92 // 復帰コードの場合、行の先頭にカーソルを移動する
orivant 0:c7da9183f23a 93 m_currentCharaNo = 0;
orivant 0:c7da9183f23a 94 // 実際の移動処理は後で行う
orivant 0:c7da9183f23a 95 stayLocate = true;
orivant 0:c7da9183f23a 96 }
orivant 0:c7da9183f23a 97 else if (c == '\n') {
orivant 0:c7da9183f23a 98 // 改行コードの場合、次の行にカーソルを移動する
orivant 0:c7da9183f23a 99 m_currentLineNo = (m_currentLineNo + 1) % LINE_COUNT;
orivant 0:c7da9183f23a 100 // 実際の移動処理は後で行う
orivant 0:c7da9183f23a 101 stayLocate = true;
orivant 0:c7da9183f23a 102 }
orivant 0:c7da9183f23a 103 else {
orivant 0:c7da9183f23a 104 // 通常の文字コードの場合
orivant 0:c7da9183f23a 105 if (stayLocate) {
orivant 0:c7da9183f23a 106 // 復帰・改行の予約がある場合は先に処理
orivant 0:c7da9183f23a 107 addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo);
orivant 0:c7da9183f23a 108 writeCommand(0x80 | addr);
orivant 0:c7da9183f23a 109 stayLocate = false;
orivant 0:c7da9183f23a 110 }
orivant 0:c7da9183f23a 111 // 1文字書き込み
orivant 0:c7da9183f23a 112 writeData(c);
orivant 0:c7da9183f23a 113 // カーソル位置管理処理
orivant 0:c7da9183f23a 114 ret = incCursorPos();
orivant 0:c7da9183f23a 115 if (ret) {
orivant 0:c7da9183f23a 116 // 改行が発生したのでカーソル位置変更
orivant 0:c7da9183f23a 117 // 実際の移動処理は後で行う
orivant 0:c7da9183f23a 118 stayLocate = true;
orivant 0:c7da9183f23a 119 }
orivant 0:c7da9183f23a 120 }
orivant 0:c7da9183f23a 121 pt++;
orivant 0:c7da9183f23a 122 }
orivant 0:c7da9183f23a 123 if (stayLocate) {
orivant 0:c7da9183f23a 124 // 復帰・改行の予約が残っている場合は処理する
orivant 0:c7da9183f23a 125 addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo);
orivant 0:c7da9183f23a 126 writeCommand(0x80 | addr);
orivant 0:c7da9183f23a 127 }
orivant 0:c7da9183f23a 128 }
orivant 0:c7da9183f23a 129 /** フォーマット指定描画
orivant 0:c7da9183f23a 130 */
orivant 0:c7da9183f23a 131 void LcdAcm1602ni::printf(const char* pFormat, ...)
orivant 0:c7da9183f23a 132 {
orivant 0:c7da9183f23a 133 va_list ap;
orivant 0:c7da9183f23a 134 va_start(ap, pFormat);
orivant 0:c7da9183f23a 135 char* allocatedBuffer;
orivant 0:c7da9183f23a 136 int size = vasprintf(&allocatedBuffer, pFormat, ap);
orivant 0:c7da9183f23a 137 va_end(ap);
orivant 0:c7da9183f23a 138 puts(allocatedBuffer);
orivant 0:c7da9183f23a 139 free(allocatedBuffer);
orivant 0:c7da9183f23a 140 }
orivant 0:c7da9183f23a 141
orivant 0:c7da9183f23a 142
orivant 0:c7da9183f23a 143 /** カーソル位置変更
orivant 0:c7da9183f23a 144 */
orivant 0:c7da9183f23a 145 void LcdAcm1602ni::locate(uint8_t lineNo, uint8_t charaNo)
orivant 0:c7da9183f23a 146 {
orivant 0:c7da9183f23a 147 if (lineNo >= LINE_COUNT) lineNo = LINE_COUNT - 1;
orivant 0:c7da9183f23a 148 if (charaNo >= LINE_CHARA_COUNT) charaNo = LINE_CHARA_COUNT - 1;
orivant 0:c7da9183f23a 149 m_currentLineNo = lineNo;
orivant 0:c7da9183f23a 150 m_currentCharaNo = charaNo;
orivant 0:c7da9183f23a 151 uint8_t addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo);
orivant 0:c7da9183f23a 152 writeCommand(0x80 | addr);
orivant 0:c7da9183f23a 153 }
orivant 0:c7da9183f23a 154 /** カーソル位置取得:行番号
orivant 0:c7da9183f23a 155 */
orivant 0:c7da9183f23a 156 uint8_t LcdAcm1602ni::getCurrentLineNo() const
orivant 0:c7da9183f23a 157 {
orivant 0:c7da9183f23a 158 return m_currentLineNo;
orivant 0:c7da9183f23a 159 }
orivant 0:c7da9183f23a 160 /** カーソル位置取得:文字番号
orivant 0:c7da9183f23a 161 */
orivant 0:c7da9183f23a 162 uint8_t LcdAcm1602ni::getCurrentCharaNo() const
orivant 0:c7da9183f23a 163 {
orivant 0:c7da9183f23a 164 return m_currentCharaNo;
orivant 0:c7da9183f23a 165 }
orivant 0:c7da9183f23a 166
orivant 0:c7da9183f23a 167
orivant 0:c7da9183f23a 168 /** 画面クリア
orivant 0:c7da9183f23a 169 */
orivant 0:c7da9183f23a 170 void LcdAcm1602ni::clearDisplay()
orivant 0:c7da9183f23a 171 {
orivant 0:c7da9183f23a 172 writeCommand(0x01);
orivant 0:c7da9183f23a 173 wait_us(2160);
orivant 10:4ceccdba0248 174 locate(0, 0);
orivant 0:c7da9183f23a 175 }
orivant 0:c7da9183f23a 176 /** 行クリア
orivant 0:c7da9183f23a 177 */
orivant 0:c7da9183f23a 178 void LcdAcm1602ni::clearLine(uint8_t lineNo)
orivant 0:c7da9183f23a 179 {
orivant 0:c7da9183f23a 180 if (lineNo >= LINE_COUNT) return;
orivant 0:c7da9183f23a 181
orivant 0:c7da9183f23a 182 // クリアする行の先頭に移動
orivant 0:c7da9183f23a 183 uint8_t addr = calcCursorAddr(lineNo, 0);
orivant 0:c7da9183f23a 184 writeCommand(0x80 | addr);
orivant 0:c7da9183f23a 185 // 1行全体に' '書き込み
orivant 0:c7da9183f23a 186 for (uint8_t i = 0; i < LINE_CHARA_COUNT; i++) {
orivant 0:c7da9183f23a 187 writeData(' ');
orivant 0:c7da9183f23a 188 }
orivant 0:c7da9183f23a 189 // カーソル位置をクリアした行の先頭に移動
orivant 0:c7da9183f23a 190 m_currentLineNo = lineNo;
orivant 0:c7da9183f23a 191 m_currentCharaNo = 0;
orivant 0:c7da9183f23a 192 addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo);
orivant 0:c7da9183f23a 193 writeCommand(0x80 | addr);
orivant 0:c7da9183f23a 194 }
orivant 0:c7da9183f23a 195 /** 範囲クリア
orivant 0:c7da9183f23a 196 */
orivant 0:c7da9183f23a 197 void LcdAcm1602ni::clearRange(uint8_t startLineNo, uint8_t startCharaNo, uint8_t endLineNo, uint8_t endCharaNo)
orivant 0:c7da9183f23a 198 {
orivant 0:c7da9183f23a 199 if (startLineNo >= LINE_COUNT) return;
orivant 0:c7da9183f23a 200 if (startCharaNo >= LINE_CHARA_COUNT) return;
orivant 0:c7da9183f23a 201 if (startLineNo > endLineNo) return;
orivant 0:c7da9183f23a 202 if (startCharaNo > endCharaNo) return;
orivant 0:c7da9183f23a 203 if (endLineNo >= LINE_COUNT) endLineNo = LINE_COUNT - 1;
orivant 0:c7da9183f23a 204 if (endCharaNo >= LINE_CHARA_COUNT) endCharaNo = LINE_CHARA_COUNT - 1;
orivant 0:c7da9183f23a 205
orivant 0:c7da9183f23a 206 uint8_t addr;
orivant 0:c7da9183f23a 207 for (uint8_t lineNo = startLineNo; lineNo <= endLineNo; lineNo++) {
orivant 0:c7da9183f23a 208 // 対象行の削除開始位置にカーソル移動
orivant 0:c7da9183f23a 209 addr = calcCursorAddr(lineNo, startCharaNo);
orivant 0:c7da9183f23a 210 writeCommand(0x80 | addr);
orivant 0:c7da9183f23a 211 // 消す範囲に' 'を書き込み
orivant 0:c7da9183f23a 212 for (uint8_t charaNo = startCharaNo; charaNo <= endCharaNo; charaNo++) {
orivant 0:c7da9183f23a 213 writeData(' ');
orivant 0:c7da9183f23a 214 }
orivant 0:c7da9183f23a 215 }
orivant 0:c7da9183f23a 216 // クリアした範囲の開始位置にカーソルを移動
orivant 0:c7da9183f23a 217 m_currentLineNo = startLineNo;
orivant 0:c7da9183f23a 218 m_currentCharaNo = startCharaNo;
orivant 0:c7da9183f23a 219 addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo);
orivant 0:c7da9183f23a 220 writeCommand(0x80 | addr);
orivant 0:c7da9183f23a 221 }
orivant 0:c7da9183f23a 222
orivant 0:c7da9183f23a 223
orivant 0:c7da9183f23a 224 /** 画面の表示設定
orivant 0:c7da9183f23a 225 */
orivant 0:c7da9183f23a 226 void LcdAcm1602ni::setDisplayVisible(bool visible)
orivant 0:c7da9183f23a 227 {
orivant 0:c7da9183f23a 228 if (m_displayVisible == visible) return;
orivant 0:c7da9183f23a 229 m_displayVisible = visible;
orivant 0:c7da9183f23a 230 uint8_t command = calcDisplayControlByteData();
orivant 0:c7da9183f23a 231 writeCommand(command);
orivant 0:c7da9183f23a 232 }
orivant 0:c7da9183f23a 233 /** 画面の表示設定取得
orivant 0:c7da9183f23a 234 */
orivant 0:c7da9183f23a 235 bool LcdAcm1602ni::getDisplayVisible() const
orivant 0:c7da9183f23a 236 {
orivant 0:c7da9183f23a 237 return m_displayVisible;
orivant 0:c7da9183f23a 238 }
orivant 0:c7da9183f23a 239 /** カーソルの表示設定
orivant 0:c7da9183f23a 240 */
orivant 0:c7da9183f23a 241 void LcdAcm1602ni::setCursorVisible(bool visible)
orivant 0:c7da9183f23a 242 {
orivant 0:c7da9183f23a 243 if (m_cursorVisible == visible) return;
orivant 0:c7da9183f23a 244 m_cursorVisible = visible;
orivant 0:c7da9183f23a 245 uint8_t command = calcDisplayControlByteData();
orivant 0:c7da9183f23a 246 writeCommand(command);
orivant 0:c7da9183f23a 247 }
orivant 0:c7da9183f23a 248 /** カーソルの表示設定取得
orivant 0:c7da9183f23a 249 */
orivant 0:c7da9183f23a 250 bool LcdAcm1602ni::getCursorVisible() const
orivant 0:c7da9183f23a 251 {
orivant 0:c7da9183f23a 252 return m_cursorVisible;
orivant 0:c7da9183f23a 253 }
orivant 0:c7da9183f23a 254 /** カーソルの点滅設定
orivant 0:c7da9183f23a 255 */
orivant 0:c7da9183f23a 256 void LcdAcm1602ni::setBlinkEnable(bool enable)
orivant 0:c7da9183f23a 257 {
orivant 0:c7da9183f23a 258 if (m_blinkEnable == enable) return;
orivant 0:c7da9183f23a 259 m_blinkEnable = enable;
orivant 0:c7da9183f23a 260 uint8_t command = calcDisplayControlByteData();
orivant 0:c7da9183f23a 261 writeCommand(command);
orivant 0:c7da9183f23a 262 }
orivant 0:c7da9183f23a 263 /** カーソルの点滅設定取得
orivant 0:c7da9183f23a 264 */
orivant 0:c7da9183f23a 265 bool LcdAcm1602ni::getBlinkEnable() const
orivant 0:c7da9183f23a 266 {
orivant 0:c7da9183f23a 267 return m_blinkEnable;
orivant 0:c7da9183f23a 268 }
orivant 0:c7da9183f23a 269
orivant 0:c7da9183f23a 270
orivant 0:c7da9183f23a 271 /** LCDコマンド書き込み
orivant 0:c7da9183f23a 272 */
orivant 0:c7da9183f23a 273 void LcdAcm1602ni::writeCommand(uint8_t commandByte)
orivant 0:c7da9183f23a 274 {
orivant 0:c7da9183f23a 275 m_i2c.start();
orivant 0:c7da9183f23a 276 m_i2c.write(ADDR_BYTE_WRITE);
orivant 0:c7da9183f23a 277 m_i2c.write(CTRL_BYTE_COMMAND);
orivant 0:c7da9183f23a 278 m_i2c.write(commandByte);
orivant 0:c7da9183f23a 279 m_i2c.stop();
orivant 0:c7da9183f23a 280 }
orivant 0:c7da9183f23a 281 /** LCDデータ書き込み
orivant 0:c7da9183f23a 282 */
orivant 0:c7da9183f23a 283 void LcdAcm1602ni::writeData(uint8_t dataByte)
orivant 0:c7da9183f23a 284 {
orivant 0:c7da9183f23a 285 m_i2c.start();
orivant 0:c7da9183f23a 286 m_i2c.write(ADDR_BYTE_WRITE);
orivant 0:c7da9183f23a 287 m_i2c.write(CTRL_BYTE_DATA);
orivant 0:c7da9183f23a 288 m_i2c.write(dataByte);
orivant 0:c7da9183f23a 289 m_i2c.stop();
orivant 0:c7da9183f23a 290 }
orivant 0:c7da9183f23a 291
orivant 0:c7da9183f23a 292
orivant 0:c7da9183f23a 293 /** ディスプレイ制御コマンド指定バイトデータの生成
orivant 0:c7da9183f23a 294 */
orivant 0:c7da9183f23a 295 uint8_t LcdAcm1602ni::calcDisplayControlByteData(bool displayVisible, bool cursorVisible, bool blinkEnable) const
orivant 0:c7da9183f23a 296 {
orivant 0:c7da9183f23a 297 uint8_t byteData = 0x08;
orivant 0:c7da9183f23a 298 if (displayVisible) byteData |= 0x04;
orivant 0:c7da9183f23a 299 if (cursorVisible) byteData |= 0x02;
orivant 0:c7da9183f23a 300 if (blinkEnable) byteData |= 0x01;
orivant 0:c7da9183f23a 301 return byteData;
orivant 0:c7da9183f23a 302 }
orivant 0:c7da9183f23a 303
orivant 0:c7da9183f23a 304
orivant 0:c7da9183f23a 305 /** カーソル位置移動管理
orivant 0:c7da9183f23a 306 */
orivant 0:c7da9183f23a 307 bool LcdAcm1602ni::incCursorPos()
orivant 0:c7da9183f23a 308 {
orivant 0:c7da9183f23a 309 m_currentCharaNo++;
orivant 0:c7da9183f23a 310 if (m_currentCharaNo >= LINE_CHARA_COUNT) {
orivant 0:c7da9183f23a 311 m_currentCharaNo = 0;
orivant 0:c7da9183f23a 312 m_currentLineNo = (m_currentLineNo + 1) % LINE_COUNT;
orivant 0:c7da9183f23a 313 return true;
orivant 0:c7da9183f23a 314 }
orivant 0:c7da9183f23a 315 return false;
orivant 0:c7da9183f23a 316 }
orivant 0:c7da9183f23a 317
orivant 0:c7da9183f23a 318
orivant 0:c7da9183f23a 319 /** カーソル位置のアドレス計算
orivant 0:c7da9183f23a 320 */
orivant 0:c7da9183f23a 321 uint8_t LcdAcm1602ni::calcCursorAddr(uint8_t lineNo, uint8_t charaNo)
orivant 0:c7da9183f23a 322 {
orivant 0:c7da9183f23a 323 uint8_t addr = LINE_HEAD_ADDR_TBL[lineNo] + charaNo;
orivant 0:c7da9183f23a 324 return addr;
orivant 0:c7da9183f23a 325 }