Straight driving a 7-segment LED display screen with the STM32

Uploaded on Oct 28, 2018 in equipment, stm32, stm32 plus

7 sector LEDs are an exceptionally affordable means to include a huge, intense and also really legible numerical display screen to your job.

Shows comparable to the one visualized over can be had for just 50 cents each on in the typical elevations of 0.56 ″, 0.36 ″ and also 0.28 ″. You can pick anywhere in between one and also 4 numbers in the exact same bundle. They’re described as 7 sector however truly they’re 8 since each number features a little decimal factor down near the bottom right.


The several number bundles make use of a circuitry setup developed to reduce the variety of pins called for to drive it without needing to install any type of reasoning in any way within the bundle.

If you count the variety of sections on, for instance, a 3 number present you ‘d swiftly understand that a straightforward setup that subjected each BAITED its very own committed pin would certainly call for (8 * 3) + 1 = 25 pins on the bundle, of which you would certainly require to connect 24 to your MCU to drive it. That’s much way too many and also is the reason that they can be found in typical cathode or typical anode arrangements.

Usual cathode setup

Allowed’s take a look at typical cathode initially.

In this setup there are committed power pins for each and every of the 7 sections however the exact same sector on each number are all linked with each other. Beyond of the LED you can see that all 8 cathodes for a figure are looped and also provided at a solitary pin.

If you take a minute to absorb this you can see just how we can illuminate a section of our selecting on any type of number. As an example, to illuminate sector A on number 2 we would use a present to pin 11 while basing pin 9. Pins 8 and also 12 should be separated or otherwise stopped from permitting present circulation.

To light sector A on number 1 we would certainly separate pin 9 and also ground pin 12, and also ultimately for number 3 we would certainly separate pin 12 and also ground pin 8.


Currently you must be obtaining a suggestion of just how these screens are planned to be driven. Allow’s take a look at a completely functioned instance of just how we would certainly present the number “123”.

First of all we would certainly light sections E, F on number 1 by allowing present circulation with pins 1, 10 and also12 After that we would certainly light sections A, B, D, E, G on number 2 by allowing pins 11, 7, 2, 1, 5 and also 9. Ultimately we would certainly light sections A, B, C, D, G by allowing just pins 11, 7, 4, 2, 5 and also 8.

If we duplicate the above activities quick sufficient after that the human eye will certainly regard all 3 numbers to be continuously lit although we are changing them on and also off really swiftly.

Usual anode setup

This write-up is mosting likely to concentrate on the typical cathode kind of display screen however, for efficiency I’ll reveal you the various other setup, so you recognize that 2 inappropriate kinds are readily available.

In the typical anode setup we once more have different pins for each and every sector and also once more all equivalent sections on all numbers are wired with each other however this time around the cathode finishes of the sector LEDs are separately subjected and also it’s the anodes that are all linked with each other on each number.

The multiplexed driving strategy is specifically the exact same for typical anode screens however that does not imply you might make use of typical anode where a style requires typical cathode since you can not, you would certainly need to alter the layout.

Driving with an MCU

There are a couple of alternatives readily available if you have an MCU and also you intend to drive among these screens. If you have an MCU with a restricted variety of IO pins, such as an Arduino Uno after that your finest choice is to make use of a devoted vehicle driver IC that will certainly do the help you.

The Saying MAX7221 will certainly drive typical cathode screens of as much as a tremendous 8 numbers while calling for simply a 3 cable SPI user interface to the host MCU. Utilizing simply among these ICs you might have 2 of the most significant 4 number screens in your job at a price of simply 3 MCU pins. I have actually utilized this IC lot of times prior to in jobs that you can check out on this website. The primary downside of this IC is that it needs a 5V supply and also 5V degrees at the SPI pins. This is not a problem for the Arduino Uno however it suggests it can not be utilized with an STM32 without a degree shifter.

If you’re utilizing an MCU with a multitude of GPIOs, such as the majority of the STM32 bundles, after that you have the choice of driving these screens straight for the price of simply 8 resistors and also 3 n-channel MOSFETs, which’s the technique that ’re mosting likely to discover below today.

Straight drive circuit

Right here’s the circuit representation that I make use of to drive a 3 number display screen that has blue LEDs. It’s a picture from a much bigger circuit that I’m dealing with.

The option of resistor is very important since it restricts the quantity of present circulation and also establishes the general illumination of the display screen. I’ll be utilizing the STM32 F0 exploration board that holds an STM32 F051 MCU to execute this circuit.

The initial point that I require to do is discover the MCU datasheet and also figure out the optimum present that the gadget can resource and also sink.

Those restrictions refer to an additional table previously in the datasheet that informs us the complete present resource and also sink for all pins.

So we have a per-pin outright restriction of 20 mA and also a general gadget restriction of 120 mA. To stay clear of warm accumulation and also permit the gadget to really do various other job too we will certainly remain far from those restrictions.

Exist any type of various other restrictions? Of course there are. It pays to review the whole datasheet since concealed away in an explanation there is a really essential restriction concerning GPIOs COMPUTER13 to COMPUTER15

We will certainly not make use of these pins.

Resistor computation

To determine the resistor worths we require to recognize the forward voltage of the LEDs in the display screen. This is quickly checked by utilizing your multimeter in its diode screening setting.

The meter reveals an ahead voltage of regarding 2.6 V which is typical for a blue LED. Currently I’ll take a wild hunch that since contemporary LEDs are really intense at reduced currents after that 2mA will certainly suffice present to obtain a wonderful, legible illumination. To match the STM32 F0 Exploration board I’ll examine this with a 3.0 V supply. That suggests a resistor of (3.0– 2.6)/ 0.002 = 200 Ω is called for.

LEDs do not photo well so please take my word for it that this behaves and also intense. Can the STM32 manage it? 2mA drops well listed below the per-pin restriction and also the most awful situation circumstance is mosting likely to be all 8 sections lit at the exact same time offering an overall present resource of 8 * 2 = 16 mA. No worry in any way. The bundle should not also obtain cozy.

The trouble with utilizing the 200 Ω resistor that we determined is that each number is just lit for 33% of the moment which will certainly make it show up 3 times as dim as we are anticipating. As a result we require to decrease the resistor by a variable of 3 and also make use of a worth of 68 Ω rather.

This will certainly increase the top present seen by the RESULTED IN 6mA however the typical present will certainly still be 2mA. In the worst-case circumstance where your MCU hangs or collapses while driving all 8 sections of a figure after that it will certainly be sourcing 8 * 6mA = 48 mA. This is still within risk-free degrees and also will certainly not melt up the bundle.

This number of 48 mA is the factor for each and every number pin being turned on or off utilizing a MOSFET. If we were to straight attach these pins to the MCU after that we would certainly remain in risk of sinking 48 mA right into a solitary pin which would most likely completely harm it.

The resistors, MOSFETs and also jumper cables are done in area and also we prepare to establish the firmware. My job circuit defines the Vishay SI2374 DS MOSFET which is a surface area install gadget. For this examination I am utilizing the through-hole BS170 rather. The option of n-channel MOSFET is trivial however, for effectiveness purpose you must pick one with a reduced on-state drain-to-source resistance. Much less than 1Ω is quickly discovered.


I selected to execute the firmware as an instance job within my stm32 plus collection. The principles are easy so you must have no problems porting it to whatever structure matches your job. The firmware is carried out in a file that you can see below on Github.

The layout functions by utilizing Timer 1 to create disrupts at a regularity of 180 Hz. Each time the interrupt fires we switch off the number that we were last showing and also carry on to establishing the GPIOs required to light the following number. As a result each number flickers quickly at 180/ 3 = 60 Hz, a number I chose to match the refresh price most frequently utilized by COMPUTER screens. This offers a screen that shows up secure to the human eye.

Right here’s a break down of the fundamental parts of the firmware.

fixed const uint8_t AsciiTable[]= {
0,// ROOM
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,// miss
0b11111100,// 0
0b01100000,// 1
0b11011010,// 2
0b11110010,// 3
0b01100110,// 4
0b10110110,// 5
0b10111110,// 6
0b11100000,// 7
0b11111110,// 8
0b11110110// 9

We intend to permit the controller to present ASCII message strings so we require a table to transform ASCII to a bitmap of which sections must illuminate for that personality. ASCII begins at 32 (area) so we begin our table there.

Each access in the table is a solitary byte with one little bit per lit-up sector in the style ABCDEFG0. Extra ASCII codes are readied to absolutely no. In this instance I just require the numbers 0-9 to make sure that’s all there remains in there. You can quickly see just how to expand this.

enum {
SEGA = 0,// PA0
SEGB = 3,// PA3
SEGC = 8,// PB8
SEGD = 4,// PB4
SEGE = 3,// PB3
SEGF = 1,// PA1
SEGG = 2,// PA2
SEGP = 5,// PB5
DIG1 = 9,// PB9
DIG2 = 2,// PB2
DIG3 = 10// PB10

The pins utilized for each and every GPIO are kept in an enum for very easy recommendation. The relatively arbitrary job matches a task I’m presently dealing with as well as likewise reveals that the pin positioning is entirely versatile.

GpioA> ;
GpioB pb;

All pins are initialised as results. To light a section I will certainly establish the sector outcome and also the equivalent number MOSFET gateway outcome HIGH. Current will certainly stream from the sector outcome GPIO, with the LED and also the MOSFET and also the LED will certainly light. To change a figure off I merely turn off its MOSFET.

/ *
* Initialise timer1 ranging from the broadband interior APB2 (APB on the F0)
* clock with an interrupt attribute

Timer1< Timer1InternalClockFeature, // the timer clock source is APB2 (APB on the F0) Timer1InterruptFeature // gain access to interrupt functionality > timer;

/ *
* Establish ourselves up as a customer for disrupts elevated by the timer course.

TimerInterruptEventSourceSlot:: bind( this, & Timer7SegmentTest:: onInterrupt)

/ *
* Establish an up-down-timer as much as tick at 80 kHz with an auto-reload worth of 444
* The timer will certainly count from 0 to 444 comprehensive, increase an Update interrupt and also
* after that reverse pull back to 0 where it ’ ll raising an additional Update interrupt
* and also begin once more. Each trip from one end to the various other takes 1/180 2nd.

timer.setTimeBaseByFrequency(80000,444, TIM_CounterMode_CenterAligned3);

/ *
* Allow simply the Update interrupt, getting rid of any type of spurious pending flag initially

timer.clearPendingInterruptsFlag( TIM_IT_Update);
timer.enableInterrupts( TIM_IT_Update);

/ *
* Beginning the timer


Establishing the timer in stm32 plus is a straightforward job of proclaiming it with the clock and also disrupt attribute, placing ourselves as a customer to the disrupts, establishing the preferred regularity and after that allowing the outer.

int worth = -1;

for(;;-RRB- {



if( worth >999)
worth = 0;

// equate worth to ascii, left warranted

_ display screen[0]= _ display screen[1]= _ display screen[2]= 0;
StringUtil:: itoa( worth, const_cast( _ display screen), 10);

// wait on 100 ms

MillisecondTimer:: hold-up(100);

The instance code after that enters into a limitless loophole counting up from absolutely no to 999 and after that twisting around and also beginning once more.

/ *
* Client callback feature. This is called when the upgrade disrupt that we ’ ve
* made it possible for is terminated.

space onInterrupt( TimerEventType tet, uint8_t/ * timerNumber */) {


// confirm our assumption

if( tet!= TimerEventType:: EVENT_UPDATE)

// switch off the last number we showed. This requires to be done initially to stay clear of
// turned off sections ending up being faintly noticeable throughout multiplexing

_ numbers[_currentDigit] reset();

// breakthrough to the number we simply established

if( _ currentDigit >= 2) {
_ currentDigit= 0;
_ currentDigitPtr= _ display screen;
_ currentDigit++;

// obtain the personality to present at this setting

uint8_t c= * _ currentDigitPtr++;

// inspect the lower end of the variety

if( c

You May Also Like