Library for LCD ACM1602NI connected using I2C interface on Nucleo F401/411. Nucleo F401/411RE で使える I2C 接続の LCD ACM1602NI 用のライブラリ.
Dependents: ACM1602NI_NucleoF4_Demo ACM1602NI_NucleoF4_Demo
Revision 0:ea06bd02d438, committed 2014-11-06
- Comitter:
- CQpub0Mikami
- Date:
- Thu Nov 06 23:48:52 2014 +0000
- Child:
- 1:0a38ce51b9b8
- Commit message:
- 1
Changed in this revision
ACM1602NI.cpp | Show annotated file Show diff for this revision Revisions of this file |
ACM1602NI.hpp | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ACM1602NI.cpp Thu Nov 06 23:48:52 2014 +0000 @@ -0,0 +1,117 @@ +//------------------------------------------------------- +// Class for LCD, ACM1602Ni +// +// 2014/10/14, Copyright (c) 2014 MIKAMI, Naoki +//------------------------------------------------------- + +#include "ACM1602NI.hpp" + +namespace Mikami +{ + // Constructor + Acm1602Ni::Acm1602Ni(PinName sda, PinName scl, uint32_t clock, + bool cursor, bool blink) + : i2c_(sda, scl), myI2c_((I2C_TypeDef*)NULL) + { + if ( ((sda == PB_9) || (sda == PB_7)) && + ((scl == PB_8) || (scl == PB_6)) ) + myI2c_ = (I2C_TypeDef*)I2C_1; // I2C1 will be used + if ( (sda == PB_3) && (scl == PB_10) ) + myI2c_ = (I2C_TypeDef*)I2C_2; // I2C2 will be used + if ( ((sda == PC_9) || (sda == PB_4)) && + (scl == PA_8) ) + myI2c_ = (I2C_TypeDef*)I2C_3; // I2C3 will be used + + connected_ = Clear(); // Clear display + if (!connected_) + { + fprintf(stderr, "\r\nLCD device not connected\r\n"); + return; + } + if (clock != 100000) i2c_.frequency(clock); + + WriteCmd(0x38); // data length:8-bit, 2-line, 5×8 dots + WriteCmd(0x0C | (cursor << 1) | blink); + WriteCmd(0x06); // cursor direction: rightward + } + + // All clear + bool Acm1602Ni::Clear() + { + bool ok = WriteCmd(0x01); + wait_ms(50); + return ok; + } + + // Write string from specified position + void Acm1602Ni::WriteString(const char str[]) + { + for (int n=0; n<16; n++) + if (str[n] == 0) break; + else WriteChar(str[n]); + } + + // Write string from specified position + void Acm1602Ni::WriteStringXY(const char str[], + uint8_t x, uint8_t y) + { + SetXY(x, y); + WriteString(str); + } + + //--------------------------------------------------- + // Following functions: private + + // Send command and data + bool Acm1602Ni::LcdTx(uint8_t cmdData, uint8_t data) + { + if (!Start()) return false; + // defines king of "data" in next statement + TxDR(cmdData); + TxDR(data); + wait_us(500); // indispensable + // Generate stop condition + SetCR1(I2C_CR1_STOP); + return true; + } + + // Preparation for send of command and data + bool Acm1602Ni::Start() + { + const uint8_t WAIT = 20; + const uint8_t LENGTH = 10; + + // wait for I2C not busy + for (int n=0; n<LENGTH; n++) + { + wait_us(WAIT); + if (!CheckSR2(I2C_SR2_BUSY)) break; + if (n == LENGTH-1) return false; + } + + // Generate start condition + SetCR1(I2C_CR1_START); + // Confirm start condition and master mode + for (int n=0; n<LENGTH; n++) + { + wait_us(WAIT); + if (CheckSR12(I2C_SR1_SB, I2C_SR2_MSL | + I2C_SR2_BUSY)) break; + if (n == LENGTH-1) return false; + } + + // Send slave address + TxDR(LCD_ADDRESS_); + // Confirm on transmit mode + for (int n=0; n<LENGTH; n++) + { + wait_us(WAIT); + if (CheckSR12(I2C_SR1_TXE | I2C_SR1_ADDR, + I2C_SR2_MSL | I2C_SR2_BUSY + | I2C_SR2_TRA)) break; + if (n == LENGTH-1) return false; + } + + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ACM1602NI.hpp Thu Nov 06 23:48:52 2014 +0000 @@ -0,0 +1,87 @@ +//------------------------------------------------------- +// Class for LCD, ACM1602Ni (Header) +// +// Default pin assignments +// D14 SDA ---- to pin5 of LCD module +// D15 SCL ---- to pin4 of LCD module +// +// Assignment of I2C ports +// SDA SCL +// I2C1 PB_7 or PB_9(D14) PB_6(D10) or PB_8(D15) +// I2C2 PB_3(D3) PB_10(D6) +// I2C3 PB_4(D5) or PC_9 PA_8(D7) +// +// 2014/10/14, Copyright (c) 2014 MIKAMI, Naoki +//------------------------------------------------------- +// I2C_TypeDef: See stm32f401xe.h on following URL +// http://mbed.org/users/mbed_official/code/mbed/file/ +// 552587b429a1/TARGET_NUCLEO_F401RE +//------------------------------------------------------- + +#ifndef ACM1602NI_HPP +#define ACM1602NI_HPP + +#include "mbed.h" + +namespace Mikami +{ + class Acm1602Ni + { + public: + // Constructor + Acm1602Ni(PinName sda = D14, // SDA + PinName scl = D15, // SCL + uint32_t clock = 100000, // clock: 100 kHz + bool cursor = false, // cursor: off + bool blink = false); // blink: off + // Return false if LCD is not connected + bool GetOk() { return connected_; } + // All clear + bool Clear(); + // Send command + bool WriteCmd(uint8_t cmd) { return LcdTx(0x00, cmd); } + // Write character + void WriteChar(char data) { LcdTx(0x80, data); } + // Specify display position, x: 0 - 15, y: 0, 1 + void SetXY(uint8_t x = 0, uint8_t y = 0) + { WriteCmd(x + y*0x40 | 0x80);} + // Write string + void WriteString(const char str[]); + // Write string from specified position + void WriteStringXY(const char str[], uint8_t x, uint8_t); + // Clear of specified line + void ClearLine(uint8_t line) + { WriteStringXY(" ", 0, line); } + + private: + // Slave address of ACM1602NI (0x50) + // left-justified 7-bit address + static const uint8_t LCD_ADDRESS_ = 0x50 << 1; + + I2C i2c_; // Object of I2C + I2C_TypeDef* myI2c_; // Pointer of I2C + + bool connected_; // false: LCD is not connected + + bool LcdTx(uint8_t cmdData, uint8_t data); + bool Start(); + + // Forbid to use copy constructor + Acm1602Ni(const Acm1602Ni&); + // Forbid to use substitution operator + Acm1602Ni& operator=(const Acm1602Ni&); + + // For check contents of SR2 + bool CheckSR2(uint16_t value) + { return value == (myI2c_->SR2 & value); } + + // For check contents of SR1 and SR2 + bool CheckSR12(uint16_t v1, uint16_t v2) + { return (v1 == (myI2c_->SR1 & v1)) && + (v2 == (myI2c_->SR2 & v2)); } + + void TxDR(uint8_t data) { myI2c_->DR = data; } + void SetCR1(uint16_t data) { myI2c_->CR1 |= data; } + }; +} +#endif // ACM1602NI_HPP