Skip to content

Instantly share code, notes, and snippets.

@agrif
Created February 14, 2021 05:19
Show Gist options
  • Save agrif/69d23f17acd0806b9590321bba3bc6a5 to your computer and use it in GitHub Desktop.
Save agrif/69d23f17acd0806b9590321bba3bc6a5 to your computer and use it in GitHub Desktop.
#include <stdint.h>
#include <mcs51/at89x051.h>
#define OSCILLATOR_FREQ 12000000
// assuming 8-bit counter in timer
#define INTERRUPTS_PER_SECOND (OSCILLATOR_FREQ / ((1 << 8) * 12))
// display multiplexing
#define DISPLAY_FREQ 1000 * 3
#define INTERRUPTS_PER_DISPLAY (INTERRUPTS_PER_SECOND / DISPLAY_FREQ)
#define NUM_DIGITS 3
volatile uint8_t display_digits[NUM_DIGITS] = {0xf, 0xf, 0xf};
volatile uint8_t display_current = NUM_DIGITS;
volatile uint16_t display_counter = INTERRUPTS_PER_DISPLAY;
// buttons
volatile uint8_t button_last = 0;
volatile uint8_t button_pressed = 0;
volatile uint16_t num = 0;
volatile uint8_t counter = 120;
void display(uint16_t val);
void isr_int0(void) __interrupt (0) {
counter--;
if (counter == 0) {
counter = 120;
num++;
}
}
void isr_timer0(void) __interrupt (1) {
display_counter--;
if (display_counter == 0) {
display_counter = INTERRUPTS_PER_DISPLAY;
display_current--;
// sample and debounce buttons
uint8_t button_now = (P1 & 0b01100000) >> 5;
button_pressed |= button_last & ~button_now;
button_last = button_now;
// turn off all digits
P3 |= 0b111000;
// set new display state
P1 &= 0xf0;
P1 |= display_digits[display_current] & 0xf;
// turn on the current digit
P3 &= ~(1 << (3 + display_current));
if (display_current == 0) {
display_current = NUM_DIGITS;
}
}
}
void setup() {
// disable interrupts
EA = 0;
// safe defaults (caps are active low)
// P1 aUDB3210 (adc data, up/down button, buzzer, display out)
P1 = 0b01110000;
// P3 H_321CSa (heat, digit select (low), PSU timing, adc select, adc clk)
P3 = 0b10111110;
// we use timer0 to drive the display multiplexer
// set timer 0 to 8 bit, no prescaler
TMOD = 0x3;
// clear timer
TL0 = 0;
TH0 = 0;
// turn timer on
TR0 = 1;
// enable timer interrupt
ET0 = 1;
// turn on edge-triggered external interrupt 0
IT0 = 1;
EX0 = 1;
// enable interrupts
EA = 1;
}
void display(uint16_t val) {
uint8_t d;
display_digits[0] = val % 10;
val /= 10;
d = val % 10;
display_digits[1] = d ? d : 0xf;
val /= 10;
d = val % 10;
display_digits[2] = d ? d : 0xf;
}
int main() {
setup();
display(num);
while (1) {
if (button_pressed & 0b01) {
// down
button_pressed &= ~0b01;
num--;
}
if (button_pressed & 0b10) {
// up
button_pressed &= ~0b10;
num++;
}
display(num);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment