Print this Post

Directly Driving 7-Segment Display with AVR IO Pins

I came across the need for a quick and dirty display to show a 4 digit number from a microcontroller. The right way to do this would be to use a microcontroller in combination with a collection of transistors and current limiting resistors, or even a dedicated 7-segment LED driver IC. The wrong way to do this is to wire LEDs directly to microcontroller IO pins to source and sink current way out of spec of the microcontroller… and that’s exactly what I did! With no current limiting resistors, the AVR is sourcing and sinking current potentially far out of spec for the chip. But, heck, it works! With 2 components (just a microcontroller and a 4 digit, 7-segment LED display) and a piece of ribbon cable, I made something that used to be a nightmare to construct (check out this post from 3 years ago when I accomplished the same thing with a rats nest of wires - it was so much work that I never built one again!) The hacked-together method I show today might not be up to spec for medical grade equipment, but it sure works for my test rig application, and it’s easy and cheap to accomplish… as long as you don’t mind breaking some electrical engineering rules. Consider how important it is to know how to hack projects like this together: Although I needed this device, if it were any harder, more expensive, or less convenient to build, I simply wouldn’t have built it! Sometimes hacking equipment together the wrong way is worth it.


Segments are both current sourced and sunk directly from AVR IO pins. Digits are multiplexed with 1ms illumination duration. I don’t really have a part number for the component because it was a China eBay special. The display was $6.50 for 4 (free shipping). That’s ~$1.65 each. The microcontroller is ~$1.

SCHEMATIC? If you want it, read this.common cathode 7 segment display lcd It’s so simple I don’t feel like making it. Refer to an ATMega48 pin diagram. The LCD is common anode (not common cathode), and here’s the schematic on the right. I got it from eBay (link) for <$2.  The connections are as follows:

  • Segments (-) A…H are directly wired to PD0…PD7
    - I call the decimal point (dp) segment “H”
    - I don’t use current limiting resistors. I’m not making a consumer product. It works fine, especially multiplexed. Yeah I could use transistors and CLRs to drive the segments to have them bright and within current specifications, but I’m not building an airplane or designing a pacemaker, I’m making a test device at minimum cost! Direct LED wiring to my microcontroller is fine for my purposes.
    - I am multiplexing the characters of my display. I could have used a driver IC to simplify my code and eliminate the current / wiring issues described above. A MAX7219 or MAX7221 would have been easy choices for this (note common anode vs. common cathode drivers / displays). It adds an extra $5 to my project cost though, so I didn’t go with a driver. I drove the segments right out of my IO pins.
  • Characters (+) 1…4 are PC0…PC3
  • Obviously I apply +5V and GND to the appropriate AVR pins

Here it all is together in my microcontroller programming set up. I’ll place this device in a little enclosure and an an appropriate BNC connector and either plan on giving it USB power or run it from 3xAA batteries. For now, it works pretty darn well on the breadboard.

Here is my entire programming setup. On the top left is my eBay special USB AVR programmer. On the right is a little adapter board I made to accomodate a 6 pin ISP cable and provide a small breadboard for adding programming jumpers into a bigger breadboard. The breadboard at the bottom houses the microcontroller and the display. No other components! Well, okay, a 0.1uF decoupling capacitor to provide mild debouncing for the TTL input.

Here is my entire programming setup. On the top left is my eBay special USB AVR programmer. On the right is a little adapter board I made to accomodate a 6 pin ISP cable and provide a small breadboard for adding programming jumpers into a bigger breadboard. The breadboard at the bottom houses the microcontroller and the display. No other components! Well, okay, a 0.1uF decoupling capacitor to provide mild debouncing for the TTL input.

Let’s talk about the code. Briefly, I use an infinite loop which continuously displays the value of the volatile long integer “numba”. In the display function, I set all of my segments to (+) then momentarily provide a current sink (-) on the appropriate digit anode for 1ms. I do this for each of the four characters, then repeat. How is the time (the value of “numba”) incremented? Using a hardware timer and its overflow interrupt! It’s all in the ATMega48 datasheet, but virtually every microcontroller has some type of timer you can use to an equivalent effect. See my earlier article “Using Timers and Counters to Clock Seconds” for details. I guess that’s pretty much it! I document my code well enough below that anyone should be able to figure it out. The microcontroller is an ATMega48 (clocked 8MHz with an internal RC clock, close enough for my purposes).

#define F_CPU 8000000UL // 8mhz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

// for simplicity, define pins as segments
#define A (1<<PD0)
#define B (1<<PD1)
#define C (1<<PD2)
#define D (1<<PD3)
#define E (1<<PD4)
#define F (1<<PD5)
#define G (1<<PD6)
#define H (1<<PD7)

void setDigit(char dig){ // set the digit starting at 0
	PORTC=(1<<dig)|(1<<PC4); // always keep the PC4 pin high

void setChar(char c){
	// given a number, set the appropraite segments
		case 0:	DDRD=A|B|C|D|E|F;	break;
		case 1:	DDRD=B|C;			break;
		case 2:	DDRD=A|B|G|E|D;		break;
		case 3: DDRD=A|B|G|C|D;		break;
		case 4: DDRD=F|G|B|C;		break;
		case 5: DDRD=A|F|G|C|D;		break;
		case 6: DDRD=A|F|G|E|C|D;	break;
		case 7: DDRD=A|B|C;			break;
		case 8: DDRD=A|B|C|D|E|F|G;	break;
		case 9: DDRD=A|F|G|B|C;		break;
		case 31: DDRD=H;			break;
		default: DDRD=0; 			break;

void flashNumber(long num){
	char i;

	for (i=0;i<4;i++){
		if (i==2){DDRD|=H;} // H is the decimal point
		_delay_ms(1); // time to leave the letter illuminated

volatile long numba = 0;
volatile long addBy = 1;

ISR(PCINT1_vect){ // state change on PC4
	if ((PINC&(1<<PC4))==0) {addBy=0;} // pause
	else {numba=0;addBy=1;} // reset to 0 and resume

	TCNT1=65536-1250; // the next overflow in 1/100th of a second
	numba+=addBy;	  // add 1 to the secound counter

int main(void)
	DDRC=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3); // set all characters as outputs
	DDRD=255;PORTD=0; 	// set all segments as outputs, but keep them low

	TCCR1B|=(1<<CS11)|(1<<CS10); // prescaler 64
	TIMSK1|=(1<<TOIE1); //Enable Overflow Interrupt Enable
	TCNT1=65536-1250;   // the next overflow in 1/100th of a second

	// note that PC4 (PCINT12) is an input, held high, and interrupts when grounded	
	PCICR |= (1<<PCIE1); // enable interrupts on PCING13..8 -> PCI1 vector
	PCMSK1 |= (1<<PCINT12); // enable PCINT12 state change to be an interrupt
	sei(); // enable global interrupts

	for(;;){flashNumber(numba);} // just show the current number repeatedly forever

I edit my code in Notepad++ by the way. To program the chip, I use a bash script…

avr-gcc -mmcu=atmega48 -Wall -Os -o main.elf main.c -w
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avrdude -c usbtiny -p m48 -F -U flash:w:"main.hex":a -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m

Nothing here is groundbreaking. It’s simple, and convenient as heck. Hopefully someone will be inspired enough by this write-up that, even if they don’t recreate this project, they’ll jump at the opportunity to make something quick and dirty in the future. It’s another example that goes to show that you don’t have to draw schematics, run simulations, do calculations and etch boards to make quick projects. Just hack it together and use it.

Update a two days later… I found a similarly quick and dirty way to package this project in an enclosure. I had on hand some 85x50x21mm project boxes (eBay, 10 for $14.85, free shipping, about $1.50 each) so I used a nibbler to hack out a square to accomodate the display. After a little super glue, ribbon cable, and solder, we’re good to go!

Related reading for the technically inclined:


About the author

Scott W Harden

Scott Harden has had a lifelong passion for computer programming and electrical engineering, and recently has become interested in its relationship with biomolecular sciences. He has run a personal website since he was 15, which has changed names from HardenTechnologies.com, to KnightHacker.com, to ScottIsHot.com, to its current SWHarden.com. Scott has been in college for 10 years, with 3 more years to go. He has an AA in Biology (Valencia College), BS in Cell Biology (Union University), MS in Molecular Biology and Microbiology (University of Central Florida), and is currently in a combined DMD (doctor of dental medicine) / PhD (neuroscience) program through the collaboration of the College of Dentistry and College of Medicine (Interdisciplinary Program in Biomedical Science, IDP) at the University of Florida in Gainesville, Florida. In his spare time Scott builds small electrical devices (with an emphasis on radio frequency) and enjoys writing cross-platform open-source software.

Permanent link to this article: http://www.SWHarden.com/blog/2014-02-27-directly-driving-7-segment-display-with-avr-io-pins/


  1. Sherry

    Good info. Lucky me I ran across your blog by accident (stumbleupon).
    I’ve saved as a favorite for later!

  2. Dave

    Good to see you posting again… Miss your Youtube vids!

  3. Angel

    Good to hear from you again Scott. Seeing your post… You are fit !

  4. Bogdan

    Scott, the technique is rather known. It works even better for AVRs because they have higher current driver, I was surprised of the difference when moving an old project from a PIC to AVR.
    But you need to take into account its limitations, specially given that the high current that goes through your ground pin it will shift from your ideal one. This affects things like ADC, Browout.

    Also the current is not that much higher, look at the output voltage vs current in the datasheet(pin drive strength). With something like 2V drop on the LED and 1.5V drop on each of the driving pins, you don’t get even 60mA. So, even the one driving a digit with 1/4 duty cycle will not go over the 40mA limit, on average.

  5. Md. Saiful Islam

    Hello brother,
    This code is not working with protues. Massage: invalid opcode 0xFFFF at PC=0×1002

  6. http://www.adventuresofayorkshiremum.co.uk

    Hey! This post couldn’t be written any better!
    Reading this post reminds me of my old room mate! He always kept chatting about this.

    I will forward this write-up to him. Pretty sure he will have a good read.
    Many thanks for sharing!

  7. Furniture Bürstadt

    Good day! I could have sworn I’ve been to this site
    before but after checking through some of the post I realized it’s
    new to me. Anyways, I’m definitely glad I found it and I’ll be bookmarking and checking back

  8. real estate apps free

    I was recommended this website by way of my cousin. I am not
    certain whether or not this publish is written by him as no one else recognise such certain approximately my difficulty.
    You are amazing! Thank you!

  9. designspiration

    For newest news you have to visit internet and on the web I found this web
    site as a best site for latest updates.

  10. Ralph Doncaster

    It’s even easier to wire up if you piggyback the LED display on top of the AVR:
    I like your code better though because it’s a lot easier to understand how it drives the LED display.
    Besides the t2313/4313, this technique will work with a t44/84. If you don’t need the decimal point you can leave reset enabled, as pin 3 would line up with pin 4 (reset) of the t84.

    I got a pack of 5 with the same pinout for $2.32:

  11. gardena gartengeräte

    Hi it’s me, I am also visiting this site on a regular
    basis, this web page is in fact good and the viewers are in
    fact sharing good thoughts.

  12. b&q diy

    As the admin of this web site is working, no uncertainty very rapidly it will be
    famous, due to its feature contents.

  13. decorative luggage on wheels

    I am really impressed with your writing skills as well as with
    the layout on your blog. Is this a paid theme or did you modify it
    yourself? Either way keep up the excellent quality writing, it is rare
    to see a great blog like this one these days.

  14. Indira

    I’m no longer certain where you’re getting your information, but good topic.

    I must spend a while learning more or figuring out more.
    Thanks for magnificent info I used to be
    searching for this information for my mission.

  15. home alone

    I almost never leave responses, but i did a few searching and wound up here Directly Driving 7-Segment Display with AVR IO Pins

  16. diy beauty

    Thanks for another informative blog. Where else could I get that kind of information
    written in such an ideal approach? I’ve a undertaking that I’m simply now
    operating on, and I’ve been on the look out for such

  17. http://www.littlehomeblessings.com/?p=7536

    Do you have a spam problem on this site; I also am a blogger,
    and I was wanting to know your situation; many of us
    have created some nice methods and we are looking to swap strategies with other folks, why not
    shoot me an e-mail if interested.

  18. Stem cell For Heart News

    I’d like to find out more? I’d want to find out some additional information.

    my web-site; Stem cell For Heart News

  19. mesenchymal stem cell markers

    Your method of telling everything in this piece of writing is truly nice, all be able to simply be aware of it, Thanks a lot.

    Here is my webpage; mesenchymal stem cell markers

  20. stem cell therapy guidelines

    Thank you, I have just been searching for information about this topic for a
    while and yours is the best I have came upon till now.
    But, what concerning the conclusion? Are you sure about the supply?

    Visit my site … stem cell therapy guidelines

  21. Room Unique Shop

    It iss really a nice and useful piece of information. I am happ that you
    simply shared this helpful info wiith us. Please stay us informed like this.
    Thank you for sharing.

  22. escort for hire

    Thank you for the good writeup. It in truth was once a leisure account it.
    Glance advanced to far introduced agreeable from you!
    By the way, how could we communicate?

  23. Stem cell transplantation side effects

    Greetings! Very helpful advice within this post!
    It’s the little changes which will make the most important changes.
    Thanks for sharing!

    Review my page: Stem cell transplantation side effects

  24. hobbies for women

    Now I am ready tto do my breakfast, later than having
    my breakfast coming yet again to read other

  25. Parthenia

    Remarkable things here. I am very satisfied tto look yourr post.

    Thank you a lot and I’m taking a look forward to contact you.
    Will you please drop me a mail?

  26. sims freeplay hack cydia

    Definitely believe that whiich you said. Your favourrite reason swemed to be on tthe wweb the simplest
    facctor to be mindful of. I say to you, I certainly get irked at the same time as folks
    think about iswues that they plainly do not recognise
    about. Youu managed to hit the nail upon the highest and also outlined out the whole
    thimg with no need side-effects, other folks could take a signal.
    Will probably bbe agsin to get more. Thank you

  27. 14 19 casual canine

    Very quickly this web site will be famous amid all blogging and site-building viewers, due to it’s
    fastidious articles

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>