HD44780 based LCD modules are very popular among hobbyists because they are cheap and they can display characters. Besides they are very easy to interface with microcontrollers. In this lab, you will learn how to interface an HD44780 based character LCD to a TI Tiva LaunchPad. The interface requires 7 I/O lines of the TM4C microcontroller: 4 data lines and 3 control lines. You also will learn how to use ezTiva LIB in order to display information on the LCD module.
Required Components List
Character LCD Module
× 1
10 KΩ Potentiometer
× 1
Breadboard
× 1
Breadboard Power Adapter
× 1
Circuit / Schematic Diagram
In this lab, a 16x2 character LCD module will be used and connected to the Tiva LaunchPad, as shown in the following diagram. The LCD module will be configured in 4-bit interfacing mode, so the data pin D[0]~D[3] on the LCD module will not be used. All the pins used to connect to the LCD module must be configured with the GPIO output direction.
Create a new folder under the EE3450 folder and name it Lab04_CharLCD. Then double-click the folder you just created to jump into it.
Launch the Keil μVisio and create a new project, save the project as Lab01_CharLCD.
Add MyDefines.h to the Source Group, and then add the Common folder to the include paths under the "Options for Target" setting.
Add ezTiva LIB into your project, increase the stack and heap size under the "startup_TM4cXXX.s (Startup)" setting, and then add the ezTivaLIB folder to the include paths under the "Options for Target" setting. (Lesson 09: Add ezTiva Library into Your Project)
Configurations
Write down the following configuration information into your lab report.
Next, we need to configure all the GPIO ports and pins that are used in the designd.
According to the pin connections, complete the following GPIO configurations for each port. Fills the pin field by the value below:
0: Clean the bit
1: Set the bit
x: Do not change the bit
d: Do not care
For both TM4C123GXL and TM4C1294XL LaunchPads, the Port C [3:0] are used for JTAG/SWD. Therefore, when you configure the Port C, you have to use bitwise operators to make sure your new configuration settings do not affect the JTAG/SWD function (PC3 ~ PC0).
Most of GPIO pins are configured as GPIOs and tri-stated by default (GPIOPCTL = 0, CPIOAFSEL = 0, GPIODIR = 0, GPIOPUR = 0, GPIOPDR = 0, GPIOODR = 0)
Enable Clock to the GPIO Modules (RCGCGPIO register) TM4C123G: SYSCTL->RCGCGPIO|= binary = hex
8
4
2
1
8
4
2
1
7
6
5
4
3
2
1
0
bit
Port F
Port E
Port D
Port C
Port B
Port A
port
0
0
-
TM4C1294: SYSCTL->RCGCGPIO |= binary = hex
8
4
2
1
8
4
2
1
8
4
2
1
8
4
2
1
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
bit
Port Q
Port P
Port N
Port M
Port L
Port K
Port J
Port H
Port G
Port F
Port E
Port D
Port C
Port B
Port A
port
0
-
-
-
After enable clock signal, check the PRGPIO register until the correspoding bit set to 1.
Unlock Port TM4C123G: PD7 and PF0 are locked after reset. TM4C1294: PD7 and PE7 are locked after reset If those pins are used in the design, it must be unlocked first. To unlock the port, 0x4C4F434B must be written into GPIOLOCK register and uncommit it by setting the GPIOCR register.
8
4
2
1
8
4
2
1
7
6
5
4
3
2
1
0
bit
Port
Pin 7
Pin 6
Pin 5
Pin 4
-
Pin 3
Pin 2
Pin 1
Pin 0
pin
Value in Hex
Register
Value to Register
-
-
=
➤
GPIO->LOCK
=
0x4C4F434B
-
-
=
➤
GPIO->CR
-
-
=
➤
GPIO->LOCK
=
0x4C4F434B
-
-
=
➤
GPIO->CR
Convert above configuration into registers
GPIO Analog Mode Select If any pin is used as an Analog signal (check Signal Type field on the table 1), the appropriate bit in AMSEL must be set.
0: Digital signal
1: Analog signal
8
4
2
1
8
4
2
1
7
6
5
4
3
2
1
0
bit
Port
Pin 7
Pin 6
Pin 5
Pin 4
-
Pin 3
Pin 2
Pin 1
Pin 0
pin
Value in Hex
Register
Value to Register
-
-
=
➤
GPIO->AMSEL
-
-
=
➤
GPIO->AMSEL
-
-
=
➤
GPIO->AMSEL
-
-
=
➤
GPIO->AMSEL
-
-
=
➤
GPIO->AMSEL
-
-
=
➤
GPIO->AMSEL
-
-
=
➤
GPIO->AMSEL
GPIO Port Control (PCTL) The PCTL register is used to select the specific periheral signal for each GPIO pin when using the alternate function mode.
0: GPIO
1~0xF: Check the GPIO Pins and Alternate Function table
GPIO Alternate Function Select (AFSEL) Setting a bit in AFSEL register configures the corresponding GPIO pin to be controlled by PCTL peripheral function.
0: General I/O
1: Pin connected to the digital function that defined in PCTL register
8
4
2
1
8
4
2
1
7
6
5
4
3
2
1
0
bit
Port
Pin 7
Pin 6
Pin 5
Pin 4
-
Pin 3
Pin 2
Pin 1
Pin 0
pin
Value in Hex
Register
Value to Register
-
-
=
➤
GPIO->AFSEL
-
-
=
➤
GPIO->AFSEL
-
-
=
➤
GPIO->AFSEL
-
-
=
➤
GPIO->AFSEL
-
-
=
➤
GPIO->AFSEL
-
-
=
➤
GPIO->AFSEL
-
-
=
➤
GPIO->AFSEL
GPIO Pin Direction (DIR) Set pin direction
0: Input pin
1: Output pin
8
4
2
1
8
4
2
1
7
6
5
4
3
2
1
0
bit
Port
Pin 7
Pin 6
Pin 5
Pin 4
-
Pin 3
Pin 2
Pin 1
Pin 0
pin
Value in Hex
Register
Value to Register
-
-
=
➤
GPIO->DIR
-
-
=
➤
GPIO->DIR
-
-
=
➤
GPIO->DIR
-
-
=
➤
GPIO->DIR
-
-
=
➤
GPIO->DIR
-
-
=
➤
GPIO->DIR
-
-
=
➤
GPIO->DIR
Internal Pull-Up Resistor (PUR), Pull-Down Resistor (PDR), and Open-Drain (ODR) PUR: The pull-up control register PDR: The pull-down control register ODR: The open-drain control register
0: Disable
1: Enable
8
4
2
1
8
4
2
1
7
6
5
4
3
2
1
0
bit
Port
Pin 7
Pin 6
Pin 5
Pin 4
-
Pin 3
Pin 2
Pin 1
Pin 0
pin
Value in Hex
Register
Value to Register
-
-
=
➤
GPIO->
-
-
=
➤
GPIO->
-
-
=
➤
GPIO->
-
-
=
➤
GPIO->
-
-
=
➤
GPIO->
-
-
=
➤
GPIO->
-
-
=
➤
GPIO->
GPIO Digital Enable Enables all the pins that are used in the design, including GPIO pins and alternate function pins.
0: Pin undriven
1: Enable pin
8
4
2
1
8
4
2
1
7
6
5
4
3
2
1
0
bit
Port
Pin 7
Pin 6
Pin 5
Pin 4
-
Pin 3
Pin 2
Pin 1
Pin 0
pin
Value in Hex
Register
Value to Register
-
-
=
➤
GPIO->DEN
-
-
=
➤
GPIO->DEN
-
-
=
➤
GPIO->DEN
-
-
=
➤
GPIO->DEN
-
-
=
➤
GPIO->DEN
-
-
=
➤
GPIO->DEN
-
-
=
➤
GPIO->DEN
Example Source Code
Copy the following example code to your main.c file.
Note: The example code is not yet complete, you must implement all functions following the lab instructions.
The following code does not complete, you need to finish the GPIO configurations.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include "TM4C123GH6PM.h"
#include "MyDefines.h"
#include "ez123G.h"
void Setup_GPIO(void);
int main(void)
{
PEZOBJ_LCD lcd; // Declare an object for LCD module
char str[100];
uint16_t i = 0;
Setup_GPIO(); // GPIO Configuration
lcd = ezLCD_Create(); // Creating a new Hardware LCD Object
ezLCD_Connect_DataPort(lcd, GPIOD, PIN_3_0); // Connecting DATA port on PortD[3:0]
ezLCD_Connect_ENPin(lcd, GPIOE, PIN1); // Connecting EN pin on PortE[1]
ezLCD_Connect_RSPin(lcd, GPIOE, PIN2); // Connecting RS pin on PortE[2]
ezLCD_Connect_RWPin(lcd, GPIOE, PIN3); // Connecting RW pin on PortE[3]
ezLCD_Start(lcd); // Starting lcd object
ezLCD_LoadVerticalBargraphFonts(lcd); // Load vertical bargraph fonts
ezLCD_ClearDisplay(lcd); // Clear LCD display
ezLCD_PrintString(lcd, "HELLO"); // Display string on LCD screen
ezLCD_Position(lcd, 1,0); // Set display position at [1,0] (raw 1. col 0)
ezLCD_PrintString(lcd, "TI Tiva 123G"); // Display string on LCD screen
while (1){
sprintf(str,"i = %d ", i);
ezLCD_Position(lcd, 0, 6);
ezLCD_PrintString(lcd, str);
ezLCD_DrawVerticalBG(lcd, 1, 15, 2, i%16);
i++;
timer_waitMillis(100); // Hardware timer delay for 100 ms
}
}
void Setup_GPIO()
{
// GPIO Initialization and Configuration
// 1. Enable Clock to the GPIO Modules (SYSCTL->RCGCGPIO)
SYSCTL->RCGCGPIO |= ____;
// allow time for clock to stabilize (SYSCTL-PRGPIO)
while ((SYSCTL->PRGPIO & (____)) != (____)) {};
// 2. Unlock GPIO only PD7, PF0 on TM4C123G; PD7 on TM4C1294 (GPIO->LOCK and GPIO->CR)
// 3. Set Analog Mode Select bits for each Port (GPIO->AMSEL 0=digital, 1=analog)
// 4. Set Port Control Register for each Port (GPIO->PCTL, check the PCTL table)
// 5. Set Alternate Function Select bits for each Port (GPIO->AFSEL 0=regular I/O, 1=PCTL peripheral)
// 6. Set Output pins for each Port (Direction of the Pins: GPIO->DIR 0=input, 1=output)
// 7. Set PUR bits (internal Pull-Up Resistor), PDR (Pull-Down Resistor), ODR (Open Drain) for each Port (0: disable, 1=enable)
// 8. Set Digital ENable register on all GPIO pins (GPIO->DEN 0=disable, 1=enable)
}
The following code does not complete, you need to finish the GPIO configurations.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include "TM4C1294NCPDT.h"
#include "MyDefines.h"
#include "ez1294.h"
void Setup_GPIO(void);
int main(void)
{
PEZOBJ_LCD lcd; // Declare an object for LCD module
char str[100];
uint16_t i = 0;
Setup_GPIO(); // GPIO Configuration
lcd = ezLCD_Create(); // Creating a new Hardware LCD Object
ezLCD_Connect_DataPort(lcd, GPIOE_AHB, PIN_3_0);// Connecting DATA port on PortE[3:0]
ezLCD_Connect_ENPin(lcd, GPIOD_AHB, PIN7); // Connecting EN pin on PortD[7]
ezLCD_Connect_RSPin(lcd, GPIOA_AHB, PIN6); // Connecting RS pin on PortA[6]
ezLCD_Connect_RWPin(lcd, GPIOM, PIN4); // Connecting RW pin on PortM[4]
ezLCD_Start(lcd); // Starting lcd object
ezLCD_LoadVerticalBargraphFonts(lcd); // Load vertical bargraph fonts
ezLCD_ClearDisplay(lcd); // Clear LCD display
ezLCD_PrintString(lcd, "HELLO"); // Display string on LCD screen
ezLCD_Position(lcd, 1,0); // Set display position at [1,0] (raw 1. col 0)
ezLCD_PrintString(lcd, "TI Tiva 1294"); // Display string on LCD screen
while (1){
sprintf(str,"i = %d ", i);
ezLCD_Position(lcd, 0, 6);
ezLCD_PrintString(lcd, str);
ezLCD_DrawVerticalBG(lcd, 1, 15, 2, i%16);
i++;
timer_waitMillis(100); // Hardware timer delay for 100 ms
}
}
void Setup_GPIO()
{
// GPIO Initialization and Configuration
// 1. Enable Clock to the GPIO Modules (SYSCTL->RCGCGPIO)
SYSCTL->RCGCGPIO |= ____;
// allow time for clock to stabilize (SYSCTL-PRGPIO)
while ((SYSCTL->PRGPIO & (____)) != (____)) {};
// 2. Unlock GPIO only PD7, PF0 on TM4C123G; PD7 on TM4C1294 (GPIO->LOCK and GPIO->CR)
GPIOD_AHB->LOCK = 0x4C4F434B;
while ((GPIOD_AHB->LOCK & 0x01) == 0x01) {}; // Unlocked when reading the GPIO->LOCK ==0x00
*(((char*)GPIOD_AHB)+0x524) = 0xFF; // Unload PD7
// 3. Set Analog Mode Select bits for each Port (GPIO->AMSEL 0=digital, 1=analog)
// 4. Set Port Control Register for each Port (GPIO->PCTL, check the PCTL table)
// 5. Set Alternate Function Select bits for each Port (GPIO->AFSEL 0=regular I/O, 1=PCTL peripheral)
// 6. Set Output pins for each Port (Direction of the Pins: GPIO->DIR 0=input, 1=output)
// 7. Set PUR bits (internal Pull-Up Resistor), PDR (Pull-Down Resistor), ODR (Open Drain) for each Port (0: disable, 1=enable)
// 8. Set Digital ENable register on all GPIO pins (GPIO->DEN 0=disable, 1=enable)
}
Lab Experiments
Using your embedded board to solve the following problems, and display the result on the character LCD module.