// Define the pin mappings for LCD
#define RS_PIN 9 // Register Select (RS) connected to A9
#define E_PIN 8 // Enable (E) connected to A8
// Helper macros to control pins manually
#define RS_HIGH() (PORTK |= (1 << RS_PIN - 8)) // Set A9 high (RS pin) on PORTK
#define RS_LOW() (PORTK &= ~(1 << RS_PIN - 8)) // Set A9 low (RS pin) on PORTK
#define E_HIGH() (PORTK |= (1 << E_PIN - 8)) // Set A8 high (E pin) on PORTK
#define E_LOW() (PORTK &= ~(1 << E_PIN - 8)) // Set A8 low (E pin) on PORTK
// Function prototypes
void lcdCommand(uint8_t cmd);
void lcdData(uint8_t data);
void lcdInit();
void lcdClear();
void lcdPulseEnable();
void lcdPrint(const char *str);
void setup() {
// Set the data direction for PORTF (A0-A7) to output
DDRF = 0xFF; // Set all A0-A7 (PORTF) as output for LCD data lines
// Set the data direction for PORTK (A8 and A9) to output
DDRK |= (1 << RS_PIN - 8) | (1 << E_PIN - 8); // Set A8 and A9 (PORTK) as output for RS and E
// 1 << 9-8 |
// Initialize the LCD
lcdInit();
lcdClear();
// Send some data to display
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 loop() {
// Nothing in loop
}
// Function to initialize the LCD in 8-bit mode
void lcdInit() {
lcdCommand(0x38); // 8-bit mode, 2-line display, 5x8 font
lcdCommand(0x0C); // Display on, cursor off
lcdCommand(0x06); // Increment cursor
lcdCommand(0x01); // Clear display
delay(5); // Wait for display to clear
}
// Function to clear the LCD
void lcdClear() {
lcdCommand(0x01); // Clear display command
delay(5); // Wait for the command to complete
}
// Function to send a command to the LCD
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
}
// Function to send data to the LCD (characters)
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
}
// Function to print a string on the LCD
void lcdPrint(const char *str) {
while (*str) {
lcdData(*str); // Send each character
str++; // Move to the next character
}
}