Проблема с переменной extern при компиляции? - PullRequest
0 голосов
/ 11 января 2019

Я использую MikroC для PIC v7.2, чтобы запрограммировать PIC18f67k40.

В functii.h у меня есть следующее объявление переменной:

extern volatile unsigned char byte_count;

В пределах main.c , следующий код:

#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++;
    } 
// ...
}

Затем в command.c у меня есть следующий код:

#include <functii.h> 

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

В main.c я обрабатываю данные, поступающие через UART, используя прерывание. Как только получен символ окончания передачи, я вызываю how_many_bytes(), который возвращает длину полученного сообщения (плюс сами байты данных, код, который я здесь не включил, но все в порядке! !).

Проблема в том, что при вызове uart1_write() byte_count всегда равно 0, а не увеличивается в последовательности прерываний.

1 Ответ

0 голосов
/ 11 января 2019

Возможно, вам нужна синхронизация между обработчиком прерываний и основной обработкой.

Если вы делаете что-то подобное

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

прерывание может произойти где угодно, например

  1. между if(byte_count != 0) и uart1_write(byte_count); или
  2. во время обработки uart1_write(byte_count);, которая использует копию старого значения, пока значение изменяется, или
  3. между uart1_write(byte_count); и byte_count = 0;.

С кодом выше случай 1 не проблема, но 2 и 3 есть. Вы потеряете все символы, полученные после прочтения byte_count для вызова функции.

Возможно, вы можете отключить / включить прерывания в определенных точках.

Лучшим решением может быть не сброс byte_count вне interrupt(), а реализация кольцевого буфера с отдельным индексом чтения и записи. Индекс чтения будет изменен только на how_many_bytes() (или uart1_write()), а индекс записи - только на interrupt().

...