OpenRTX/lib/miosix-kernel/miosix/util/lcd44780.cpp

101 wiersze
2.0 KiB
C++

#include <stdio.h>
#include <stdarg.h>
#include "miosix.h"
#include "interfaces/delays.h"
#include "lcd44780.h"
namespace miosix {
Lcd44780::Lcd44780(miosix::GpioPin rs, miosix::GpioPin e, miosix::GpioPin d4,
miosix::GpioPin d5, miosix::GpioPin d6, miosix::GpioPin d7,
int row, int col) : rs(rs), e(e), d4(d4), d5(d5), d6(d6), d7(d7),
row(row), col(col)
{
rs.mode(Mode::OUTPUT);
e.mode(Mode::OUTPUT);
d4.mode(Mode::OUTPUT);
d5.mode(Mode::OUTPUT);
d6.mode(Mode::OUTPUT);
d7.mode(Mode::OUTPUT);
e.low();
Thread::sleep(50); //Powerup delay
init();
clear();
}
void Lcd44780::go(int x, int y)
{
if(x<0 || x>=col || y<0 || y>=row) return;
// 4x20 is implemented as 2x40.
// TODO Test 4x16 display.
if(y>1)
{
x += col;
}
comd(0x80 | ((y & 1) ? 0x40 : 0) | x); //Move cursor
}
int Lcd44780::printf(const char* fmt, ...)
{
va_list arg;
char line[40];
va_start(arg,fmt);
int len=vsnprintf(line,sizeof(line),fmt,arg);
va_end(arg);
for(int i=0;i<len;i++) data(line[i]);
return len;
}
void Lcd44780::clear()
{
comd(1);
Thread::sleep(2); //Some displays require this delay
}
void Lcd44780::init()
{
rs.low();
half(0x20);
rs.high();
delayUs(50);
if(row==1) comd(32); else comd(40);
Thread::sleep(5); //Initialization delay
comd(12); //Display ON, cursor OFF, blink OFF
comd(6); //Auto increment ON, shift OFF
}
void Lcd44780::half(unsigned char byte)
{
if(byte & (1<<7)) d7.high(); else d7.low(); //Not much fast, but works
if(byte & (1<<6)) d6.high(); else d6.low();
if(byte & (1<<5)) d5.high(); else d5.low();
if(byte & (1<<4)) d4.high(); else d4.low();
delayUs(1);
e.high();
delayUs(1);
e.low();
}
void Lcd44780::data(unsigned char byte)
{
half(byte);
byte<<=4;
half(byte);
delayUs(50);
}
void Lcd44780::comd(unsigned char byte)
{
rs.low();
half(byte);
byte<<=4;
half(byte);
delayUs(50);
rs.high();
}
} //namespace miosix