In this lab, you are going to interface a seven-segment display to Tiva LaunchPad. The display counts from 0 ~ F and resets itself to zero. Before going further, let us first discuss seven-segment displays.
Seven Segment Display
If your embedded system only needs to display numbers, you can consider using a seven-segment display. The seven-segment display is a simple device. It has 8 LEDs (the decimal point is the 8th) and can be lit in different combinations to represent the Arabic numerals and some English characters.
The segments of a seven-segment display are referred to by the letters A to G, and an optional decimal point (an "eighth segment", referred to as DP) for the display of non--integer numbers.
There are mainly two types of seven-segment displays available. In a simple LED package as shown in the figure above, typically all of the cathodes (negative terminals) or all of the anodes (positive terminals) of the segment LEDs are connected and brought out to a common pin; this is referred to as a "common cathode" or a "common anode" device. Hence, a 7 segment plus decimal point package will only require nine pins, though commercial products typically contain more pins, and/or places where pins would go, in order to match standard IC sockets.
In a common anode display, all the positive terminals (anode connections) of the LED segments are connected together to logic "1", or Vcc on pin 3 and pin 8. To turn on an individual segment, you ground one of the pins with a suitable current limiting resistor to the cathode of the particular segment (a ~ g).
In a common cathode seven segment display, all the cathode connections of the LED segments are joined together to logic "0" or ground on pin 3 and pin 8. To use this type of display, you need to connect ground (GND) to pin3 and/or pin 8 and connect "HIGH" or logic "1" signal via a current limiting resistor to forward bias the individual Anode terminals (a ~ g).
In general, common anode displays are more popular than common cathode displays, since logic circuits can sink more current than they can source.
How to display a number on the seven segment display?
Depending upon which character will be displayed, the particular set of LEDs is forward biased.
Display a "0" To display the numerical digit "0" on the display as shown in the figure above, the LED segments corresponding to a, b, c, d, e, and f must be lit up. For common cathode display, these pins must be connected to power, and for common anode display, these pins must be connected to the ground.
Display a "1" To display the numerical digit "1" on the display as shown in the figure above, the LED segments corresponding to b, c must be lit up. For common cathode display, these pins must be connected to power, and for common anode display, these pins must be connected to the ground.
Displaying Letters
A single byte can encode the full state of a 7-segment-display. The most popular bit encodings are gfedcba and abcdefg, where each letter represents a particular segment in the display. In the gfedcba representation, a byte value of 0x06 would (in a common anode circuit) lit up segments 'c' and 'b', which would display a '1'.
Hexadecimal digit can be displayed on a seven-segment display. A combination of uppercase and lowercase letters is used for letters 'A' to 'F'; this is done in order to obtain a unique, unambiguous shape for each hexadecimal digit (otherwise, a capital 'D' would look identical to a '0' and a capital 'B' would look identical to an '8'). Also the digit '6' must be displayed with the top bar lit to avoid ambiguity with the lowercase letter 'b'.
The following table applies a common cathode seven segment display device. If you are using a common anode, the values in the table must be inverted.
Table 1: Seven Segment Display Truth Table for Hexadecimal Encodings
Digit
Display
Individual Segments Illuminated
Port [7:0]
Port [7:0]
dp
g
f
e
d
c
b
a
dp.g.f.e.d.c.b.a
dp.a.b.c.d.e.f.g
0
0
0
1
1
1
1
1
1
0x3F
0x7E
1
0
0
0
0
0
1
1
0
0x06
0x30
2
3
4
5
6
7
8
9
A
B
C
D
E
F
When you connect seven segment displays in a circuit, a current limiting resistor must be wired in series with each display segment. Any resistor value between 100Ω and 1KΩ will work for the LED resistor. The lower resistance will result in a brighter segment. It is best to use resistors of the same value so all the segments light up evenly.
Required Components List
220 Ω Resistor
x 8
7-Segment Display
x 1
Breadboard
x 1
Circuit / Schematic Diagram
The circuit diagram for connecting a common cathode seven segment display to the TI Tiva microcontroller port is shown below. The microcontroller I/O pins source the current required for the segment LEDs. The current limiting resistors connected in series between the microcontroller pina and segment LEDs are 220ohm each. Segments a ~ g and dp are driven through GPIO output ports.
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
Wire a circuit for the 7-segment display on the breadboard with eight current limiting resistors, then connect wires to the TI Tiva board. Make sure the power is disconnected when wiring up your breadboard.
The predefined hexadecimal encoding values need to be shifted to the corresponding bit in order to light up the correct segment LED on different Ports.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "TM4C123GH6PM.h"
#include "MyDefines.h"
void DelayMs(int ms); // Software Delay Function
void SegDisplay(uint8_t d);
void Setup_GPIO(void);
// You nave to finish the following array for Seven Segment Display
char SevenSeg[] = { 0x3f, // 0
0x06 // 1
// You have to finish this array for 7-seg display
};
int main()
{
char ch = 0;
int i = 0;
// Place your initialization/startup code here (e.g. Setup_GPIO() )
Setup_GPIO();
while (1) {
// Place your application code here
for (i = 0; i < sizeof(sevenSeg); i++) {
SegDisplay(ch & 0x0F);
ch++;
DelayMs(1000);
}
}
}
//------------------------------------------------------------------------------
void SegDisplay(uint8_t d)
{
char seg;
seg = SevenSeg[???];
}
//------------------------------------------------------------------------------
void Setup_GPIO(void)
{
// Configure GPIOs
// 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, PE7 on TM4C1294 (GPIO->LOCK and GPIO->CR
GPIOF->LOCK = 0x4C4F434B;
GPIOF->CR |= _PIN0;
// 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)
}
//------------------------------------------------------------------------------
// Delay ms milliseconds (16MHz CPU Clock)
void DelayMs(int ms)
{
volatile int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 4167; j++) {} // Do nothing for 1ms
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "TM4C1294NCPDT.h"
#include "MyDefines.h"
void DelayMs(int ms); // Software Delay Function
void SegDisplay(uint8_t d);
void Setup_GPIO(void);
char SevenSeg[] = { 0x3f, // 0
0x06 // 1
// You have to finish this array for 7-seg display
};
int main()
{
char ch = 0;
int i = 0;
// Place your initialization/startup code here (e.g. Setup_GPIO() )
Setup_GPIO();
while (1) {
// Place your application code here
for (i = 0; i < sizeof(sevenSeg); i++) {
SegDisplay(ch & 0x0F);
ch++;
DelayMs(1000);
}
}
}
//------------------------------------------------------------------------------
void SegDisplay(uint8_t d)
{
char seg;
seg = SevenSeg[???];
}
//------------------------------------------------------------------------------
void Setup_GPIO(void)
{
// Configure GPIOs
// 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, PE7 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)
}
//------------------------------------------------------------------------------
// Delay ms milliseconds (16MHz CPU Clock)
void DelayMs(int ms)
{
volatile int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 1605; j++) {} // Do nothing for 1ms
}
Lab Experiments
Comment out the for-loop code in the main function, inside the while-loop.
while (1) {
// Place your application code here
// for (i = 0; i < sizeof(sevenSeg); i++) {
// SegDisplay(ch & 0x0F);
// ch++;
// DelayMs(1000);
// }
}
Write a C code to have your display count up from 0 to F (and then rolls over to 0 again), with each digit displayed for one second.
Modify your code, add the SW1 function into your project.
After a power reset, the counter is STOP, and display '0' on the 7-Segment Display.
When the user presses SW1, the counter START to count up from 0 to F with a 1-sec interval and rolls over to 0 again.
Users can press SW1 to PAUSE / CONTINUE the counter.
You can use the following flowchart or finite state machine to implement the code:
Figure: The Polling Solution
The pseudocode for Polling solution:
// Implement the following code inside the main() function
create bool variables: preSw, currSw, pause create integer variable: i, count set preSw to true set pause to true set i, count to zero
setup GPIO display '0' on 7-seg display
loop read current SW state to currSw
if (falling edge occurred) invert pause value endif
update the preSw from currSw
if pause not true increase count by 1 if count large than 50 set count to zero increase i value by 1 endif endif
display i value on the 7-seg display delay for 20 ms
repeat
Questions
What type of seven segment display did you use in this lab?
Complete Table 1 which shows which segments must be illuminated to display the hex digits 0..F.
If you used a common anode (CA) 7-segment display instead of a common cathode (CC) one, what change would you have to make in the wiring and the code?
In this lab, we use eight resistors for each LED on a 7-segment display unit. Instead of using eight resistors, can you just use one 220 ohm resistor connected to the common ground of the unit, and have the equivalent circuit? Explain why or why not.
Now, add on-board SW1 and SW2 to the project. SW1 is for RESET, and SW2 is for COUNT.
When the user presses the RESET (SW1) button, reset the counter value to zero and display "0".
When the user presses the COUNT (SW2) button, increase the counter value by 1 and display it on the seven segment display.
The counter only increases at the moment when the COUNT (SW2) button is pressed (falling edge on signal input pin).
Hint:
The RESET key has a higher priority than the COUNT key, so you need to check the RESET key state first. If the user does not press the RESET key, then check the COUNT key.