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
ACM1602NI.cpp@3:8e405cedea99, 2014-12-14 (annotated)
- Committer:
- CQpub0Mikami
- Date:
- Sun Dec 14 08:19:21 2014 +0000
- Revision:
- 3:8e405cedea99
- Parent:
- 2:56a2f5e674e4
4
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
CQpub0Mikami | 0:ea06bd02d438 | 1 | //------------------------------------------------------- |
CQpub0Mikami | 0:ea06bd02d438 | 2 | // Class for LCD, ACM1602Ni |
CQpub0Mikami | 0:ea06bd02d438 | 3 | // |
CQpub0Mikami | 2:56a2f5e674e4 | 4 | // 2014/12/14, Copyright (c) 2014 MIKAMI, Naoki |
CQpub0Mikami | 0:ea06bd02d438 | 5 | //------------------------------------------------------- |
CQpub0Mikami | 0:ea06bd02d438 | 6 | |
CQpub0Mikami | 0:ea06bd02d438 | 7 | #include "ACM1602NI.hpp" |
CQpub0Mikami | 0:ea06bd02d438 | 8 | |
CQpub0Mikami | 0:ea06bd02d438 | 9 | namespace Mikami |
CQpub0Mikami | 0:ea06bd02d438 | 10 | { |
CQpub0Mikami | 0:ea06bd02d438 | 11 | // Constructor |
CQpub0Mikami | 0:ea06bd02d438 | 12 | Acm1602Ni::Acm1602Ni(PinName sda, PinName scl, uint32_t clock, |
CQpub0Mikami | 0:ea06bd02d438 | 13 | bool cursor, bool blink) |
CQpub0Mikami | 0:ea06bd02d438 | 14 | : i2c_(sda, scl), myI2c_((I2C_TypeDef*)NULL) |
CQpub0Mikami | 0:ea06bd02d438 | 15 | { |
CQpub0Mikami | 0:ea06bd02d438 | 16 | if ( ((sda == PB_9) || (sda == PB_7)) && |
CQpub0Mikami | 0:ea06bd02d438 | 17 | ((scl == PB_8) || (scl == PB_6)) ) |
CQpub0Mikami | 0:ea06bd02d438 | 18 | myI2c_ = (I2C_TypeDef*)I2C_1; // I2C1 will be used |
CQpub0Mikami | 0:ea06bd02d438 | 19 | if ( (sda == PB_3) && (scl == PB_10) ) |
CQpub0Mikami | 0:ea06bd02d438 | 20 | myI2c_ = (I2C_TypeDef*)I2C_2; // I2C2 will be used |
CQpub0Mikami | 0:ea06bd02d438 | 21 | if ( ((sda == PC_9) || (sda == PB_4)) && |
CQpub0Mikami | 0:ea06bd02d438 | 22 | (scl == PA_8) ) |
CQpub0Mikami | 0:ea06bd02d438 | 23 | myI2c_ = (I2C_TypeDef*)I2C_3; // I2C3 will be used |
CQpub0Mikami | 0:ea06bd02d438 | 24 | |
CQpub0Mikami | 0:ea06bd02d438 | 25 | connected_ = Clear(); // Clear display |
CQpub0Mikami | 0:ea06bd02d438 | 26 | if (!connected_) |
CQpub0Mikami | 0:ea06bd02d438 | 27 | { |
CQpub0Mikami | 0:ea06bd02d438 | 28 | fprintf(stderr, "\r\nLCD device not connected\r\n"); |
CQpub0Mikami | 0:ea06bd02d438 | 29 | return; |
CQpub0Mikami | 0:ea06bd02d438 | 30 | } |
CQpub0Mikami | 0:ea06bd02d438 | 31 | if (clock != 100000) i2c_.frequency(clock); |
CQpub0Mikami | 0:ea06bd02d438 | 32 | |
CQpub0Mikami | 0:ea06bd02d438 | 33 | WriteCmd(0x38); // data length:8-bit, 2-line, 5×8 dots |
CQpub0Mikami | 0:ea06bd02d438 | 34 | WriteCmd(0x0C | (cursor << 1) | blink); |
CQpub0Mikami | 0:ea06bd02d438 | 35 | WriteCmd(0x06); // cursor direction: rightward |
CQpub0Mikami | 0:ea06bd02d438 | 36 | } |
CQpub0Mikami | 0:ea06bd02d438 | 37 | |
CQpub0Mikami | 0:ea06bd02d438 | 38 | // All clear |
CQpub0Mikami | 0:ea06bd02d438 | 39 | bool Acm1602Ni::Clear() |
CQpub0Mikami | 0:ea06bd02d438 | 40 | { |
CQpub0Mikami | 0:ea06bd02d438 | 41 | bool ok = WriteCmd(0x01); |
CQpub0Mikami | 0:ea06bd02d438 | 42 | wait_ms(50); |
CQpub0Mikami | 0:ea06bd02d438 | 43 | return ok; |
CQpub0Mikami | 0:ea06bd02d438 | 44 | } |
CQpub0Mikami | 0:ea06bd02d438 | 45 | |
CQpub0Mikami | 1:0a38ce51b9b8 | 46 | // Write string |
CQpub0Mikami | 0:ea06bd02d438 | 47 | void Acm1602Ni::WriteString(const char str[]) |
CQpub0Mikami | 0:ea06bd02d438 | 48 | { |
CQpub0Mikami | 0:ea06bd02d438 | 49 | for (int n=0; n<16; n++) |
CQpub0Mikami | 0:ea06bd02d438 | 50 | if (str[n] == 0) break; |
CQpub0Mikami | 0:ea06bd02d438 | 51 | else WriteChar(str[n]); |
CQpub0Mikami | 0:ea06bd02d438 | 52 | } |
CQpub0Mikami | 0:ea06bd02d438 | 53 | |
CQpub0Mikami | 0:ea06bd02d438 | 54 | // Write string from specified position |
CQpub0Mikami | 0:ea06bd02d438 | 55 | void Acm1602Ni::WriteStringXY(const char str[], |
CQpub0Mikami | 0:ea06bd02d438 | 56 | uint8_t x, uint8_t y) |
CQpub0Mikami | 0:ea06bd02d438 | 57 | { |
CQpub0Mikami | 0:ea06bd02d438 | 58 | SetXY(x, y); |
CQpub0Mikami | 0:ea06bd02d438 | 59 | WriteString(str); |
CQpub0Mikami | 0:ea06bd02d438 | 60 | } |
CQpub0Mikami | 0:ea06bd02d438 | 61 | |
CQpub0Mikami | 0:ea06bd02d438 | 62 | //--------------------------------------------------- |
CQpub0Mikami | 0:ea06bd02d438 | 63 | // Following functions: private |
CQpub0Mikami | 0:ea06bd02d438 | 64 | |
CQpub0Mikami | 0:ea06bd02d438 | 65 | // Send command and data |
CQpub0Mikami | 0:ea06bd02d438 | 66 | bool Acm1602Ni::LcdTx(uint8_t cmdData, uint8_t data) |
CQpub0Mikami | 0:ea06bd02d438 | 67 | { |
CQpub0Mikami | 0:ea06bd02d438 | 68 | if (!Start()) return false; |
CQpub0Mikami | 3:8e405cedea99 | 69 | // defines kind of "data" in next statement |
CQpub0Mikami | 0:ea06bd02d438 | 70 | TxDR(cmdData); |
CQpub0Mikami | 0:ea06bd02d438 | 71 | TxDR(data); |
CQpub0Mikami | 0:ea06bd02d438 | 72 | wait_us(500); // indispensable |
CQpub0Mikami | 0:ea06bd02d438 | 73 | // Generate stop condition |
CQpub0Mikami | 0:ea06bd02d438 | 74 | SetCR1(I2C_CR1_STOP); |
CQpub0Mikami | 0:ea06bd02d438 | 75 | return true; |
CQpub0Mikami | 0:ea06bd02d438 | 76 | } |
CQpub0Mikami | 0:ea06bd02d438 | 77 | |
CQpub0Mikami | 0:ea06bd02d438 | 78 | // Preparation for send of command and data |
CQpub0Mikami | 0:ea06bd02d438 | 79 | bool Acm1602Ni::Start() |
CQpub0Mikami | 0:ea06bd02d438 | 80 | { |
CQpub0Mikami | 2:56a2f5e674e4 | 81 | const uint8_t WAIT = 30; |
CQpub0Mikami | 0:ea06bd02d438 | 82 | const uint8_t LENGTH = 10; |
CQpub0Mikami | 0:ea06bd02d438 | 83 | |
CQpub0Mikami | 0:ea06bd02d438 | 84 | // wait for I2C not busy |
CQpub0Mikami | 0:ea06bd02d438 | 85 | for (int n=0; n<LENGTH; n++) |
CQpub0Mikami | 0:ea06bd02d438 | 86 | { |
CQpub0Mikami | 0:ea06bd02d438 | 87 | wait_us(WAIT); |
CQpub0Mikami | 0:ea06bd02d438 | 88 | if (!CheckSR2(I2C_SR2_BUSY)) break; |
CQpub0Mikami | 0:ea06bd02d438 | 89 | if (n == LENGTH-1) return false; |
CQpub0Mikami | 0:ea06bd02d438 | 90 | } |
CQpub0Mikami | 0:ea06bd02d438 | 91 | |
CQpub0Mikami | 0:ea06bd02d438 | 92 | // Generate start condition |
CQpub0Mikami | 0:ea06bd02d438 | 93 | SetCR1(I2C_CR1_START); |
CQpub0Mikami | 0:ea06bd02d438 | 94 | // Confirm start condition and master mode |
CQpub0Mikami | 0:ea06bd02d438 | 95 | for (int n=0; n<LENGTH; n++) |
CQpub0Mikami | 0:ea06bd02d438 | 96 | { |
CQpub0Mikami | 0:ea06bd02d438 | 97 | wait_us(WAIT); |
CQpub0Mikami | 0:ea06bd02d438 | 98 | if (CheckSR12(I2C_SR1_SB, I2C_SR2_MSL | |
CQpub0Mikami | 0:ea06bd02d438 | 99 | I2C_SR2_BUSY)) break; |
CQpub0Mikami | 0:ea06bd02d438 | 100 | if (n == LENGTH-1) return false; |
CQpub0Mikami | 0:ea06bd02d438 | 101 | } |
CQpub0Mikami | 0:ea06bd02d438 | 102 | |
CQpub0Mikami | 0:ea06bd02d438 | 103 | // Send slave address |
CQpub0Mikami | 0:ea06bd02d438 | 104 | TxDR(LCD_ADDRESS_); |
CQpub0Mikami | 0:ea06bd02d438 | 105 | // Confirm on transmit mode |
CQpub0Mikami | 0:ea06bd02d438 | 106 | for (int n=0; n<LENGTH; n++) |
CQpub0Mikami | 0:ea06bd02d438 | 107 | { |
CQpub0Mikami | 0:ea06bd02d438 | 108 | wait_us(WAIT); |
CQpub0Mikami | 0:ea06bd02d438 | 109 | if (CheckSR12(I2C_SR1_TXE | I2C_SR1_ADDR, |
CQpub0Mikami | 0:ea06bd02d438 | 110 | I2C_SR2_MSL | I2C_SR2_BUSY |
CQpub0Mikami | 0:ea06bd02d438 | 111 | | I2C_SR2_TRA)) break; |
CQpub0Mikami | 0:ea06bd02d438 | 112 | if (n == LENGTH-1) return false; |
CQpub0Mikami | 0:ea06bd02d438 | 113 | } |
CQpub0Mikami | 0:ea06bd02d438 | 114 | |
CQpub0Mikami | 0:ea06bd02d438 | 115 | return true; |
CQpub0Mikami | 0:ea06bd02d438 | 116 | } |
CQpub0Mikami | 0:ea06bd02d438 | 117 | } |