uint8_t lcd_read(uint8_t rs) { __IO uint8_t data; if(rs) { //read data lcd_rs_high(); } else { //read busy flag lcd_rs_low(); } lcd_rw_high(); // read mode //set data pins to input GPIO_InitStructure.GPIO_Pin = DATA_PORT_Pin_0 | DATA_PORT_Pin_1 | DATA_PORT_Pin_2 | DATA_PORT_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_Init(LCD_PORT, &GPIO_InitStructure); //read 2 nibbles lcd_e_high(); //enable lcd_e_delay(); data = (uint8_t)GPIO_ReadInputData(LCD_PORT) << 4; lcd_e_low(); //disable lcd_e_delay(); lcd_e_high(); //enable lcd_e_delay(); data |= (uint8_t)GPIO_ReadInputData(LCD_PORT) & 0x0F; lcd_e_low(); //disable return data; }
/** * Writes a raw instruction to the LCD. * @param command The 4-bit instruction code. * @param data The 8-bit paramater/data to the specified instruction. */ void lcd_write_command(unsigned char command, unsigned char data) { /* Wait for the busy flag to clear */ lcd_wait_busy(); /* Set Enable low, RW low, RS high to write the instruction command */ lcd_enable_low(); lcd_rw_low(); lcd_rs_high(); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); /* Instruction commands are a maximum of 4 bits long, so * just mask off the rest. */ LCD_DATA_PORT = (command&0x0F); lcd_enable_high(); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); /* Set RW low, RW low to write the instruction data */ lcd_rw_low(); lcd_rs_low(); LCD_DATA_PORT = data; __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); lcd_strobe_enable(); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); __asm("nop;"); }
//----------------------------------------------------------------------------------------- // 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); }
void lcd_write(uint8_t data, uint8_t rs) { __IO uint8_t outputdata; if(rs) { //write data lcd_rs_high(); } else { //write instruction lcd_rs_low(); } lcd_rw_low(); //set to write //set data pins to output GPIO_InitStructure.GPIO_Pin = DATA_PORT_Pin_0 | DATA_PORT_Pin_1 | DATA_PORT_Pin_2 | DATA_PORT_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(LCD_PORT, &GPIO_InitStructure); /** * Preserve the RS,RW,E bits in order to write out: * our data goe son the 4 most significant bits with * the high nibble output first. */ outputdata = (uint8_t)GPIO_ReadOutputData(LCD_PORT); outputdata &= 0x05; //we're only interested in the lower bits (RS,RW,E) //output high nibble first GPIO_Write(LCD_PORT, outputdata | (data & 0xF0)); //push data lcd_e_toggle(); GPIO_Write(LCD_PORT, outputdata | ((data << 4) & 0xF0)); //push data lcd_e_toggle(); GPIO_Write(LCD_PORT, outputdata | 0xF0); //set pins high as inactive state }