2 ATMega pinout (with LCD_SHIFTREG):
8 ATMega pinout (without LCD_SHIFTREG):
20 In both cases, HD44780 R/W needs to be connected to ground.
28 #define CLOCK_PORT PORTB
29 #define CLOCK_BIT 0x02
30 #define REGSEL_PORT PORTB
31 #define REGSEL_BIT 0x01
33 #define CLOCK_PORT PORTD
34 #define CLOCK_BIT 0x20
35 #define REGSEL_PORT PORTD
36 #define REGSEL_BIT 0x10
40 #define LCD_BUFSIZE 32
43 #define NOP() __asm__("nop")
46 static volatile uint8_t lcd_busy = 0;
47 static uint8_t lcd_buffer[LCD_BUFSIZE];
48 static volatile uint8_t lcd_buf_head = 0;
49 static volatile uint8_t lcd_buf_tail = 0;
52 static void lcd_clock(void)
55 CLOCK_PORT |= CLOCK_BIT;
57 CLOCK_PORT &= ~CLOCK_BIT;
60 static void lcd_set_data(uint8_t d)
63 for(uint8_t i=0; i<8; ++i)
65 PORTB = (PORTB&~0x04)|((d&1)<<2);
72 PORTD = (PORTD&0x3F) | (d<<6);
73 PORTB = (PORTB&0xC0) | (d>>2);
77 static void lcd_command(uint8_t c)
79 REGSEL_PORT &= ~REGSEL_BIT;
84 static void lcd_delay(uint16_t us)
88 timer_start_us(0, us);
95 static void lcd_wait(void)
100 static void lcd_buffer_push(uint8_t byte)
102 while((lcd_buf_head+1)%sizeof(lcd_buffer)==lcd_buf_tail) ;
103 lcd_buffer[lcd_buf_head] = byte;
104 lcd_buf_head = (lcd_buf_head+1)%sizeof(lcd_buffer);
107 static uint8_t lcd_buffer_pop(void)
109 uint8_t byte = lcd_buffer[lcd_buf_tail];
110 lcd_buf_tail = (lcd_buf_tail+1)%sizeof(lcd_buffer);
114 static void lcd_timer(void)
118 if(lcd_buf_head!=lcd_buf_tail)
120 uint8_t byte = lcd_buffer_pop();
123 REGSEL_PORT |= REGSEL_BIT;
124 byte = lcd_buffer_pop();
127 REGSEL_PORT &= ~REGSEL_BIT;
129 REGSEL_PORT |= REGSEL_BIT;
142 TIMER_SET_CALLBACK(0, lcd_timer)
173 void lcd_gotoxy(uint8_t x, uint8_t y)
182 lcd_buffer_push(a|0x80);
191 void lcd_write(uint8_t c)
197 lcd_buffer_push(0xFF);
203 REGSEL_PORT |= REGSEL_BIT;