Lab Project 3:
Using the Seven-Segment Display
For more info: support@digilent.ro
Revision: September 3, 2009
Overview
This document describes the use of two Digilent peripheral modules, the PmodSSD™ SevenSegment Display Module and the PmodSWT™ Switch Module, in order to illustrate the use of
ATmega64L ports, timers, and timer interrupts. This type of display is widely used in digital clocks,
traffic light timing, electronic meters, and many other electronic devices for displaying numerical
information.
Bold numbers in brackets refer to the bibliography below.
PmodSSD Seven-Segment Display Module
From the previous lab project you have learned how to configure the timer and timer interrupts, and
also the ports of the microcontroller. In this application you will work with a seven-segment display
and decode the numbers to be displayed, as well as setting the right timing for selecting both digits of
the display.
The PmodSSD offers a single two-digit seven-segment display device that can be attached directly to
any Digilent system board. The seven-segment display uses high-bright LEDs that are easily readable
with less than 5mA of current consumption, so they can be driven directly from most system boards.
[4]
The two digits on the common cathode seven-segment LED display are each composed of seven
segments arranged in a “figure 8” pattern, with an LED embedded in each segment. Segment LEDs
can be individually illuminated, so any one of 128 patterns can be displayed on a digit by illuminating
certain LED segments and leaving the others dark. Of these 128 possible patterns, the ten
corresponding to the decimal digits are the most useful. The cathodes of the seven LEDs forming
each digit are tied together into one “common cathode” circuit node, but the LED anodes remain
separate. The common cathode signals are available as two “digit enable” input signals to the display.
The anodes of similar segments on both digits are connected into seven circuit nodes that are
available from the Pmod connector pins.[4]
These seven anode signals are available as inputs to the two-digit display. This signal connection
scheme creates a multiplexed display, where the anode signals are common to both digits but can
only illuminate the segments of the digit whose corresponding cathode signal is asserted (see Figure
1).
www.digilentinc.com
page 1 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
Figure 1 Common Cathode
In order to show a two-digit number on the display, the cathodes have to be driven in a continuous
succession at a faster update rate than the human eye can perceive. Each digit is illuminated half of
the time, but because the eye cannot perceive the darkening of a digit before it is illuminated again,
the digit appears continuously illuminated. If the update or “refresh” rate is slowed to a given point
(around 45Hz), then most people will begin to see the display flicker. In order for each of the four
digits to appear bright and continuously illuminated, both digits should be driven once every 1 to 16ms
(for a refresh frequency of 60Hz to 1KHz). For example, in a 60Hz refresh scheme, the entire display
would be refreshed once every 16ms, and each digit would be illuminated for half of the refresh cycle,
or 8ms.
To illustrate the process, if C1 is asserted while AB and AC are asserted, then a “1” will be displayed
in digit position 1. Then, if C2 is asserted while AA, AB, and AC are asserted, then a “7” will be
displayed in digit position 2. If C1 and AB, AC are driven for 8 ms, and then C2 and AA, AB, AC are
driven for 8 ms in an endless succession, the display will show “17” (see Figure 2). [4]
www.digilentinc.com
page 2 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
Figure 2 Seven-Segment Display Connection Diagram
The segments of a single digit are named as shown in Figure 3.
Figure 3 Segment Names
www.digilentinc.com
page 3 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
Decoding the segments means creating a lookup table with all the corresponding values for each
number shown as a hexadecimal digit. Using Figure 3 as a base for the decoding algorithm, and
considering a common cathode configuration, the lookup table is as follows: [6]
Table 1 Decoding Lookup Table
Hex number Seven Segment Conversion
g
f
e
d
c
0
0
1
1
1
1
1
0
0
0
0
1
2
1
0
1
1
0
3
1
0
0
1
1
4
1
1
0
0
1
5
1
1
0
1
1
6
1
1
1
1
1
7
0
0
0
0
1
8
1
1
1
1
1
9
1
1
0
1
1
A
1
1
1
0
1
b
1
1
1
1
1
C
0
1
1
1
0
d
1
0
1
1
1
E
1
1
1
1
0
F
1
1
1
0
0
b
1
1
1
1
1
0
0
1
1
1
1
0
0
1
0
0
a
1
0
1
1
0
1
1
1
1
1
1
0
1
0
1
1
Seven Segment
equivalent
3F
06
5B
4F
66
6D
7D
07
7F
6F
77
7C
39
5E
79
71
NOTE: In order to distinguish the letter B from the numeral 8 and the letter D from the numeral 0, you
have to display the letters in lower case.
Regarding the selection of the two digits and refresh rate, this can be set using timer interrupts. For an
accepted refresh frequency between 60Hz and 1KHz, if you choose a 100 Hz rate, interrupts should
occur every 0.01 seconds. Thus the number from TCNT registers is calculated by the following
formula:
(3.1)
For Tint=0.01s, fCK=8MHz and NCK=1024, the value for N will be 4E. For an overflow interrupt, the final
number loaded in TCNT is FFFF-4E=FFB1.
www.digilentinc.com
page 4 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
PmodSWT Switch Module
The PmodSWT has four slide switches that can be used to provide “on and off” inputs to a circuit.
The PmodSWT’s switches can be used as mode switches and also as data input switches. They can
be activated individually or simultaneously in any combination. When the switch is in the up position it
sends the voltage on the VCC pin to the corresponding pin on J1, and when the switch is in the down
position it sends GND to the corresponding pin on J1 (as shown in Figure 4). [2]
The PmodSWT has a 6-pin header for easy connection to a Digilent system board. Some system
boards, like the Digilent Pegasus board, have a 6-pin header that can connect to the PmodSWT with
a 6-pin cable. [2]
Figure 4 PmodSWT Circuit Diagram
Example Project
The application uses the PmodSWT to set a certain number and the PmodSSD to display the number
which is binary set. The PmodSWT is attached to connector JH on the Cerebot II, meaning
ATMega64L port F pins.
Pins are read in a variable called Sw and the 8-bit value is truncated to a 4-bit value, which represents
the number set from the four switches. According to that value, the decoding function will send the
corresponding values to both digits.
Due to the fact that the refresh rate is greater than 60Hz, when set at 100Hz, the two digits of the
display appear selected all the time because the flickering cannot be perceived by the human eye.
The software diagrams are presented below.
www.digilentinc.com
page 5 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
Start
Port initialization
Timer 1 initialization
Timer 1 interrupt
Figure 5 Main Function Diagram
Start
Toggle selecting
digit variable
Call SsgDecoder
function
Send value to port A
Yes
First digit selected?
Send value to port C and
select second digit
No
Send value to port C and
select first digit
Figure 6 Timer1 Interrupt Function
Ports A and C are used because the module can only be connected at two of the board’s connectors.
In order to send the value for a certain number to both ports, two variables are used: DisplayedNrA
and DisplayedNrC. Four bits of each displayed number are sent to port A and the remaining four bits
to port C.
The application’s source code is shown at the end of the document.
www.digilentinc.com
page 6 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
Tasks
1. Modify the timing so the interrupt occurs at a frequency of 50Hz and see what happens.
Explain why.
2. Modify Table 1 to show the LEDs having a common anode.
3. Write your own code for creating a two-digit decimal counter.
Tip: You will have to use two of the microcontroller’s timers; one for counting and one for
displaying the values. Calculate the timing for interrupts and make sure you avoid the
flickering. Then be careful to send the right numbers to the display. You can do it like this:
Tens=Number/10;
Units=Number%10;
Bibliography
[1]
[2]
[3]
[4]
[5]
[6]
http://www.atmel.com/dyn/resources/prod_documents/2490S.pdf
http://digilentinc.com/Data/Products/PMOD-SWITCH/Pmod%20SWT_rm.pdf
http://digilentinc.com/Data/Products/PMOD-SWITCH/PmodSWT_sch.pdf
http://digilentinc.com/Data/Products/PMOD-SSD/Pmod%20SSD_rm.pdf
http://digilentinc.com/Data/Products/PMOD-SSD/PmodSSD_sch.pdf
http://www.dnatechindia.com/index.php/Tutorials/8051-Tutorial/7-Seg-Interfacing.html
Application Source Code
/************************************************************************/
/*
*/
/*
LabProject3.c -Digilent Cerebot Example Program
*/
/*
*/
/************************************************************************/
/*
Author:
Monica Bot
*/
/*
Copyright 2009, Digilent Inc.
*/
/************************************************************************/
/*
Module Description:
*/
/*
*/
/*
This program is an example to illustrate using C code and WinAVR
*/
/*
to program the Cerebot board. It shows an example of using Pmods
*/
/*
SWT and SSD.
*/
/*
*/
/************************************************************************/
/*
Revision History:
*/
/*
*/
/*
02/25/2009(BotM): created
*/
/*
*/
/************************************************************************/
/* ------------------------------------------------------------ */
/*
Include File Definitions
*/
/* ------------------------------------------------------------ */
#include <stdio.h>
#include <avr/io.h>
#include <inttypes.h>
www.digilentinc.com
page 7 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
#include <avr/interrupt.h>
/* ------------------------------------------------------------ */
/*
Local Type Definitions
*/
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/*
Global Variables
*/
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/*
Local Variables
*/
/* ------------------------------------------------------------ */
unsigned char DisplayedNrA;
unsigned char DisplayedNrC;
unsigned char c=0x00;
/* ------------------------------------------------------------ */
/*
Forward Declarations
*/
/* ------------------------------------------------------------ */
void DeviceInit(void);
void TimerInit();
void SsgDecoder();
/* ------------------------------------------------------------ */
/*
Interrupt Service Routines
*/
/* ------------------------------------------------------------ */
ISR(TIMER1_OVF_vect)
{
/* Displays the binary number set from switches of Pmod SWT
on the Pmod SSD
*/
c=~c;
SsgDecoder();
PORTA=DisplayedNrA;
if (c==0xFF)
{
PORTC=DisplayedNrC+0x08;
}
else
{
PORTC=DisplayedNrC;
}
TCNT1H=0xFF;
TCNT1L=0xB1;
}
/* ------------------------------------------------------------ */
/*
Procedure Definitions
*/
/* ------------------------------------------------------------ */
/*** main
**
**
Synopsis:
**
st = main()
**
**
Parameters:
**
none
**
www.digilentinc.com
page 8 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
**
Return Values:
**
does not return
**
**
Errors:
**
none
**
**
Description:
**
Main program module. Performs basic board and timer
**
initialization and then enters the main program loop.
*/
int
main(void)
{
cli();
DeviceInit();
TimerInit();
sei();
for(;;){
}
}
/* ------------------------------------------------------------ */
/*** SsgDecoder
**
**
Synopsis:
**
SsgDecoder()
**
**
Parameters:
**
none
**
**
Return Values:
**
none
**
**
Errors:
**
none
**
**
Description:
**
Decodes the Seven Segments Display according to the binary
**
settings of PORTF
*/
void
SsgDecoder()
{
unsigned char Sw;
unsigned char DataSw;
Sw=PINF;
DataSw=(Sw&0x0F);
switch (DataSw)
{
case 0x00:
DisplayedNrA=0x0F;
DisplayedNrC=0x03;
break;
www.digilentinc.com
page 9 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
case 0x01:
DisplayedNrA=0x06;
DisplayedNrC=0x00;
break;
case 0x02:
DisplayedNrA=0x0B;
DisplayedNrC=0x05;
break;
case 0x03:
DisplayedNrA=0x0F;
DisplayedNrC=0x04;
break;
case 0x04:
DisplayedNrA=0x06;
DisplayedNrC=0x06;
break;
case 0x05:
DisplayedNrA=0x0D;
DisplayedNrC=0x06;
break;
case 0x06:
DisplayedNrA=0x0D;
DisplayedNrC=0x07;
break;
case 0x07:
DisplayedNrA=0x07;
DisplayedNrC=0x00;
break;
case 0x08:
DisplayedNrA=0x0F;
DisplayedNrC=0x07;
break;
case 0x09:
DisplayedNrA=0x0F;
DisplayedNrC=0x06;
break;
case 0x0A:
DisplayedNrA=0x07;
DisplayedNrC=0x07;
break;
case 0x0B:
DisplayedNrA=0x0C;
DisplayedNrC=0x07;
break;
case 0x0C:
DisplayedNrA=0x09;
DisplayedNrC=0x03;
break;
case 0x0D:
DisplayedNrA=0x0E;
DisplayedNrC=0x05;
break;
www.digilentinc.com
page 10 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
case 0x0E:
DisplayedNrA=0x09;
DisplayedNrC=0x07;
break;
case 0x0F:
DisplayedNrA=0x01;
DisplayedNrC=0x07;
break;
default:
DisplayedNrA=0x00;
DisplayedNrC=0x00;
}
}
/* ------------------------------------------------------------ */
/*** DeviceInit
**
**
Synopsis:
**
DeviceInit()
**
**
Parameters:
**
none
**
**
Return Values:
**
none
**
**
Errors:
**
none
**
**
Description:
**
Initializes on chip peripheral devices to the default
**
state.
*/
void
DeviceInit()
{
/* Default i/o ports A,C and F to output, initialize PORTA, PORTF
and PORTC to 0 value
*/
DDRA=0xFF;
PORTA=0x00;
DDRC=0xFF;
PORTC=0x00;
PORTF=0x00;
DDRF=0x00;
PINF=0x00;
}
/* ------------------------------------------------------------ */
/*** TimerInit
**
**
Synopsis:
www.digilentinc.com
page 11 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.
Lab Project 3: Using the Seven-Segment Display
**
TimerInit()
**
**
Parameters:
**
none
**
**
Return Values:
**
none
**
**
Errors:
**
none
**
**
Description:
**
Enables Timer1 interrupt and sets it for 0,01s interrupt
*/
void
TimerInit()
{
/* Sets the prescaler to 1024, loads TCNT registers with
the coresponding value for 0,01s, enables Timer1 interrupt
*/
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0xFF;// intr la 0,01s
TCNT1L=0xB1;
TIMSK=0x04;
ETIMSK=0x00;
TIFR=0x04;
}
/* ------------------------------------------------------------ */
/*** ProcName
**
**
Synopsis:
**
**
Parameters:
**
**
Return Values:
**
**
Errors:
**
**
Description:
**
*/
/* ------------------------------------------------------------ */
/************************************************************************/
www.digilentinc.com
page 12 of 12
Copyright Digilent, Inc. All rights reserved. Other product and company names mentioned may be trademarks of their respective owners.