Interfacing an LCD display in parallel mode with a Cortex M0+ microcontroller provides a simple and efficient way to drive the LCD while minimizing utilization of the microcontroller’s limited I/O pins. The Cortex M0+ parallel interface uses 8 data pins and 3 control pins to send characters and commands to the LCD display.
Overview of Parallel LCD Interfacing
In parallel mode, the LCD expects an 8-bit data bus and 3 control signals – Enable, Read/Write, and Register Select. The 8-bit data bus allows the microcontroller to send a full 8-bit ASCII character or LCD command code to the display in one write operation. The Enable pin is pulsed high after each data byte is ready on the bus, causing the LCD controller to latch the data. The R/W pin selects the transfer direction, while the RS pin chooses between the data register and instruction register inside the LCD controller.
The Cortex M0+ GPIO peripheral is well suited for implementing the parallel interface. With up to 32 I/O pins, there are enough pins to devote 8 pins for the data bus and 3 control pins while leaving additional pins for other functions. The GPIO peripheral includes various modes useful for interfacing like setting pins as digital outputs, configuring drive strength, and writing to groups of I/O pins simultaneously.
Interfacing Hardware
A typical LCD will have a 16-pin male header with pins for the 8 data lines (DB7-DB0), 3 control lines (E, R/W, RS), and 5V & Ground power pins. The Cortex M0+ development board or target system should have a female 16-pin header or female-male jumper wires to connect to the LCD. Ensure the voltage levels match between the MCU and LCD.
The pins should be connected as follows:
- LCD DB7 – DB0 pins to MCU GPIO pins
- LCD E pin to MCU GPIO pin
- LCD R/W pin to MCU GPIO pin
- LCD RS pin to MCU GPIO pin
- LCD VSS pin to MCU GND
- LCD VDD pin to +5V from MCU or external
The 8 data pins can use any available GPIO pins on the M0+, as long as sufficient pins are available. Using consecutive GPIO pins makes the software implementation easier. The control pins should be on GPIO pins that can trigger interrupts, which is useful for timed LCD operations.
Software Libraries and Driver Code
The MCU needs C code to interface with the LCD controller. This involves initializing the LCD, writing data and commands, controlling the timing of LCD operations, and optimizing writes for performance. The LCD vendor will often provide a driver library with functions to initialize the LCD, move the cursor, write characters/strings, clear the screen, etc. These libraries are helpful for rapid development.
For a custom driver, the initialization sequence will configure the GPIO pins, send reset commands to the LCD controller, and initialize any desired modes. Sending data bytes requires pulsing the Enable pin after setting the data pins and R/W & RS control levels. The timing of the Enable pulse width and delay between transfers is critical.
Key functions needed in the driver include:
- LCD initialization – configures 8 data pins as outputs, configures R/W, RS, E as outputs, resets LCD controller, sets any modes
- Write byte – writes 8-bit data value to data pins, sets R/W low for write, sets RS for data/instruction, strobes Enable pin
- Write command – calls write byte with RS low for instructions
- Write data – calls write byte with RS high for data
- Set cursor – uses instruction codes to move cursor
- Clear display – clears LCD and moves cursor home
For better performance, the GPIO peripheral on the Cortex M0+ supports atomic bit band access. This allows the driver to set or clear individual data pins in the 8-bit port without the read-modify-write cycle typically needed. Bit band accesses are single cycle and avoid contention when setting the data byte.
Example Code
Here is example code to initialize the LCD and write a character using bit band access in C: // LCD pins connected to GPIO Port 0 #define LCD_DATA_PORT 0 // LCD control pins on GPIO0 #define LCD_E_PIN 0 #define LCD_RW_PIN 1 #define LCD_RS_PIN 2 void lcd_init() { // Configure GPIO pins GPIO0->MODER |= 0xFF << (LCD_DATA_PORT * 2); // Data pins as output GPIO0->MODER |= (1 << LCD_E_PIN * 2); // E pin as output GPIO0->MODER |= (1 << LCD_RW_PIN * 2); // R/W pin as output GPIO0->MODER |= (1 << LCD_RS_PIN * 2); // RS pin as output // Initialization sequence lcd_write_command(0x38); // 2 line, 5×8 font lcd_write_command(0x01); // Clear screen lcd_write_command(0x0F); // Turn on display, cursor blinking } void lcd_write_byte(char byte) { GPIO0->BSRR = 0xFF << LCD_DATA_PORT; // Clear data pins if(byte & 0x01) { *((volatile uint32_t *)(GPIO0_BASE + (1 << LCD_DATA_PORT)) = 1; // DB0 = 1 } // Set other bits GPIO0->BRR = 1 << LCD_RW_PIN; // R/W low for write GPIO0->BRR = 1 << LCD_RS_PIN; // Instruction register GPIO0->BSRR = 1 << LCD_E_PIN; // Enable pulse DelayMicroseconds(1); GPIO0->BRR = 1 << LCD_E_PIN; } void lcd_write_command(char cmd) { lcd_write_byte(cmd); } void lcd_write_char(char data) { GPIO0->BSRR = 1 << LCD_RS_PIN; // Data register lcd_write_byte(data); } int main() { lcd_init(); lcd_write_char(‘X’); // Write ‘X’ character }
Optimization and Performance
Several techniques can optimize the LCD interface on Cortex M0+ for better performance:
- Use DMA transfers to offload writing multiple characters/strings from CPU
- Configure GPIO for very fast output speeds if LCD supports it
- Use interrupts or timers for automatic refreshing the LCD
- Create custom character patterns for frequently used symbols
- Buffer data before writing to reduce individual write operations
- Accelerate performance-critical operations with bit band accesses
Writing single bytes sequentially is slow, so bulk writes allow the Cortex M0+ to optimize instruction execution. DMA improves throughput by writing bytes continuously without CPU overhead. Some tradeoffs around using DMA include increased memory usage and complexity in the driver code.
Common Issues
Some common issues encountered when interfacing a parallel LCD with Cortex M0+ include:
- Incorrect or loose display connections
- Voltage level mismatches
- Timing violations on the Enable and R/W signals
- Invalid LCD initialization instruction sequences
- Incorrect RS and R/W states when writing data/commands
- Issuing commands when previous command is still in progress
- Not waiting sufficient time between initialization sequence steps
- Faulty LCD display
To debug issues, verify all connections, the voltage levels, timing of the interface signals using an oscilloscope or logic analyzer, and proper initialization. Start with the simplest write operations like clearing the display to isolate bugs.
Conclusion
Interfacing a parallel LCD display with the Cortex M0+ microcontroller provides a basic human interface for embedded applications. The parallel interface only uses 11 GPIO pins while leveraging the M0+ optimized GPIO peripheral for performance. Careful configuration of the LCD driver, proper interface signal timing, and techniques like DMA and buffered writes allow practical user interfaces to be built.