2
votes

I'm using MikroC for PIC v7.2, to program a PIC18f67k40.

Within functii.h, I have the following variable declaration:

extern volatile unsigned char byte_count;

Within main.c, the following code:

#include <functii.h>
// ...
volatile unsigned char byte_count = 0;
// ...

void interrupt () {
    if (RC1IF_bit) {
        uart_rx = Uart1_read();
        uart_string[byte_count] = uart_rx;    
        byte_count++;
    } 
// ...
}

Then, within command.c, I have the following code:

#include <functii.h> 

void how_many_bytes () {
    // ...
    uart1_write(byte_count);
    // ...
}

In main.c, I process data coming through the UART, using an interrupt. Once the end of transmission character is received, I call how_many_bytes(), which sends back the length of the message that was received (plus the data bytes themselves, the code for which I didn't include here, but those are all OK!!).

The problem is that on the uart1_write() call, byte_count is always 0, instead of having been incremented in the interrupt sequence.

1
Do you have any code resetting byte_count back to zero? Are you sure that doesn't happen? Also, are you sure that the interrupt function is called? And that RC1IF_bit is "true"? - Some programmer dude
I do, but AFTER uart1_write(byte_count);. - Andrei Oniga
A linkage problem would be warned by the compiler (something like "undefined reference to byte_count"). On the other hand, the linker does not mind if the variable is incremented or not, or your condition is executed or not. As the first comment suggested, it looks like the code is not being executed, due to a wrong interrupts/uart configuration, hardware, etc... Set a break-point inside the condition (RC1IF_bit) and see what is going on. - Jose
The "interesting" issue is that reading each value of the uart_string[] array gives the correct bytes values. And since the vector is populated by using byte_count as the index and it's being incremented at each step, then the interrupt must be running correctly. What seems to happen is that byte_count gets reset to 0 somehow, before it's sent back via the UART. - Andrei Oniga
@AndreiOniga It is difficult to help when we don't see a complete minimal example, see stackoverflow.com/help/mcve. Even if we cannot run your example without the corresponding hardware the missing code might be necessary to find your problem. - Bodo

1 Answers

-1
votes

Probably you need some synchronization between the interrupt handler and the main processing.

If you do something like this

if(byte_count != 0) {
    uart1_write(byte_count);
    byte_count = 0;
}

the interrupt can occur anywhere, for example

  1. between if(byte_count != 0)and uart1_write(byte_count); or
  2. during the processing of uart1_write(byte_count); which uses a copy of the old value while the value gets changed or
  3. between uart1_write(byte_count); and byte_count = 0;.

With the code above case 1 is no problem but 2 and 3 are. You would lose all characters received after reading byte_count for the function call.

Maybe you can disable/enable interrupts at certain points.

A better solution might be to not reset byte_count outside of interrupt() but instead implement a ring buffer with separate read and write index. The read index would be modified by how_many_bytes() (or uart1_write()) only and the write index by interrupt() only.