// LCD Functions Developed by electroSome https://electrosome.com/interfacing-lcd-atmega32-microcontroller-atmel-studio/ // September 2nd, 2023, modified by Thierry LEQUEU // December 24, 2023, modified by Thierry LEQUEU #define eS_PORTA0 0 #define eS_PORTA1 1 #define eS_PORTA2 2 #define eS_PORTA3 3 #define eS_PORTA4 4 #define eS_PORTA5 5 #define eS_PORTA6 6 #define eS_PORTA7 7 #define eS_PORTB0 10 #define eS_PORTB1 11 #define eS_PORTB2 12 #define eS_PORTB3 13 #define eS_PORTB4 14 #define eS_PORTB5 15 #define eS_PORTB6 16 #define eS_PORTB7 17 #define eS_PORTC0 20 #define eS_PORTC1 21 #define eS_PORTC2 22 #define eS_PORTC3 23 #define eS_PORTC4 24 #define eS_PORTC5 25 #define eS_PORTC6 26 #define eS_PORTC7 27 #define eS_PORTD0 30 #define eS_PORTD1 31 #define eS_PORTD2 32 #define eS_PORTD3 33 #define eS_PORTD4 34 #define eS_PORTD5 35 #define eS_PORTD6 36 #define eS_PORTD7 37 #ifndef D0 #define D0 eS_PORTC0 #define D1 eS_PORTC1 #define D2 eS_PORTC2 #define D3 eS_PORTC3 #endif #include void pinChange(int a, int b) { if(b == 0) { if(a == eS_PORTA0) PORTA &= ~(1< RS = 0 Lcd8_Port(a); //Data transfer pinChange(EN,1); // => E = 1 _delay_ms(1); pinChange(EN,0); // => E = 0 _delay_ms(1); } void Lcd8_Clear() { Lcd8_Cmd(1); } void Lcd8_Set_Cursor(char a, char b) { if(a == 1) Lcd8_Cmd(0x80 + b); else if(a == 2) Lcd8_Cmd(0xC0 + b); } void Lcd8_Init() { pinChange(RW,0); pinChange(RS,0); pinChange(EN,0); _delay_ms(20); ///////////// Reset process from datasheet ///////// Lcd8_Cmd(0x30); _delay_ms(5); Lcd8_Cmd(0x30); _delay_ms(1); Lcd8_Cmd(0x30); _delay_ms(10); ///////////////////////////////////////////////////// Lcd8_Cmd(0x38); //function set Lcd8_Cmd(0x0C); //display on,cursor off,blink off Lcd8_Cmd(0x01); //clear display Lcd8_Cmd(0x06); //entry mode, set increment } void Lcd8_Write_Char(char a) { pinChange(RS,1); // => RS = 1 Lcd8_Port(a); //Data transfer pinChange(EN,1); // => E = 1 _delay_ms(1); pinChange(EN,0); // => E = 04 _delay_ms(1); } void Lcd8_Write_String(char *a) { int i; for(i=0;a[i]!='\0';i++) Lcd8_Write_Char(a[i]); } void Lcd8_Shift_Right() { Lcd8_Cmd(0x1C); } void Lcd8_Shift_Left() { Lcd8_Cmd(0x18); } // End of LCD 8 Bit Interfacing Functions ///////////////////////////////////////////////////// // Start of LCD 4 Bit Interfacing Functions // D4, D5, D6, D7 are defined in the main.c void Lcd4_Port(char a) { if(a & 1) pinChange(D4,1); else pinChange(D4,0); if(a & 2) pinChange(D5,1); else pinChange(D5,0); if(a & 4) pinChange(D6,1); else pinChange(D6,0); if(a & 8) pinChange(D7,1); else pinChange(D7,0); } void Lcd4_Cmd(char a) { pinChange(RS,0); // => RS = 0 Lcd4_Port(a); pinChange(EN,1); // => E = 1 _delay_ms(1); pinChange(EN,0); // => E = 0 _delay_ms(1); } void Lcd4_Clear() { Lcd4_Cmd(0); Lcd4_Cmd(1); // It clears the whole display and sets display data RAMs address 0 in address counter. } void Lcd4_Set_Cursor_OLD(char a, char b) { char temp,z,y; if(a == 1) { temp = 0x80 + b; z = temp>>4; y = (0x80+b) & 0x0F; Lcd4_Cmd(z); Lcd4_Cmd(y); } else if(a == 2) { temp = 0xC0 + b; z = temp>>4; y = (0xC0+b) & 0x0F; Lcd4_Cmd(z); Lcd4_Cmd(y); } } void Lcd4_Set_Cursor(char x, char y) // For an LCD display 4 lines et 16 characters !!!! OK on December 24, 2023. { char z; if(y == 0) { z = 0x80 + 0x00 + x; // The 1st line start at the address 0x00 = 00. // z = 0x08; //temp>>4; // y = cc & 0x0F; // Décalage possible de 0 à 15 only ! Lcd4_Cmd(z>>4); // The function Lcd4_Cmd only write the 4 least significant bits! Lcd4_Cmd(z & 0x0F); // so you have to write the Address Counter in 2 steps! } if(y == 1) { z = 0x80 + 0x40 + x; // The 1st line start at the address 0x40 = 64. See SPLC780D page 16. Lcd4_Cmd(z>>4); // Write the 4 most significant bits. Lcd4_Cmd(z & 0x0F); // Write the 4 least significant bits. } if(y == 2) { z = 0x80 + 0x10 + x; // The 3rd line starts at the end of the 1st line, i.e. at address 0x10 = 16! Lcd4_Cmd(z>>4); // Write the 4 most significant bits Lcd4_Cmd(z & 0x0F); // Write the 4 least significant bits. } if(y == 3) { z = 0x80 + 0x50 + x; // The 4th line starts at the end of the 2nd line, i.e. at address 0x40 - 0x10 = 80! Lcd4_Cmd(z>>4); // Write the 4 most significant bits Lcd4_Cmd(z & 0x0F); // Write the 4 least significant bits. } } void Lcd4_Init() { pinChange(RW,0); Lcd4_Port(0x00); _delay_ms(20); // Wait time > 15ms after VDD > 4.5V. ///////////// Reset process from datasheet ///////// Lcd4_Cmd(0x03); _delay_ms(5); // Wait time > 4.1ms Lcd4_Cmd(0x03); _delay_ms(11); // Wait time > 100us Lcd4_Cmd(0x03); ///////////////////////////////////////////////////// Lcd4_Cmd(0x02); Lcd4_Cmd(0x02); Lcd4_Cmd(0x08); Lcd4_Cmd(0x00); Lcd4_Cmd(0x0C); Lcd4_Cmd(0x00); Lcd4_Cmd(0x06); } void Lcd4_Write_Char(char a) { char temp,y; temp = a & 0x0F; y = a & 0xF0; pinChange(RS,1); // => RS = 1 Lcd4_Port(y>>4); // Data transfer pinChange(EN,1); _delay_ms(1); pinChange(EN,0); _delay_ms(1); Lcd4_Port(temp); pinChange(EN,1); _delay_ms(1); pinChange(EN,0); _delay_ms(1); } void Lcd4_Write_String(char *a) { int i; for(i=0;a[i]!='\0';i++) Lcd4_Write_Char(a[i]); } void Lcd4_Shift_Right() { Lcd4_Cmd(0x01); Lcd4_Cmd(0x0C); } void Lcd4_Shift_Left() { Lcd4_Cmd(0x01); Lcd4_Cmd(0x08); } // End of LCD 4 Bit Interfacing Functions