#include "config.h" #include #include #include #define LCD_DATA_PORT PORTB #define LCD_DATA_DDR DDRB #define LCD_RS_PIN PB1 #define LCD_EN_PIN PB2 #define LCD_DB4 PB3 #define LCD_DB5 PB4 #define LCD_DB6 PB5 #define LCD_DB7 PB6 // Delay constants from the datasheet. These are mostly in nanoseconds #define LAG 10 #define TW 300 #define TSU1 100 void lcd_4bit_init() { LCD_DATA_DDR = 0xFF; LCD_DATA_PORT = (1 << LCD_DB5); LCD_DATA_PORT &= ~(1 << LCD_RS_PIN); _delay_us(1); LCD_DATA_PORT |= (1 << LCD_EN_PIN); _delay_us(1); LCD_DATA_PORT &= ~(1 << LCD_EN_PIN); _delay_us(1); LCD_DATA_PORT &= ~(1 << LCD_DB5); _delay_us(1); } void lcd_send(bool rs, uint8_t data) { LCD_DATA_DDR = 0xFF; LCD_DATA_PORT = 0x00; LCD_DATA_PORT |= (data >> 4) << 3; _delay_us(1); // If rs (actual text data), set RS pin high if(rs == true) LCD_DATA_PORT |= (1 << LCD_RS_PIN); // Pulse enable _delay_ms(2); LCD_DATA_PORT |= (1 << LCD_EN_PIN); _delay_us(1); LCD_DATA_PORT &= ~(1 << LCD_EN_PIN); //_delay_us(1); // Clear data pins LCD_DATA_PORT &= ~(0x0F << 3); // Mask the lower bits and shift accordingly LCD_DATA_PORT |= (data & 0x0F) << 3; _delay_us(1); // Pulse enable LCD_DATA_PORT |= (1 << LCD_EN_PIN); _delay_us(1); LCD_DATA_PORT &= ~(1 << LCD_EN_PIN); _delay_us(1); LCD_DATA_PORT &= ~(0x0F << 3); LCD_DATA_PORT &= ~(1 << LCD_RS_PIN); // RS Low } void lcd_init() { _delay_ms(100); lcd_4bit_init(); //lcd_send(1, 0b01111000); lcd_send(0, 0x01); // Clear screen lcd_send(0, 0x02); // Return home lcd_send(0, 0b00001100); // Display on, no cursor lcd_send(0, 0b00101000); } void lcd_clear() { lcd_send(0, 0x01); } void test_leds() { DDRB |= 0xFF; PORTB = (1 << LCD_DB4); _delay_us(1); PORTB = (1 << LCD_DB5); _delay_us(1); PORTB = (1 << LCD_DB6); _delay_us(1); PORTB = (1 << LCD_DB7); _delay_us(1); PORTB = (1 << LCD_EN_PIN); _delay_us(1); PORTB = (1 << LCD_RS_PIN); _delay_us(1); PORTB = 0x00; } void lcd_set_cursor(uint8_t row, uint8_t col) { uint8_t position = 0x80; if (row == 1) position += 0x40; position += col; lcd_send(0, position); } // Takes a string and splits it over two lines if needed. Max length is 32 characters. void lcd_write_string(const char* string) { uint8_t i = 0; while(string[i]) { if(i == 16) { lcd_set_cursor(1, 0); while(string[i] == ' ') i++; // Skip leading spaces on the new line } lcd_send(1, string[i]); i++; } } // Takes two separate strings and prints them on their corresponding row void lcd_write_strings(const char* top, const char* bottom) { uint8_t i = 0; while (top[i]) { lcd_send(1, top[i]); i++; } i = 0; lcd_set_cursor(1, 0); while(bottom[i]) { lcd_send(1, bottom[i]); i++; } }