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.
Display
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.
Microcontroller
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"}%
Programming
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.
Video
http://thescarydoor.blip.tv/file/2796384/
--
StephenCavilia 2009-11-02