//----------------------------------------------------------------------------------------- // FUNCTION: lcd_write // PURPOSE: send a character or an instruction to the LCD void lcd_write(uint8_t data, uint8_t rs) { _delay_us(1000); //check write type if (rs) lcd_rs_high(); //write data else lcd_rs_low(); //write instruciton // configure data pins as output LCD_DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN); LCD_DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN); LCD_DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN); LCD_DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN); // output high nibble first LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN); LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN); LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN); LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); if(data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN); if(data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN); if(data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); if(data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); lcd_toggle_e(); // output low nibble LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN); LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN); LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN); LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); if(data & 0x08) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN); if(data & 0x04) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN); if(data & 0x02) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); if(data & 0x01) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); lcd_toggle_e(); // all data pins high (inactive) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN); LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN); }
// PURPOSE: send a character or an instruction to the LCD void HD44780::lcd_write(uint8_t data,uint8_t rs) { // we cannot check LCD status (no read available) , so we will assume a default delay to wait for lcd to be ready fcpu_delay_us(500); //check write type if (rs) lcd_rs_high(); //write data else lcd_rs_low(); //write instruciton // configure data pins as output LCD_DDR(LCD_4BIT_D4_PORT) |= _BV(LCD_4BIT_D4_PIN); LCD_DDR(LCD_4BIT_D5_PORT) |= _BV(LCD_4BIT_D5_PIN); LCD_DDR(LCD_4BIT_D6_PORT) |= _BV(LCD_4BIT_D6_PIN); LCD_DDR(LCD_4BIT_D7_PORT) |= _BV(LCD_4BIT_D7_PIN); // output high nibble first LCD_4BIT_D7_PORT &= ~_BV(LCD_4BIT_D7_PIN); LCD_4BIT_D6_PORT &= ~_BV(LCD_4BIT_D6_PIN); LCD_4BIT_D5_PORT &= ~_BV(LCD_4BIT_D5_PIN); LCD_4BIT_D4_PORT &= ~_BV(LCD_4BIT_D4_PIN); if(data & 0x80) LCD_4BIT_D7_PORT |= _BV(LCD_4BIT_D7_PIN); if(data & 0x40) LCD_4BIT_D6_PORT |= _BV(LCD_4BIT_D6_PIN); if(data & 0x20) LCD_4BIT_D5_PORT |= _BV(LCD_4BIT_D5_PIN); if(data & 0x10) LCD_4BIT_D4_PORT |= _BV(LCD_4BIT_D4_PIN); lcd_toggle_e(); // output low nibble LCD_4BIT_D7_PORT &= ~_BV(LCD_4BIT_D7_PIN); LCD_4BIT_D6_PORT &= ~_BV(LCD_4BIT_D6_PIN); LCD_4BIT_D5_PORT &= ~_BV(LCD_4BIT_D5_PIN); LCD_4BIT_D4_PORT &= ~_BV(LCD_4BIT_D4_PIN); if(data & 0x08) LCD_4BIT_D7_PORT |= _BV(LCD_4BIT_D7_PIN); if(data & 0x04) LCD_4BIT_D6_PORT |= _BV(LCD_4BIT_D6_PIN); if(data & 0x02) LCD_4BIT_D5_PORT |= _BV(LCD_4BIT_D5_PIN); if(data & 0x01) LCD_4BIT_D4_PORT |= _BV(LCD_4BIT_D4_PIN); lcd_toggle_e(); // all data pins high (inactive) LCD_4BIT_D4_PORT |= _BV(LCD_4BIT_D4_PIN); LCD_4BIT_D5_PORT |= _BV(LCD_4BIT_D5_PIN); LCD_4BIT_D6_PORT |= _BV(LCD_4BIT_D6_PIN); LCD_4BIT_D7_PORT |= _BV(LCD_4BIT_D7_PIN); }
// PURPOSE: Initialize LCD to 4 bit I/O mode void HD44780::lcd_init() { // configure all port bits as output (LCD data and control lines on different ports LCD_DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN); LCD_DDR(LCD_E_PORT) |= _BV(LCD_E_PIN); LCD_DDR(LCD_4BIT_D4_PORT) |= _BV(LCD_4BIT_D4_PIN); LCD_DDR(LCD_4BIT_D5_PORT) |= _BV(LCD_4BIT_D5_PIN); LCD_DDR(LCD_4BIT_D6_PORT) |= _BV(LCD_4BIT_D6_PIN); LCD_DDR(LCD_4BIT_D7_PORT) |= _BV(LCD_4BIT_D7_PIN); // wait 25ms or more after power-on fcpu_delay_us(25000); // initial write to lcd is 8bit LCD_4BIT_D5_PORT |= _BV(LCD_4BIT_D5_PIN); // _BV(LCD_FUNCTION)>>4; LCD_4BIT_D4_PORT |= _BV(LCD_4BIT_D4_PIN); // _BV(LCD_FUNCTION_8BIT)>>4; lcd_toggle_e(); fcpu_delay_us(2000); //2000 // delay, busy flag can't be checked here // repeat last command lcd_toggle_e(); fcpu_delay_us(64); //64 // delay, busy flag can't be checked here // now configure for 4bit mode LCD_4BIT_D4_PORT &= ~_BV(LCD_4BIT_D4_PIN); // LCD_FUNCTION_4BIT_1LINE>>4 lcd_toggle_e(); fcpu_delay_us(2000); // some displays need this additional delay // set 4 bit IO lcd_instr(LCD_FUNCTION_4BIT_2LINES); // 4-bit interface, dual line, 5x7 dots lcd_toggle_e(); fcpu_delay_us(2000); // some displays need this additional delay lcd_instr(LCD_ENTRY_INC_);//cursor move right, no shift display lcd_toggle_e(); fcpu_delay_us(2500); // some displays need this additional delay lcd_instr(LCD_DISP_ON);// display on, cursor off, blink char off lcd_toggle_e(); fcpu_delay_us(2500); // some displays need this additional delay lcd_home();//set cursor to home and clear the cursor }