// Define the pin mappings for LCD
#define RS_PIN 10 // Register Select (RS) connected to A9
#define E_PIN 15 // Enable (E) connected to A8
// Helper macros to control pins manually
#define RS_HIGH() (PORTK |= (1 << RS_PIN - 8)) // Set A10 high (RS pin) on PORTK
#define RS_LOW() (PORTK &= ~(1 << RS_PIN - 8)) // Set A10 low (RS pin) on PORTK
#define E_HIGH() (PORTK |= (1 << E_PIN - 8)) // Set A15 high (E pin) on PORTK
#define E_LOW() (PORTK &= ~(1 << E_PIN - 8))
void lcdCommand(uint8_t cmd);
void lcdData(uint8_t data);
void lcdInit();
void lcdClear();
void lcdPulseEnable();
void lcdPrint(const char *str);
void setup() {
// put your setup code here, to run once:
DDRF = 0xFF;
DDRK |= (1 << RS_PIN - 8) | (1 << E_PIN - 8);
lcdInit();
lcdClear();
lcdCommand(0x80); // Set cursor to the beginning of the first line (0x80)
lcdPrint("Hello,");
//lcdCommand(0xC0 ); // Set cursor to the second line (0xC0)
lcdPrint("How are you");
}
void lcdInit() {
delay(15); // Wait for more than 15 ms after VCC rises to 4.5V
lcdCommand(0x30); // Function set: 8-bit interface
delay(5); // Wait for more than 4.1 ms
lcdCommand(0x30); // Repeat function set
delayMicroseconds(100); // Wait for more than 100 µs
lcdCommand(0x30); // Repeat function set
lcdCommand(0x38); // Function set: 8-bit interface, 2 lines, 5x8 dots
lcdCommand(0x0C); // Display ON, Cursor OFF, Blink OFF
lcdCommand(0x06); // Entry mode set: increment cursor, no shift
lcdCommand(0x01); // Clear display
delay(5); // Wait for display to clear
}
void lcdClear() {
lcdCommand(0x01); // Clear display command
delay(5); // Wait for the command to complete
}
void lcdCommand(uint8_t cmd) {
RS_LOW(); // Set RS low for command mode
PORTF = cmd; // Put the command on the data bus (PORTF for A0-A7)
lcdPulseEnable(); // Send the enable pulse
delay(2); // Wait for the command to complete
}
void lcdData(uint8_t data) {
RS_HIGH(); // Set RS high for data mode
PORTF = data; // Put the data on the data bus (PORTF for A0-A7)
lcdPulseEnable(); // Send the enable pulse
delay(2); // Wait for the data to be written
}
// Function to send a pulse on the enable line to latch data/command
void lcdPulseEnable() {
E_HIGH(); // Set enable high
delayMicroseconds(1); // Short delay
E_LOW(); // Set enable low
delayMicroseconds(100); // Wait for LCD to process
}
void lcdPrint(const char *str) {
while (*str) {
lcdData(*str); // Send each character
str++; // Move to the next character
}
}
void loop() {
// put your main code here, to run repeatedly:
}