/* * "THE BEER-WARE LICENSE" (Revision 42): * Martin Wenger and Stefan Rupp * wrote this file. As long as you retain this notice you can do whatever you want * with this stuff. If we meet some day, and you think this stuff is worth it, * you can buy me/us a beer in return. * (c) 2005-2010 Martin Wenger, Stefan Rupp * (c) 2014 Stefan Rupp */ #include #include #include #include // ==> _NOP() #include "timer.h" #include "lcd.h" #define LCD_DATA_PIN (PINA) #define LCD_DATA_PORT (PORTA) #define LCD_DATA_DIR (DDRA) #define LCD_DATA_MASK (0x0f) #if (F_CPU <= 4000000UL) #define WAIT_250_ns() _NOP() #elif (F_CPU <= 8000000UL) #define WAIT_250_ns() _NOP();_NOP() #elif (F_CPU <= 12000000UL) #define WAIT_250_ns() _NOP();_NOP();_NOP() #elif (F_CPU <= 16000000UL) #define WAIT_250_ns() _NOP();_NOP();_NOP();_NOP() #elif (F_CPU <= 20000000UL) #define WAIT_250_ns() _NOP();_NOP();_NOP();_NOP();_NOP() #else #include #define WAIT_250_ns() _delay_us(1) #endif #define LCD_DATA_MODE() (PORTA |= (1<> 4); _NOP(); send_nibble(0x0f & byte); } int lcd_get(void) { lcd_wait_while_busy(); return lcd_read_byte(1); } int lcd_put(char c) { lcd_send_byte(c, 1); return 0; } void lcd_puts(char *s) { while (*s) { //lcd_put(*s++); lcd_send_byte(*s++, 1); } } void lcd_cursor(uint8_t blink) { if (blink) { // enable display with cursor + blinking lcd_send_byte(0x0f, 0); } else { // enable display, no cursor, no blinking lcd_send_byte(0x0c, 0); return; } } void lcd_init(void) { /* Initialize both ATmega and Display * After return from this function, * display we be set to 4-bit data mode */ // wait until LCD gets ready to accept instructions. timer_wait(50); // set CONTROL Pins as outputs: DDRA |= (0x70); LCD_CMD_MODE(); LCD_SET_WRITE(); // set LCD to 8-bit mode send_nibble(0x03); timer_wait(5); send_nibble(0x03); timer_wait(5); send_nibble(0x03); // LCD definitely is in 8-bit mode now // set module to 4-bit mode now // Remember! As we're in 8-bit mode now, // send_nibble is the right thing, not send_byte! timer_wait(5); send_nibble(0x02); timer_wait(5); // set to 5 x 8 dots per character, // 16 characters per line, 2 lines lcd_send_byte(0x28, 0); // enable display, no cursor, no blinking //lcd_send_byte(0x0c, 0); // enable display with cursor + blinking //lcd_send_byte(0x0f, 0); lcd_cursor(1); // Set display to // + Move cursor (and do not shift display) // + Move right lcd_send_byte(0x04, 0); // clear dislay lcd_clear(); return; } void lcd_clear(void) { lcd_send_byte(0x01, 0); } void lcd_locate(uint8_t row, uint8_t col) { if (row) col += 0x40; lcd_send_byte(0x80 + col, 0); }