Skip to content

Instantly share code, notes, and snippets.

@tokolist
Last active October 16, 2017 13:25
Show Gist options
  • Save tokolist/ad8e00d3b65e6c978b01 to your computer and use it in GitHub Desktop.
Save tokolist/ad8e00d3b65e6c978b01 to your computer and use it in GitHub Desktop.
Hardware Interrupt and Seven-segment LED Digit Display Controlling Using an AVR Microcontroller http://youtu.be/XkO-7eyUWf8
#define F_CPU 16000000 //16MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
typedef struct {
volatile uint8_t *port;
char pin;
} Segment;
volatile char led_num[] = {0, 0, 0};
void rand_num()
{
int r = round(rand() / (RAND_MAX / 999));
led_num[0] = floor(r/100);
r = r - led_num[0]*100;
led_num[1] = floor(r/10);
r = r - led_num[1]*10;
led_num[2] = r;
}
ISR(INT0_vect)
{
cli();
rand_num();
sei();
}
int main(void)
{
Segment segm[] {
{&PORTC, PC5}, //A
{&PORTD, PD1}, //B
{&PORTC, PC4}, //C
{&PORTC, PC2}, //D
{&PORTC, PC0}, //E
{&PORTD, PD0}, //F
{&PORTC, PC1}, //G
{&PORTC, PC3}, //DP
};
Segment digit[] {
{&PORTD, PD6}, //1
{&PORTB, PB0}, //2
{&PORTD, PD7}, //3
};
//set output pins
DDRC = (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3) | (1<<DDC4) | (1<<DDC5);
DDRB = (1<<DDB0);
DDRD = (1<<DDD0) | (1<<DDD1) | (1<<DDD6) | (1<<DDD7);
PORTD |= (1<<PD2); //PullUp
GICR |= (1<<INT0); //Enable interruption
MCUCR |= (1<<ISC01); //falling edge
rand_num();
sei();
while(1)
{
int s = sizeof(segm)/sizeof(Segment);
int s2 = sizeof(digit)/sizeof(Segment);
for(int n=0; n < s2; n++)
{
for(int m=0; m < s2; m++)
{
*digit[m].port &= ~(1<<digit[m].pin);
}
char mask = 0;
switch(led_num[n])
{
case 0: mask = 0b11111100; break;
case 1: mask = 0b01100000; break;
case 2: mask = 0b11011010; break;
case 3: mask = 0b11110010; break;
case 4: mask = 0b01100110; break;
case 5: mask = 0b10110110; break;
case 6: mask = 0b10111110; break;
case 7: mask = 0b11100000; break;
case 8: mask = 0b11111110; break;
case 9: mask = 0b11110110; break;
default: mask = 0; break;
}
for(int i=0; i < s; i++)
{
char bit = mask & (1 << (s-i-1));
if(bit)
{
*segm[i].port &= ~(1<<segm[i].pin);
}
else
{
*segm[i].port |= (1<<segm[i].pin);
}
}
*digit[n].port |= (1<<digit[n].pin);
_delay_ms(1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment