/* * Author: Jake Goodwin * Date: 2022 * Description: Interfacing with a 1602LCD only with the uc no perifs */ #include #include #include #include #define RS_PORT PORTD #define RS_PIN PIND0 #define RS_DDR DDD0 //#define RW_PORT PORTD //#define RW_PIN PIND1 //#define RW_DDR DDD1 #define ENA_PORT PORTD #define ENA_PIN PIND1 #define ENA_DDR DDD1 #define BIT4_PORT PORTD #define BIT4_PIN PIND4 #define BIT4_DDR DDD4 #define BIT5_PORT PORTD #define BIT5_PIN PIND5 #define BIT5_DDR DDD5 #define BIT6_PORT PORTD #define BIT6_PIN PIND6 #define BIT6_DDR DDD6 #define BIT7_PORT PORTD #define BIT7_PIN PIND7 #define BIT7_DDR DDD7 #define LED_PIN PINC0 #define LED_PORT PORTC #define LED_DDR DDC0 //LCD CONNECTIONS: /* * VSS --> GND * VDD --> VCC * V0 --> POT --> GND * RS --> PD0(AVR) * RW --> GND * E --> PD1(AVR) * D4 --> PD4(AVR) * D5 --> PD5(AVR) * D6 --> PD6(AVR) * D7 --> PD7(AVR) * * PURPOSE: * RS: register select, * RW: Read/Write select signal, * E: Operation(data read/write) enable signal. * DB0~DB3: not used for 4bit operations. * DB4~DB7: high order three-state data lines. */ //############################# //MACROS //############################# //already defined //#define _BV(bit) (1 << bit) #define setbit(port, bit) (port) |= (1 << (bit)) #define clearbit(port, bit) (port) &= ~(1 << (bit)) //############################# //FUNCTION PROTOTYPES //############################# void init_lcd(void); void cmd_lcd(uint8_t cmd); void cmd_nibble_lcd(uint8_t cmd); void clear_lcd(void); static void led_blink(void); void set_lcd_one_line_(void); void set_lcd_two_line(void); void return_home_lcd(void); void turn_off_lcd(void); void turn_on_lcd(void); void set_cgram_lcd_address(uint8_t addr); void set_ddram_lcd_address(uint8_t addr); void write_lcd_address(uint8_t addr); void set_entry_mode_increment_lcd(void); void set_entry_mode_decrement_lcd(void); void shift_right_lcd(void); void shift_left_lcd(void); void bbs(void); void clear_buf_lcd(); int main() { PORTD = 0x00; DDRD = 0xff; //SETUP HERE. led_blink(); led_blink(); init_lcd(); _delay_ms(500); return_home_lcd(); while(1) { led_blink(); _delay_ms(1000); set_entry_mode_increment_lcd(); for(uint8_t i = 0; i < 15; i++) { //shift_right_lcd(); write_lcd_address(0x7e); _delay_ms(100); } set_entry_mode_decrement_lcd(); for(uint8_t i = 0; i < 15; i++) { //shift_left_lcd(); write_lcd_address(0x7f); _delay_ms(100); } //set_cgram_lcd_address(0x00); //set_entry_mode_increment_lcd(); //bbs(); _delay_ms(1000); clear_lcd(); PORTD = 0x00; led_blink(); led_blink(); led_blink(); _delay_ms(1000); _delay_ms(1000); _delay_ms(1000); _delay_ms(1000); _delay_ms(1000); } return 0; } //############################# //FUNCTIONS //############################# void bbs(void) { _delay_ms(500); write_lcd_address(0x42); write_lcd_address(0x4f); write_lcd_address(0x4f); write_lcd_address(0x42); write_lcd_address(0x49); write_lcd_address(0x45); write_lcd_address(0x53); } /* * Input: none * Output: none * Description: setsup the lcd for two line display and sets start posistion. */ void init_lcd(void) { _delay_ms(500); clear_buf_lcd(); clear_buf_lcd(); _delay_ms(10); turn_on_lcd(); _delay_ms(10); set_lcd_two_line(); _delay_ms(10); //clear_lcd(); _delay_ms(5); //return_home_lcd(); _delay_ms(5); } /* * Input: None * Outupt: None * Description: Sets the LCD into 4bit two line display mode. */ void set_lcd_two_line(void) { cmd_lcd(0x28); } /* * Input: None * Outupt: None * Description: Sets the LCD into 4bit one line display mode. */ void set_lcd_one_line(void) { cmd_lcd(0x20); } /* * Input: None * Outupt: None * Description: Sends the clear screen command to the LCD */ void clear_lcd(void) { cmd_lcd(0x01); } /* * Input: None * Outupt: None * Description: Returns the LCD cursor to home position. */ void return_home_lcd(void) { cmd_lcd(0x02); } /* * Input: None * Output: None * Description: Shifts cusor to the right one char. */ void shift_right_lcd(void) { cmd_lcd(0x14); } /* * Input: None * Output: None * Description: Shifts cusor to the left one char. */ void shift_left_lcd(void) { cmd_lcd(0x10); } /* * Input: None * Outupt: None * Description: Toggles the LCD power state. */ void turn_off_lcd(void) { cmd_lcd(0x08); } /* * Input: None * Outupt: None * Description: Toggles the LCD power state. */ void turn_on_lcd(void) { cmd_lcd(0x0f); } /* * Input: None * Outupt: None * Description: */ void set_cgram_lcd_address(uint8_t addr) { uint8_t cmd = 0x40; cmd |= addr; cmd_lcd(cmd); } /* * Input: None * Outupt: None * Description: */ void set_ddram_lcd_address(uint8_t addr) { uint8_t cmd = 0x80; cmd |= addr; cmd_lcd(cmd); } /* * Input: None * Outupt: None * Description: */ void write_lcd_address(uint8_t addr) { setbit(PORTD, RS_PIN); cmd_lcd(addr); clearbit(PORTD, RS_PIN); _delay_ms(10); } void set_entry_mode_increment_lcd(void) { cmd_lcd(0x06); } void set_entry_mode_decrement_lcd(void) { cmd_lcd(0x04); } void clear_buf_lcd() { DDRD = 0xff; PORTD &=0x0f; setbit(PORTD, ENA_PIN); _delay_ms(5); clearbit(PORTD, ENA_PIN); _delay_ms(2); setbit(PORTD, ENA_PIN); _delay_ms(5); clearbit(PORTD, ENA_PIN); } /* * Input: uint8_t, a 8bit command code. * Output: none * Description: Takes a 8bit command code and sends it as two 4bit nibbles * to the 1602LCD. The timing of delays is very important to match the * datasheets timing diagrams. */ void cmd_lcd(uint8_t cmd) { DDRD = 0xff; PORTD &=0x0f; //Send first nibble setbit(PORTD, ENA_PIN); PORTD |= (cmd & 0xf0); _delay_ms(1); clearbit(PORTD, ENA_PIN); _delay_ms(3); //Send the second nibble and shift cmd by four. PORTD &= 0x0f; setbit(PORTD, ENA_PIN); PORTD |= (cmd<<4); _delay_ms(1); clearbit(PORTD, ENA_PIN); _delay_ms(3); } /* * Input: None * Output: None * Description: Toggles the pin for the LED indicator. */ static void led_blink(void) { //Set the DDR for output. DDRC |= (1<