#include <avr/io.h>
#include <avr/interrupt.h>
#define VAL_DIGITS 5
#define MAX_DISP_VAL 99999
#define DISP_DIGITS VAL_DIGITS + 1
#define DISP_CYCLE_PACE 200UL // Cycle each group every second
#define beaconPin 8
const uint8_t segLUT[10] = {
0b00111111, // 0 : a b c d e f -
0b00000110, // 1 : - b c - - - -
0b01011011, // 2 : a b -d e - g
0b01001111, // 3 : a b c d - - g
0b01100110, // 4 : - b c - - f g
0b01101101, // 5 : a - c d - f g
0b01111101, // 6 : a - c d e f g
0b00000111, // 7 : a b c - - - -
0b01111111, // 8 : a b c d e f g
0b01101111 // 9 : a b c d - f g
};
const uint8_t BLANK = 0b00000000;
uint8_t digit[DISP_DIGITS] = {0};
// Variable pour compter les afficheurs
volatile uint8_t currentDigitIndex = 0;
volatile uint8_t digitBit = 1;
volatile uint32_t displayValue = 0;
uint32_t nextValueTick = 0;
void uint32_to_uint8_Digits(uint32_t value, uint8_t *digits) {
if (value < MAX_DISP_VAL) { // Check for Overflow
for (uint8_t index = 0; index < VAL_DIGITS; index++) {
digits[index] = (value? segLUT[value % 10] : BLANK);
value /= 10;
}
}
else { // Overflow, return 99999
for (uint8_t index = 0; index < VAL_DIGITS; index++) {
digits[index] = segLUT[9]; // Could be '-' (0b01000000) as well
}
}
digits[2] |= 0b10000000; // Diplay the dot
}
void setup() {
// put your setup code here, to run once:
pinMode(beaconPin, OUTPUT);
digitalWrite(beaconPin, LOW);
// Désactive les interruptions pendant la configuration
cli();
// Réinitialise le registre de contrôle du Timer1
TCCR1A = 0;
TCCR1B = 0;
// Configure le Timer1 en mode CTC
TCCR1B |= (1 << WGM12);
// Préscaler de 64
TCCR1B |= (1 << CS11) | (1 << CS10);
// Valeur de comparaison pour 2 ms
OCR1A = 499;
// Active l'interruption sur comparaison
TIMSK1 |= (1 << OCIE1A);
// Réactive les interruptions globales
sei();
DDRD = 0xFF; // Toutes les broches du port D en sortie
PORTD = segLUT[0];
DDRC = 0x3F; // 0x3F = 0b00111111 (C0 à C5 en sortie, C6 et C7 inchangés)
PORTC = (PORTC | 0b00111111) & ~digitBit;
}
ISR(TIMER1_COMPA_vect) {
static uint8_t currentDigit = 0;
PORTC |= 0b00111111; // Clear all digits first
PORTD = currentDigit;
PORTC = (PORTC | 0b00111111) & ~digitBit;
if (++currentDigitIndex == DISP_DIGITS) {
currentDigitIndex = 0;
digitBit = 1;
}
else {
digitBit <<= 1;
}
currentDigit = digit[currentDigitIndex];
digitalWrite(beaconPin, !digitalRead(beaconPin)); // Blink if alive!
}
void loop() {
uint32_t now = millis();
if (nextValueTick < now) {
nextValueTick += DISP_CYCLE_PACE;
displayValue += 1;
uint32_to_uint8_Digits(displayValue, digit);
}
}