AVR Digital Counter

%IMAGE{"counter-75.jpg" type="frame" align="right" size="300"}%

This project is a simple board that displays numbers counting from 00 to 99 on a 7-segment LED display using an AtmelAVR microcontroller.


The 2-digit 7-segment display is made from discrete 5mm red LEDs, using 2 per segment for a total of 28 lights. Segments within each digit are connected with a common cathode, and corresponding segments of all digits are connected to common anodes. The 7 segment anodes and 2 digit cathodes are connected to MCU digital output pins, allowing any light to be powered by pulling its segment line high and digit line low. By scanning across the digits at high speed, all digits appear to be continuously lit.

Building the Display

To make the 7-segment display, start with a piece of .1" grid perfboard and 14 standard 5mm radial LEDs. Push the LEDs through the board (TODO: picture) with leads in horizontal segments oriented vertically and in vertical segments oriented horizontally. Solder all cathodes of the digit together, leaving one lead at the bottom to connect to an MCU pin. Solder the two anode leads from each segment together and bend one to the side, keeping the leads from the side segments vertically separated. When adding extra digits, connect the segment anodes to the corresponding leads from all existing digits, and keep a common cathode for each digit. The final display will have 7 segment anodes shared across all digits and one cathode per digit.


The microcontroller is an Atmel AVR ATmega88P in a 28-pin DIP package. The onboard 8 MHz RC oscillator is used, so not external crystal is required.

I/O Connections

  • PORTD:6-0 is connected to the display segment lines.
  • PORTC:1-0 is connected to the display digit lines.
  • RESET, SCK, MISO and MOSI are connected to a 6-pin ISP header for programming the MCU while on the board.

Board Schematic

%IMAGE{"avrcounter.png" type="frame" align="center" size="600"}%


The program is written using avr-libc and the avr-gcc C compiler.

%CODE{lang="c"}% #include <avr/io.h> #define F_CPU 800000L #include <util/delay.h>

void set_digit(uint8_t digit, uint8_t value) { PORTD = 0x00; switch (digit) { case 1: PORTC = 0x02; break; case 2: PORTC = 0x01; }

switch (value) { case 0: PORTD = 0x77; break; case 1: PORTD = 0x24; break; case 2: PORTD = 0x5D; break; case 3: PORTD = 0x6D; break; case 4: PORTD = 0x2E; break; case 5: PORTD = 0x6B; break; case 6: PORTD = 0x7B; break; case 7: PORTD = 0x25; break; case 8: PORTD = 0x7F; break; case 9: PORTD = 0x6F; } }

int main() {

uint8_t d1, d2, i;

DDRC = 0x03; DDRD = 0x7F; PORTC = 0x00;

while (1) { for (d1=0; d1<10; d1++) { for (d2=0; d2<10; d2++) { for (i=0; i<60; i++) { set_digit(1, d1); _delay_ms(5); set_digit(2, d2); _delay_ms(5); } } } }

return 0; } %ENDCODE%

Full source code in avr-apps git repository.



-- StephenCavilia 2009-11-02

ProjectForm edit

Name AVR Digital Counter
Summary A digital counter using an AVR micocontroller and 7-segment LED display
Components AtmelAVR, SevenSegmentDisplay
Difficulty Intermediate
Author StephenCavilia
Topic attachments
I Attachment Action Size Date Who Comment
avrcounter.pngpng avrcounter.png manage 79 K 06 Nov 2009 - 21:40 StephenCavilia  
avrcounter.schsch avrcounter.sch manage 9 K 06 Nov 2009 - 21:38 StephenCavilia AVR digital display
avrtemp.schsch avrtemp.sch manage 9 K 06 Nov 2009 - 21:35 StephenCavilia AVR thermometer
counter-75.jpgjpg counter-75.jpg manage 510 K 07 Nov 2009 - 03:52 StephenCavilia photo of counter display
Topic revision: r9 - 05 Dec 2009, StephenCavilia
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding CodenamePending? Send feedback