ATTiny2313 LCD and Keypad Controller
ATTiny2313 LCD and Keypad Controller
This document describes the I2C LCD controller – designed to control LCD displays with the
HD4470 parallel interface.
An ATIny2313 micro controller was chosen for this project. The code for this stretches the
ATTiny2313 to its limit in terms of size
Character codes 0xfe and 0xff (decimal 254 and 255) are special codes, so to send
these we need to precede them with 0xfe.
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
sendStr("Hello World");
}
void loop()
{
}
void sendStr(char* b)
{
Wire.beginTransmission(0x12); // transmit to device 12
while (*b)
{
if (*b == 0xfe || *b == 0xff) Wire.send(0xfe);
Wire.send(*b++); // sends one byte
}
Wire.endTransmission(); // stop transmitting
delay(2);
}
b. Commands (HD4470)
All the HD4470 commands are prefixed by 0xfe (decimal 254).
For full details please see the HD4470 data sheet.
For command 0x01 and 0x02 add a delay of 2mS after the command. For all other
commands a delay of 50uS is sufficient.
Some of the supported commands are:
0xfe, 0x01 Clears entire display and sets cursor to the beginning
0xfe, 0x02 Clears entire display and undoes any shift
0xfe, 0x08 sets display options – OR with
0x04 display on /off
0x02 Cursor on / off
0x01 Cursor blinking on / off
0xfe, 0x10 Shift display or cursor – OR with
0x08 Cursor = 0, display = 1
0x04 shift right = 1, shift left = 0
0xfe, 0x40 Set into programmable character mode – OR with
CGRAM address. Subsequent data sent programmes the
characters and does not display on the LCD.
0xfe, 0x80 Set back to ‘normal’ character mode and position the cursor
OR with the cursor address. See the HD4470 datasheet for
Information on how to work out cursor addresses.
Subsequent data sent is displayed on the LCD
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
clearLCD();
sendStr("Hello World");
}
void loop()
{
}
void sendStr(char* b)
{
Wire.beginTransmission(0x12); // transmit to device 12
while (*b)
{
if (*b == 0xfe || *b == 0xff) Wire.send(0xfe);
Wire.send(*b++); // sends one byte
}
Wire.endTransmission(); // stop transmitting
delay(2);
}
void clearLCD()
{
Wire.beginTransmission(0x12); // transmit to device 12
Wire.send(0xfe); // signal command follows
Wire.send(0x01); // send the command
Wire.endTransmission(); // stop transmitting
delay(2);
}
c. Extended commands
All the extended commands are prefixed with 0xff (decimal 255).
i. Backlight
0xff, 0x01, BL BL =0 backlight off, otherwise on
Arduino code:
ii. EEPROM
0xff, 0x02, addr Reads EEPROM address addr
0xff, 0x03, addr, value Write value into EEPROM address addr
0xff, 0x04, addr Display zero terminated string at EEPROM
address addr.
Arduino code:
iii. Reset
0xff, 0xf0 Reset EEPROM to defaults and reset the chip
0xff, 0xf1 reset the chip – reading current values from EEPROM
Arduino code:
All key presses are debounced for 30mS – debounce period can be modified
at EEPROM address 6.
Commands:
0xff, 0x10 Returns one byte – number of keys in buffer
0xff, 0x11 Returns next key in buffer, and removes it from the buffer
0xff, 0x12 returns the keycode for a key currently held down
0xff, 0x13 clears the buffer
0xff, 0x14, n Read n bytes from the keypad buffer
0xff, 0x15 Interrupt pin off
0xff, 0x16 Interrupt pin on
Arduino code:
byte readKeyp()
{
Wire.beginTransmission(0x12); // transmit to device 12
Wire.send(0xFF); // sends command flag
Wire.send(0x11); // read next key
Wire.endTransmission(); // stop transmitting
delay(2);
Wire.requestFrom(0x12,1);
return Wire.receive(); // get the next char in the
// buffer
// note zero is returned if none
}
6. Keypad mapping
EEPROM address 8 is the value used for no key in the buffer, default is 0.