const byte datapin = PB5;
const byte clockpin = PB4;
const byte latchpin = PB3;
const byte digits = 8;
volatile uint8_t isr_buffer[digits];
volatile uint8_t isr_digit = 0;
// which pin on the 1st shift register illuminates which digit?
uint8_t digit_pin_map[digits] = {
1<<7, 1<<0, 1<<1, 1<<2,
1<<6, 1<<3, 1<<4, 1<<5
};
SIGNAL(TIM0_COMPA_vect) {
shiftOut(datapin, clockpin, LSBFIRST, isr_buffer[isr_digit]);
shiftOut(datapin, clockpin, LSBFIRST, digit_pin_map[isr_digit]);
digitalWrite(latchpin, HIGH);
digitalWrite(latchpin, LOW);
if (++isr_digit == sizeof(isr_buffer))
isr_digit = 0;
}
void setup() {
pinMode(datapin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(latchpin, OUTPUT);
// piggy back on the existing Timer0
OCR0A = 0xAF;
TIMSK |= _BV(OCIE0A);
}
void loop() {
uint32_t n = 0;
while (1) {
write_7seg(n++, 16);
}
}
// which pin on the 2nd shift register illuminates which segment?
enum SegmentBits {
seg_a = 0b10000000, seg_b = 0b00100000, seg_c = 0b00001000,
seg_d = 0b00000010, seg_e = 0b00000001, seg_f = 0b01000000,
seg_g = 0b00010000, seg_dp = 0b00000100
};
const uint8_t segment_map[] = {
seg_a | seg_b | seg_c | seg_d | seg_e | seg_f, // 0
seg_b | seg_c, // 1
seg_a | seg_b | seg_g | seg_e | seg_d, // 2
seg_a | seg_b | seg_g | seg_c | seg_d, // 3
seg_f | seg_g | seg_b | seg_c, // 4
seg_a | seg_f | seg_g | seg_c | seg_d, // 5
seg_a | seg_f | seg_e | seg_d | seg_c | seg_g, // 6
seg_a | seg_b | seg_c, // 7
seg_a | seg_b | seg_c | seg_d | seg_e | seg_f | seg_g, // 8
seg_a | seg_b | seg_c | seg_d | seg_f | seg_g, // 9
seg_e | seg_f | seg_a | seg_b | seg_c | seg_g, // A
seg_f | seg_e | seg_d | seg_c | seg_g, // b
seg_g | seg_e | seg_d, // c
seg_g | seg_e | seg_d | seg_c | seg_b, // d
seg_a | seg_f | seg_g | seg_e | seg_d, // E
seg_a | seg_f | seg_g | seg_e, // F
};
// base can be 2 to 16.
void write_7seg(uint32_t num, uint8_t base) {
for (uint8_t i = 0; i < digits; i++) {
byte digit = num % base;
num /= base;
isr_buffer[i] = ~segment_map[digit];
}
// overflow? set all the decimal points
if (num != 0) {
for (uint8_t i = 0; i < digits; i++)
isr_buffer[i] ^= seg_dp;
}
}