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?

asked Apr 26, 2023 at 8:41
\$\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.

answered Apr 26, 2023 at 9:09
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.