The LPC845 is an ARM Cortex M0+ based microcontroller from NXP Semiconductors. It is an extremely low cost and low power microcontroller that is well suited for a wide range of embedded applications. The Cortex M0+ architecture provides good performance while maintaining low power consumption, making it ideal for battery powered and energy sensitive devices.
Interfacing a liquid crystal display (LCD) is a common task in embedded projects using microcontrollers like the LPC845. LCDs allow displaying textual information, data, graphics etc. and provide a simple user interface. The LPC845 microcontroller provides several options for connecting and interfacing with LCDs.
LCD Interface Options
Some of the common interface options for connecting LCDs to the LPC845 microcontroller are:
- Parallel interface
- 4-bit mode parallel interface
- SPI interface
- I2C interface
Parallel Interface
In parallel interface, the LCD is connected to the microcontroller using multiple GPIO pins – one pin for each data line. An 8-bit LCD will need 9 pins (8 data lines + 1 RS pin). The parallel interface provides fast transfer of data to the LCD.
The disadvantage is it consumes lot of GPIO pins on the microcontroller. The LPC845 has upto 26 GPIO pins, so an 8-bit parallel interface would take a big chunk of the available GPIO pins.
4-bit Mode Parallel Interface
In 4-bit mode, only the upper 4 bits of each byte are transferred per transaction. This reduces the number of pins needed between the LPC845 and LCD to just 7 pins. Data transfer speed is reduced compared to full 8-bit mode.
4-bit mode provides a good balance between pin usage and performance for most applications. It frees up GPIO pins for other uses.
SPI Interface
The LPC845 microcontroller has an SPI peripheral interface. The LCD can be connected to the SPI port using just 4 pins – MOSI, MISO, SCLK and a D/C control line. SPI provides high speed serial transfer of data over short distances.
SPI interface minimizes use of GPIOs while providing good performance. However, it requires additional logic/driver components to adapt the SPI signals to LCD interface. The LCD controller needs to support SPI.
I2C Interface
I2C requires only 2 wires (SDA, SCL) to connect the LCD. I2C can support multiple devices on the same bus. Speed is slower compared to parallel/SPI interfaces.
I2C minimizes pin use, but needs additional components to adapt signals. The LCD must have an I2C interface built in or connected externally via port expanders.
Interfacing 4-bit Mode LCD
The most commonly used option is interfacing a 4-bit LCD in 4-bit mode. This provides a good balance of performance and pin utilization. Following are the typical steps to interface a 4-bit LCD with the LPC845 microcontroller:
- Configure LCD pins as digital outputs on the LPC845
- Generate timing delays using timers or delay routines
- Initialize LCD in 4-bit mode
- Send LCD commands to configure display
- Write data and strings to the LCD
1. Configure LCD Pins
A 7-pin interface will be used with the LCD for the 4 data lines (DB7-DB4), RS, R/W and EN signals. These 7 GPIO pins need to be configured as digital outputs: // Configure LCD pins PINSEL0 |= 0x0005000; // Enable LCD pin functions // LCD pin directions FIO0DIR |= 0xFFF; // Set pins P0.0 to P0.11 as outputs
2. Generate Timing Delays
The LCD interface requires precise timing delays for actions like initialization, writing data etc. This can be achieved using timers or simple delay loops.
A 10us delay routine can be created to generate the required delays: void LCD_delay_10us(int us) { // Approx 10us delay int i; for(i=0; i
3. Initialize LCD in 4-bit Mode
4-bit initialization requires sending special commands using the upper 4 data lines. The R/W pin is pulled high to write: LCD_RS = 0; // Instruction mode LCD_RW = 1; // Write mode // Initialize LCD in 4 bit mode LCD_delay_10us(50000); // Wait 50ms after power ON LCD_send_nibble(0x03); // First initialization LCD_delay_10us(5000); // Wait 5ms LCD_send_nibble(0x03); // Second initialization LCD_delay_10us(150); // Wait 150us LCD_send_nibble(0x03); // Third initialization LCD_delay_10us(50); // Wait 50us LCD_send_nibble(0x02); // Function set
4. Send LCD Commands
Once initialized, the LCD command register can be written to using the upper 4 bits: // Set 4-bit mode LCD_command(0x28); // Display on, cursor on, blink off LCD_command(0x0E); // Clear screen LCD_command(0x01);
5. Write Data and Strings
To write data and strings, the RS pin is made high. Each character is written 4 bits at a time: // Write ‘A’ character LCD_RS = 1; LCD_RW = 1; LCD_send_nibble(0x41 >> 4); LCD_send_nibble(0x41);
Full strings can be written using a loop: void LCD_string(char *str) { while(*str) { LCD_data(*str++); } }
Interfacing LCD via I2C
The LPC845 microcontroller contains an I2C peripheral interface that can be utilized to connect to an I2C enabled LCD module. This minimizes pin usage to just the SDA and SCL lines.
The steps involved are:
- Configure the I2C peripheral on the LPC845
- Set the LCD I2C address
- Initialize the LCD via I2C
- Send commands and data to the LCD
1. Configure I2C Peripheral
The following enables the I2C peripheral clock and sets up the SDA and SCL pins: // Enable I2C clock LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); // Configure I2C pins LPC_IOCON->PIO0_4 &= ~0x3F; LPC_IOCON->PIO0_4 |= 0x01; LPC_IOCON->PIO0_5 &= ~0x3F; LPC_IOCON->PIO0_5 |= 0x01;
2. Set LCD I2C Address
Most I2C LCDs allow setting a custom address, for example with a jumper. This 7-bit address needs to be specified during initialization. #define LCD_I2C_ADDR 0x27
3. Initialize LCD
The I2C peripheral is initialized and used to send initialization commands: // Initialize I2C peripheral I2C_init(I2C_STANDARD_MODE); // Initialize LCD I2C_start(); I2C_write_byte(LCD_I2C_ADDR); I2C_write_byte(0x38); // 8-bit mode I2C_write_byte(0x39); // 8-bit, 2 line mode I2C_write_byte(0x14); // 5×8 font I2C_write_byte(0x70 | LCD_BACKLIGHT); // Turn on backlight I2C_write_byte(0x06); // Cursor move direction I2C_write_byte(0x01); // Clear display I2C_stop();
4. Send Commands and Data
Any subsequent LCD commands and data can be transferred over I2C: I2C_start(); I2C_write_byte(LCD_I2C_ADDR); // Send ‘Hello’ text I2C_write_byte(0x80); // Go to 1st line I2C_write_string(“Hello”); I2C_stop();
Interfacing Serial LCD
Some LCD modules meant for embedded use have an integrated UART/serial interface built in. This allows interfacing using just 2 wires for TX and RX lines.
Steps for serial LCD interfacing:
- Configure UART pins on LPC845
- Set UART baud rate
- Initialize LCD using commands
- Send data and strings over serial
1. Configure UART Pins
The TX and RX pins need to be assigned to a UART peripheral on the LPC845: // Enable UART clock LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); // Assign PIO0_0 to TX, PIO0_4 to RX LPC_IOCON->PIO0_0 |= 1; LPC_IOCON->PIO0_4 |= 1;
2. Set UART Baud Rate
The UART peripheral is initialized to communicate at the baud rate supported by the serial LCD, typically 9600: // Configure UART LPC_USART->CFG = 0; // 9600 baud @ 12MHz IRC oscillator LPC_USART->BRG = 0x1A0; LPC_USART->CTL = 0x03;
3. Initialize LCD
The serial LCD is initialized by sending configuration commands: // Initialize LCD LCD_serial_cmd(0x33); // Initialize LCD_serial_cmd(0x32); // 4-bit mode LCD_serial_cmd(0x28); // 2 line display // Other LCD configuration commands
4. Send Data and Strings
Text strings and data can be printed by sending the characters over the serial UART: // Print text string LCD_serial_string(“Hello!”); // Print data values char buffer[16]; sprintf(buffer, “%d”, sensor_value); LCD_serial_string(buffer);
Interfacing Graphical LCD
Graphical LCD displays can show images, icons and custom fonts in addition to text. They contain a display buffer memory that the CPU can write pixel data into. Some common graphical LCD options are:
- Monochrome LCDs
- Color LCDs with controller
- OLED displays
- TFT displays
The steps to interface a graphical LCD are:
- Choose LCD and initialize controller
- Configure display geometry and pixel format
- Write pixel data, shapes, images to framebuffer
- Update content on display
1. Initialize LCD Controller
Graphical LCD panels utilize a controller (GPU) to handle the framebuffer and provide an interface to the host CPU. The LCD controller is initialized first.
For example, initializing an SSD1963 driver over 16-bit parallel interface: // SSD1963 LCD controller // Initialize SSD1963 SSD1963_Init(); // Set LCD panel size SSD1963_SetDisplaySize(480, 272); // Configure 16-bit RGB 5-6-5 format SSD1963_SetRGBFormat(RGB565);
2. Configure Display Geometry
The geometry like screen resolution, color format/depth and orientation are configured: // 240×320 RGB565 landscape orientation SSD1963_SetOrientation(LANDSCAPE); SSD1963_SetDisplaySize(320, 240); SSD1963_SetRGBFormat(RGB565);
3. Write Pixel Data to Framebuffer
The LCD controller’s framebuffer can be written with pixel color values to render shapes, images and text: // Draw rectangle SSD1963_DrawRect(x, y, w, h, RGB(255, 0, 0)); // Draw image SSD1963_DrawBitmap(x, y, image_data); // Draw text SSD1963_DrawText(“Hello!”, x, y, font, RGB(0, 0, 0));
4. Update Content on Display
Finally the updated framebuffer contents are copied to the actual LCD panel: // Copy framebuffer to LCD SSD1963_UpdateScreen();
This process of updating the framebuffer and refreshing the LCD is handled automatically in most graphical libraries.
Summary
The small and low power LPC845 microcontroller provides a versatile interface options to connect LCD displays. Parallel interface uses most pins but offers highest speed. Serial LCD requires least pins and I2C offers good middle ground.
Graphical LCDs open up more features but need added controller electronics. With the help of good libraries, LCD interfacing on LPC845 can be easy and enable adding visual display capability to embedded applications.