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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ACM1602NI.cpp Source File

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 }