Library for LCD ACM1602NI connected using I2C on Nucleo F401 is not to be found. Using I2C class offered by mbed, I cannot program for this LCD on Nucleo F401. So I programmed for this LCD to control by direct accsessing registors for I2C in STM32F401RE. Nucleo F401 で使用できる,I2C 接続の LCD ACM1602NI 用のライブラリ.このライブラリでは,I2C クラスのコンストラクタとクロック周波数設定のメンバ関数は使っているが,その他のメンバ関数などは使っていない.その理由は,タイミングの関係だと思うが,I2C クラスのメンバ関数では正常に動くプログラムを,どうしても作れないことによる.しょうがないので,MCU の I2C 関係のレジスタに直接アクセスするようなプログラムを作ったたところ,動くようになった.Nucleo の F401RE 以外については確認していない.動かない場合は,I2C 用のレジスタのアドレスを,使っている MCU に応じて書きかえる必要がある.
Dependents: ACM1602NI_Nucleo_Demo
ACM1602NI.cpp
00001 //------------------------------------------------------ 00002 // Class for LCD, ACM1602NI 00003 // 00004 // 2014/08/27, Copyright (c) 2014 MIKAMI, Naoki 00005 //------------------------------------------------------ 00006 00007 #include "ACM1602NI.hpp" 00008 00009 namespace Mikami 00010 { 00011 // Constructor 00012 Acm1602Ni::Acm1602Ni(PinName sda, PinName scl, uint32_t clock, 00013 bool cursor, bool blink) 00014 : i2c_(sda, scl) 00015 { 00016 uint32_t i2cAddr = 0; 00017 if ( ((sda == PB_9) || (sda == PB_7)) && 00018 ((scl == PB_8) || (scl == PB_6)) ) 00019 i2cAddr = I2C_1; // I2C1 will be used 00020 if ( (sda == PB_3) && (scl == PB_10) ) 00021 i2cAddr = I2C_2; // I2C2 will be used 00022 if ( ((sda == PC_9) || (sda == PB_4)) && 00023 (scl == PA_8) ) 00024 i2cAddr = I2C_3; // I2C3 will be used 00025 00026 i2c_cr1_ = (uint32_t *)i2cAddr; 00027 i2c_dr_ = (uint32_t *)(i2cAddr + 0x10); 00028 i2c_sr1_ = (uint32_t *)(i2cAddr + 0x14); 00029 i2c_sr2_ = (uint32_t *)(i2cAddr + 0x18); 00030 00031 connected_ = Clear(); // Clear display 00032 if (!connected_) return; 00033 00034 if (clock != 100000) i2c_.frequency(clock); 00035 00036 WriteCmd(0x38); // data length:8-bit, 2-line, 5×8 dots 00037 WriteCmd(0x0C | (cursor << 1) | blink); 00038 WriteCmd(0x06); // cursor direction: rightward 00039 } 00040 00041 // All clear 00042 bool Acm1602Ni::Clear() 00043 { 00044 bool ok = WriteCmd(0x01); 00045 wait_ms(50); 00046 return ok; 00047 } 00048 00049 // Write string from specified position 00050 void Acm1602Ni::WriteString(const char str[], uint8_t x, uint8_t y) 00051 { 00052 SetXY(x, y); 00053 for (int n=0; n<16; n++) 00054 if (str[n] == 0) break; 00055 else WriteChar(str[n]); 00056 } 00057 00058 //------------------------------------------------------------------------------ 00059 // Following: private functions 00060 00061 // Send command and data 00062 bool Acm1602Ni::LcdTx(uint8_t cmdData, uint8_t data) 00063 { 00064 if (!Start()) return false; 00065 TxDR(cmdData); // "cmdData" defines king of "data" in next statement 00066 TxDR(data); // Send command or RAM dataspecify specified by "cmdData" 00067 wait_us(500); // indispensable 00068 SetCR1(0x200); // Generate stop condition 00069 return true; 00070 } 00071 00072 // Preparation for send of command and data 00073 bool Acm1602Ni::Start() 00074 { 00075 const uint8_t WAIT = 20; 00076 const uint8_t LENGTH = 10; 00077 uint8_t n; 00078 00079 // wait for I2C not busy 00080 for (n=0; n<LENGTH; n++) 00081 { 00082 wait_us(WAIT); 00083 if (!Check(i2c_sr2_, 0x02)) break; 00084 } 00085 if (n == LENGTH) return false; 00086 00087 // Generate start condition 00088 SetCR1(0x100); 00089 // Confirm start condition and master mode 00090 for (n=0; n<LENGTH; n++) 00091 { 00092 wait_us(WAIT); 00093 if (Check(i2c_sr1_, 0x01) && Check(i2c_sr2_, 0x03)) break; 00094 } 00095 if (n == LENGTH) return false; 00096 00097 // Send slave address 00098 TxDR(LCD_ADDRESS_); 00099 // Confirm on transmit mode 00100 for (n=0; n<LENGTH; n++) 00101 { 00102 wait_us(WAIT); 00103 if (Check(i2c_sr1_, 0x82) && Check(i2c_sr2_, 0x07)) break; 00104 } 00105 if (n == LENGTH) return false; 00106 00107 return true; 00108 } 00109 }
Generated on Wed Jul 13 2022 09:31:04 by 1.7.2