I have this task where I have to use timer interrupts intead of delays (for efficiency purposes) in this 7 segment display circuit with PIC18F4620.
Here is the circuit:
enter image description here Display is common anode.
I would normally write the code like this and the output on the display would be "32.10" but I have to eliminate all the delays:
int dgt[10] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10};
output_high(pin_d7);
output_c(dgt[0]);
output_high(pin_c7);
delay_ms(5);
output_low(pin_d7);
output_high(pin_d6);
output_c(dgt[1]);
output_high(pin_c7);
delay_ms(5);
output_low(pin_d6);
output_high(pin_d5);
output_c(dgt[2]);
output_low(pin_c7);
delay_ms(5);
output_low(pin_d5);
output_high(pin_d4);
output_c(dgt[3]);
output_high(pin_c7);
delay_ms(5);
output_low(pin_d4);
I started to experiment with replacing delays with timer1 interrupt with a LED blinking circuit and that code is something like this:
#define tmr 218
#use fast_io(b)
#int_timer1
void delayy(void)
{
output_toggle(pin_b0);
set_timer1(tmr);
clear_interrupt(INT_timer1);
}
void main()
{
set_tris_b(0x00);
enable_interrupts(INT_timer1);
enable_interrupts(GLOBAL);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(tmr);
while(TRUE);
}
My question is: How can I write that 7 segment display code without any delays and with only timers?
1 Answer 1
You need to move your code from the main loop to interrupt handlers, doing small part of work on each interrupt.
Set timer to generate an interrupt every 5 ms. Then your code, rewritten as a finte-state machine, placed in the interrupt handler would look like this:
void timer_isr()
{
switch(state)
{
case 1:
output_high(pin_d7);
output_c(dgt[0]);
output_high(pin_c7);
state = 2;
break;
case 2:
output_low(pin_d7);
output_high(pin_d6);
output_c(dgt[1]);
output_high(pin_c7);
state = 3;
break;
case 3:
output_low(pin_d6);
output_high(pin_d5);
output_c(dgt[2]);
output_low(pin_c7);
state = 4;
break;
case 4:
output_low(pin_d5);
output_high(pin_d4);
output_c(dgt[3]);
output_high(pin_c7);
state = 5;
break;
case 5:
output_low(pin_d4);
state = 6;
break;
}
//clear interrupt/rearm timer
}
state
is a global variable, declared as volatile
, to prevent optimizing-out all code. Process is started by writing state = 1
. By changing timer configuration on each state-change you can get different delays.