Last active
September 20, 2015 08:50
-
-
Save JRHeaton/d4f122bfd5ab90d8aef8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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