LCDモジュール ACM1602NI(I2C接続) を制御するライブラリ
Dependents: scan2 BoxController
LcdAcm1602ni.cpp
- Committer:
- orivant
- Date:
- 2016-12-14
- Revision:
- 0:c7da9183f23a
- Child:
- 9:96baac039a90
File content as of revision 0:c7da9183f23a:
/** LCDモジュール ACM1602NI を制御するクラスの定義 */ #include "LcdAcm1602ni.h" const uint8_t LcdAcm1602ni::LINE_HEAD_ADDR_TBL[LINE_COUNT] = {0x00, 0x40}; //!< 行の先頭アドレス /** コンストラクタ */ LcdAcm1602ni::LcdAcm1602ni(PinName pinSDA, PinName pinSCL) :m_pinSDA(pinSDA) ,m_pinSCL(pinSCL) ,m_i2c(pinSDA, pinSCL) ,m_currentLineNo(0) ,m_currentCharaNo(0) ,m_displayVisible(true) ,m_cursorVisible(false) ,m_blinkEnable(false) { } /** デストラクタ */ LcdAcm1602ni::~LcdAcm1602ni() { } /** 初期化 */ void LcdAcm1602ni::initialize() { // I2C通信の周波数設定 m_i2c.frequency(I2C_MAX_FREQUENCY); uint8_t command; // ディスプレイを消す command = calcDisplayControlByteData(false, false, false); writeCommand(command); wait_us(53); // ファンクション設定(0011[8bitモード]1[2行モード]0[文字5x8表示モー]00 = 00111000 = 0x38) writeCommand(0x38); wait_us(53); // 画面クリア(00000001 = 0x01) writeCommand(0x01); wait_us(2160); // データ書き込み後アドレス加算モード設定(0000011[インクリメント]0 = 00000110 = 0x06) writeCommand(0x06); wait_us(53); // ディスプレイ表示 command = calcDisplayControlByteData(); writeCommand(command); wait_us(53); } /** 1文字描画 */ void LcdAcm1602ni::putc(char c) { // 1文字書き込み writeData(c); // カーソル位置管理処理 bool ret = incCursorPos(); if (ret) { // 復帰・改行が発生したのでカーソル位置変更 uint8_t addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo); writeCommand(0x80 | addr); } } /** 文字列描画 */ void LcdAcm1602ni::puts(const char* pStr) { uint8_t addr; bool ret; const char* pt = pStr; bool stayLocate = false; while (*pt) { const char &c = *pt; if (c == '\r') { // 復帰コードの場合、行の先頭にカーソルを移動する m_currentCharaNo = 0; // 実際の移動処理は後で行う stayLocate = true; } else if (c == '\n') { // 改行コードの場合、次の行にカーソルを移動する m_currentLineNo = (m_currentLineNo + 1) % LINE_COUNT; // 実際の移動処理は後で行う stayLocate = true; } else { // 通常の文字コードの場合 if (stayLocate) { // 復帰・改行の予約がある場合は先に処理 addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo); writeCommand(0x80 | addr); stayLocate = false; } // 1文字書き込み writeData(c); // カーソル位置管理処理 ret = incCursorPos(); if (ret) { // 改行が発生したのでカーソル位置変更 // 実際の移動処理は後で行う stayLocate = true; } } pt++; } if (stayLocate) { // 復帰・改行の予約が残っている場合は処理する addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo); writeCommand(0x80 | addr); } } /** フォーマット指定描画 */ void LcdAcm1602ni::printf(const char* pFormat, ...) { va_list ap; va_start(ap, pFormat); char* allocatedBuffer; int size = vasprintf(&allocatedBuffer, pFormat, ap); va_end(ap); puts(allocatedBuffer); free(allocatedBuffer); } /** カーソル位置変更 */ void LcdAcm1602ni::locate(uint8_t lineNo, uint8_t charaNo) { if (lineNo >= LINE_COUNT) lineNo = LINE_COUNT - 1; if (charaNo >= LINE_CHARA_COUNT) charaNo = LINE_CHARA_COUNT - 1; m_currentLineNo = lineNo; m_currentCharaNo = charaNo; uint8_t addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo); writeCommand(0x80 | addr); } /** カーソル位置取得:行番号 */ uint8_t LcdAcm1602ni::getCurrentLineNo() const { return m_currentLineNo; } /** カーソル位置取得:文字番号 */ uint8_t LcdAcm1602ni::getCurrentCharaNo() const { return m_currentCharaNo; } /** 画面クリア */ void LcdAcm1602ni::clearDisplay() { writeCommand(0x01); wait_us(2160); } /** 行クリア */ void LcdAcm1602ni::clearLine(uint8_t lineNo) { if (lineNo >= LINE_COUNT) return; // クリアする行の先頭に移動 uint8_t addr = calcCursorAddr(lineNo, 0); writeCommand(0x80 | addr); // 1行全体に' '書き込み for (uint8_t i = 0; i < LINE_CHARA_COUNT; i++) { writeData(' '); } // カーソル位置をクリアした行の先頭に移動 m_currentLineNo = lineNo; m_currentCharaNo = 0; addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo); writeCommand(0x80 | addr); } /** 範囲クリア */ void LcdAcm1602ni::clearRange(uint8_t startLineNo, uint8_t startCharaNo, uint8_t endLineNo, uint8_t endCharaNo) { if (startLineNo >= LINE_COUNT) return; if (startCharaNo >= LINE_CHARA_COUNT) return; if (startLineNo > endLineNo) return; if (startCharaNo > endCharaNo) return; if (endLineNo >= LINE_COUNT) endLineNo = LINE_COUNT - 1; if (endCharaNo >= LINE_CHARA_COUNT) endCharaNo = LINE_CHARA_COUNT - 1; uint8_t addr; for (uint8_t lineNo = startLineNo; lineNo <= endLineNo; lineNo++) { // 対象行の削除開始位置にカーソル移動 addr = calcCursorAddr(lineNo, startCharaNo); writeCommand(0x80 | addr); // 消す範囲に' 'を書き込み for (uint8_t charaNo = startCharaNo; charaNo <= endCharaNo; charaNo++) { writeData(' '); } } // クリアした範囲の開始位置にカーソルを移動 m_currentLineNo = startLineNo; m_currentCharaNo = startCharaNo; addr = calcCursorAddr(m_currentLineNo, m_currentCharaNo); writeCommand(0x80 | addr); } /** 画面の表示設定 */ void LcdAcm1602ni::setDisplayVisible(bool visible) { if (m_displayVisible == visible) return; m_displayVisible = visible; uint8_t command = calcDisplayControlByteData(); writeCommand(command); } /** 画面の表示設定取得 */ bool LcdAcm1602ni::getDisplayVisible() const { return m_displayVisible; } /** カーソルの表示設定 */ void LcdAcm1602ni::setCursorVisible(bool visible) { if (m_cursorVisible == visible) return; m_cursorVisible = visible; uint8_t command = calcDisplayControlByteData(); writeCommand(command); } /** カーソルの表示設定取得 */ bool LcdAcm1602ni::getCursorVisible() const { return m_cursorVisible; } /** カーソルの点滅設定 */ void LcdAcm1602ni::setBlinkEnable(bool enable) { if (m_blinkEnable == enable) return; m_blinkEnable = enable; uint8_t command = calcDisplayControlByteData(); writeCommand(command); } /** カーソルの点滅設定取得 */ bool LcdAcm1602ni::getBlinkEnable() const { return m_blinkEnable; } /** LCDコマンド書き込み */ void LcdAcm1602ni::writeCommand(uint8_t commandByte) { m_i2c.start(); m_i2c.write(ADDR_BYTE_WRITE); m_i2c.write(CTRL_BYTE_COMMAND); m_i2c.write(commandByte); m_i2c.stop(); } /** LCDデータ書き込み */ void LcdAcm1602ni::writeData(uint8_t dataByte) { m_i2c.start(); m_i2c.write(ADDR_BYTE_WRITE); m_i2c.write(CTRL_BYTE_DATA); m_i2c.write(dataByte); m_i2c.stop(); } /** ディスプレイ制御コマンド指定バイトデータの生成 */ uint8_t LcdAcm1602ni::calcDisplayControlByteData(bool displayVisible, bool cursorVisible, bool blinkEnable) const { uint8_t byteData = 0x08; if (displayVisible) byteData |= 0x04; if (cursorVisible) byteData |= 0x02; if (blinkEnable) byteData |= 0x01; return byteData; } /** カーソル位置移動管理 */ bool LcdAcm1602ni::incCursorPos() { m_currentCharaNo++; if (m_currentCharaNo >= LINE_CHARA_COUNT) { m_currentCharaNo = 0; m_currentLineNo = (m_currentLineNo + 1) % LINE_COUNT; return true; } return false; } /** カーソル位置のアドレス計算 */ uint8_t LcdAcm1602ni::calcCursorAddr(uint8_t lineNo, uint8_t charaNo) { uint8_t addr = LINE_HEAD_ADDR_TBL[lineNo] + charaNo; return addr; }