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.