Skip to content

Instantly share code, notes, and snippets.

@JRHeaton
Last active September 20, 2015 08:50
Show Gist options
  • Save JRHeaton/d4f122bfd5ab90d8aef8 to your computer and use it in GitHub Desktop.
Save JRHeaton/d4f122bfd5ab90d8aef8 to your computer and use it in GitHub Desktop.
// 8mhz internal
#define F_CPU 8000000
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
// 8 bit LCD logic pins
#define LCD_DATA_DIRECTION DDRB
#define LCD_DATA_PORT PORTB
#define LCD_DATA_INPUT PINB
// LCD control pins
#define LCD_CONTROL_DIRECTION DDRC
#define LCD_CONTROL_PORT PORTC
#define LCD_RS PC5
#define LCD_RW PC4
#define LCD_E PC3
// Test LED
#define LED_DIRECTION DDRC
#define LED_PORT PORTC
#define LED PC2
// Bitwise macros
#define BYTE(bit) (1 << (bit))
#define SET(b, bit) ((b) |= BYTE(bit))
#define UNSET(b, bit) ((b) &= ~BYTE(bit))
// Configuration
#define LCD_STROBE_DURATION 1
// Used for stdout
FILE lcd_file;
typedef unsigned char byte;
typedef volatile byte addr;
class LCD {
public:
LCD(addr *data_dir, addr *data_port, addr *data_pin,
addr *ctrl_dir, addr *ctrl_port,
byte rs, byte rw, byte e) :
data_dir(data_dir), data_port(data_port), data_pin(data_pin),
ctrl_dir(ctrl_dir), ctrl_port(ctrl_port),
rs(rs), rw(rw), e(e)
{
*ctrl_dir = BYTE(LCD_RS) | BYTE(LCD_RW) | BYTE(LCD_E);
*data_dir = (byte)0xFF;
}
void selectDR() {
SET(*ctrl_port, rs);
}
void selectIR() {
UNSET(*ctrl_port, rs);
}
void setRead(bool read) {
if (read) { SET(*ctrl_port, rw); }
else { UNSET(*ctrl_port, rw); }
}
void setEnable(bool enable) {
if (enable) { SET(*ctrl_port, e); }
else { UNSET(*ctrl_port, e); }
}
void strobeEnable() {
setEnable(true);
_delay_ms(LCD_STROBE_DURATION);
setEnable(false);
}
unsigned char readBusyFlag() {
// direction = input
*data_dir = 0;
setRead(true);
selectIR();
setEnable(true);
_delay_ms(LCD_STROBE_DURATION);
unsigned char ret = *data_pin;
setEnable(false);
// direction = output
*data_dir = 0xFF;
return ret;
}
void busyWait() {
while ((readBusyFlag() & 0x80) == 0x80) {}
}
void sendCommand(unsigned char cmd) {
busyWait();
*data_port = cmd;
setRead(false);
selectIR();
strobeEnable();
*data_port = 0;
}
void sendCharacter(char character) {
busyWait();
*data_port = character;
setRead(false);
selectDR();
strobeEnable();
*data_port = 0;
}
void sendString(const char *string) {
char *str = (char *)string;
while (*str != '\0') {
sendCharacter(*str++);
}
}
protected:
addr *data_dir, *data_port, *data_pin;
addr *ctrl_dir, *ctrl_port;
byte rs, rw, e;
};
int lcd_put(char c, FILE *f) {
if (c == '\n') {
return 0;
}
LCD *lcd = (LCD *)f->udata;
if (lcd != NULL) {
lcd->sendCharacter(c);
}
return 0;
}
int main() {
LED_DIRECTION = 0xFF;
SET(LED_PORT, LED);
LCD m(&LCD_DATA_DIRECTION, &LCD_DATA_PORT, &LCD_DATA_INPUT,
&LCD_CONTROL_DIRECTION, &LCD_CONTROL_PORT,
LCD_RS, LCD_RW, LCD_E);
lcd_file.put = lcd_put;
lcd_file.udata = &m;
lcd_file.flags = __SWR;
stdout = &lcd_file;
m.sendCommand(0b00111000); // 2 line display, 8 bit logic config
m.sendCommand(0b00000010); // return cursor to 0
m.sendCommand(0b00001111); // cursor on, cursor blinking, display on
puts("hi dan!");
while(1) {}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment