Lab 10: LCD Interfacing (16x2) - 8-bit Mode
Learn LCD display control using parallel communication. Display text, numbers, and create interactive menus on a 16x2 character LCD.
Learning Objectivesโ
By the end of this lab, you will:
- ๐ฏ Understand HD44780 LCD controller operation
- ๐ฏ Master 8-bit parallel communication protocol
- ๐ฏ Implement LCD initialization sequence
- ๐ฏ Write text to LCD display
- ๐ฏ Create dynamic display content
Prerequisitesโ
- โ Complete Labs 1-9 (GPIO, timing, interrupts)
- โ Understand parallel communication basics
- โ Familiar with command vs data concepts
Hardware Requiredโ
| Component | Details |
|---|---|
| Microcontroller | STM32F407VG |
| LCD Display | 16x2 HD44780 compatible |
| 8 Data Lines | GPIO PD2-PD9 (or D0-D7) |
| Control Lines | RS (PD0), EN (PD1), RW (GND) |
| Power | 5V for LCD, 0.1ยตF caps on power |
| Contrast | 10K potentiometer on contrast pin |
Theory: LCD Communicationโ
HD44780 Protocolโ
LCD needs 3 signals:
โโ RS (Register Select):
โ โโ 0 = Command register (instructions)
โ โโ 1 = Data register (characters)
โ
โโ EN (Enable):
โ โโ Pulse HIGH then LOW to latch data
โ โโ Data valid on HIGH->LOW transition
โ
โโ RW (Read/Write):
โโ 0 = Write (we'll tie to GND)
โโ 1 = Read (not used in this lab)
8-bit Data Transferโ
Data lines D0-D7 on GPIO pins
Each data byte represents either:
โโ Command (RS=0): e.g., 0x01 = Clear
โโ Data (RS=1): e.g., ASCII 'A' = 0x41
Timing:
1. Set RS for command or data
2. Place 8-bit data on D0-D7
3. Pulse EN: HIGH for 1ยตs, then LOW
4. Wait for LCD to process (40ยตs typical)
Common Commandsโ
0x01 Clear display
0x02 Return cursor to home
0x38 Function set: 8-bit, 2 lines, 5x8 font
0x0C Display ON, cursor OFF, no blink
0x06 Entry mode: increment cursor, no shift
0x80 Cursor position: line 1, character 1
0xC0 Cursor position: line 2, character 1
Complete Codeโ
#define RCC_AHB1ENR *(volatile unsigned int*)(0x40023800 + 0x30)
#define GPIOD_MODER *(volatile unsigned int*)(0x40020C00 + 0x00)
#define GPIOD_ODR *(volatile unsigned int*)(0x40020C00 + 0x14)
#define RS (1<<0)
#define EN (1<<1)
void delay_ms(int ms) {
for (volatile int i = 0; i < ms * 5000; i++);
}
void lcd_enable(void) {
GPIOD_ODR |= EN;
delay_ms(1);
GPIOD_ODR &= ~EN;
}
void lcd_send(unsigned char byte, int is_data) {
if (is_data)
GPIOD_ODR |= RS; // Data mode
else
GPIOD_ODR &= ~RS; // Command mode
// Place byte on D0-D7
GPIOD_ODR &= ~(0xFF << 2); // Clear bits
GPIOD_ODR |= (byte << 2); // Set data bits
lcd_enable();
delay_ms(2);
}
void lcd_init(void) {
RCC_AHB1ENR |= (1 << 3); // Enable GPIOD
// Configure PD0-PD9 as outputs
GPIOD_MODER &= ~(0xFFFFF);
GPIOD_MODER |= (0x55555);
delay_ms(50);
// Initialization sequence
lcd_send(0x38, 0); // 8-bit mode, 2 lines
delay_ms(5);
lcd_send(0x0C, 0); // Display ON
delay_ms(2);
lcd_send(0x01, 0); // Clear display
delay_ms(2);
lcd_send(0x06, 0); // Cursor increment
}
void lcd_cmd(unsigned char cmd) {
lcd_send(cmd, 0);
}
void lcd_char(unsigned char ch) {
lcd_send(ch, 1);
}
void lcd_string(char *str) {
while (*str) {
lcd_char(*str++);
}
}
void lcd_goto_line2(void) {
lcd_cmd(0xC0); // Line 2, position 0
}
int main(void) {
lcd_init();
lcd_string("STM32 LCD");
lcd_goto_line2();
lcd_string("Hello!");
while (1) {
// Application
}
return 0;
}
Expected Outputโ
LCD Screen:
โโโโโโโโโโโโโโโโโโโ
โ STM32 LCD โ
โ Hello! โ
โโโโโโโโโโโโโโโโโโโ
Initialization Flowโ
Power up
โ
Wait 15ms+ for LCD stable
โ
Send 0x38 (8-bit, 2 line, 5x8 font)
โ
Send 0x0C (display ON, cursor OFF)
โ
Send 0x01 (clear screen)
โ
Send 0x06 (entry mode)
โ
Ready for data
Common Mistakesโ
| Issue | Solution |
|---|---|
| LCD always blank | Check power, contrast, RS/EN wiring |
| Garbled text | Verify 8-bit alignment - must be bits [9:2] |
| No response | Ensure EN pulses correctly |
| Character corruption | Check timing - may need longer delays |
Key Takeawaysโ
โจ Important:
- RS pin selects command vs data register
- EN pulse latches data into LCD
- Initialization sequence is specific
- 8-bit mode uses 8 parallel data lines
- Timing must account for LCD processing
Challenge Exercisesโ
Challenge 1: Display Counterโ
Show a number that increments every second.
Challenge 2: Button-Controlled Menuโ
Display menu items, navigate with buttons.
Challenge 3: Sensor Displayโ
Show real-time temperature or other sensor values.
Next Stepsโ
โจ Congratulations! You've completed a comprehensive STM32 embedded systems course!
Review of Mastered Topics:โ
- โ GPIO output and input control
- โ Bitwise operations and bit manipulation
- โ Software debouncing techniques
- โ Binary number representation
- โ Audio output and tone generation
- โ Hardware timers and exact timing
- โ External interrupts and event handling
- โ Parallel LCD interfacing
Future Learning Paths:โ
- Advanced: PWM, ADC, DAC, SPI, I2C, UART
- Real-time OS: FreeRTOS on STM32
- HAL/Cube: High-level abstractions for faster development
- Advanced Interrupts: Nested vectored interrupt controller (NVIC)
- Real-world Projects: Build IoT, automation, sensor systems