[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Something I don't understand (loops and interrupts)
From: |
BERTRAND Joël |
Subject: |
Something I don't understand (loops and interrupts) |
Date: |
Fri, 3 Apr 2020 10:28:28 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 SeaMonkey/2.53.1 |
Hello,
I'm trying to use avr-gcc to write a trivial firmare and my code
doesn't run as expected. I have tried to find a solution without any result.
My current source code is available on
https://hilbert.systella.fr/test.tar.gz
I have designed a PCB with an ATmega1284. On this board, I have
soldered 10 leds to debug an external sensor and I have written a piece
of code to turn on these leds. These leds are switched off by an
interrupt after 1/5th of second.
Each led is associated to a struct:
typedef volatile struct
{
volatile uint8_t *port;
volatile uint8_t *pin;
volatile uint8_t bitNo;
volatile int8_t timer;
} gpio_t;
enum { i_work = 0, i_wait, i_meas_in_progress, i_meas_ready,
i_send_data, i_watchdog_reset, i_comm_rx, i_comm_tx, i_comm_ok,
i_irq, i_max};
static gpio_t i_led[i_max] =
{
{ &PORTD, &PIND, 3, 0 },
{ &PORTD, &PIND, 4, 0 },
{ &PORTD, &PIND, 5, 0 },
{ &PORTD, &PIND, 6, 0 },
{ &PORTD, &PIND, 7, 0 },
{ &PORTB, &PINB, 0, 0 },
{ &PORTB, &PINB, 1, 0 },
{ &PORTB, &PINB, 2, 0 },
{ &PORTB, &PINB, 3, 0 },
{ &PORTB, &PINB, 4, 0 }
};
I don't understant why some leds are switched off and why some others
leds aren't! Thus, I have tried to debug TIMER1_COMPA_vect. In this
interrupt, I have written:
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
{
uint8_t i;
interrupt_counter = (interrupt_counter + 1) % 25;
if (interrupt_counter == 0) // 1 s
{
gpio_toggle(&i_led[i_work]);
}
// Switch debug leds off
for(i = 0; i < i_max; i++)
{
if (interrupt_counter == 0) serial_send_byte(i);
if (i_led[i].timer > 0)
{
i_led[i].timer--;
if (i_led[i].timer == 0)
{
gpio_off(&i_led[i]);
}
}
}
return;
}
serial_send_byte is a trivial function:
void
serial_send_byte(uint8_t byte)
{
while(!(UCSR0A & (1 << UDRE0)));
UDR0 = byte;
gpio_on(&i_led[i_comm_tx], 5);
return;
}
MCU enters in this interrupt (25 times each second). I have checked
that gpio_toggle(&i_led[i_work]) generates 1 Hz signal. But I don't
understand why for(i = 0; i < i_max; i++) doesn't run as expected. I
obtain on serial line (115200, 8N1):
10:23:00: 7
10:23:00: 8
10:23:00: 9
10:23:00: 4
10:23:01: 5
10:23:01: 6
10:23:01: 7
10:23:01: 8
10:23:01: 9
10:23:01: 4
10:23:02: 5
10:23:02: 6
10:23:02: 7
10:23:02: 8
10:23:02: 9
10:23:02: 0
10:23:03: 4
10:23:03: 5
10:23:03: 6
10:23:03: 7
10:23:03: 8
10:23:03: 9
10:23:03: 4
10:23:04: 5
10:23:04: 6
10:23:04: 7
10:23:04: 8
10:23:04: 9
10:23:04: 4
10:23:05: 5
10:23:05: 6
10:23:05: 7
10:23:05: 8
10:23:05: 9
Value of i_max: 10. But why i doesn't contains values between 0 and 3 ?
Best regards,
JB
- Something I don't understand (loops and interrupts),
BERTRAND Joël <=