0
\$\begingroup\$

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?

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.