Почему я не могу прочитать флаг прерывания из моего основного цикла? - PullRequest
0 голосов
/ 27 февраля 2019

Я пишу код для микроконтроллера stm32l011, и сейчас он должен выполнить одну базовую задачу - дождаться определенного байта (заданного мной) из UART и после "\ r \ n" или "\ n \ r"последовательность.Если он получает это, он устанавливает нулевой указатель на адрес предопределенного символа, который читается и обрабатывается в основном цикле.

    volatile uint8_t uart_buff[UART_BUFF_LEN] = {'\0'};
    volatile uint8_t *uart_data = NULL;
    volatile uint8_t *uart_stack = uart_buff+2;

    void USART2_IRQHandler(void){
        if(LL_USART_IsActiveFlag_RXNE(USART2)){
            *uart_stack = LL_USART_ReceiveData8(USART2);
            user_uart_send_byte(*uart_stack);

            //same as if(!(strcmp((uart_stack-1), "\r\n") || strcmp((uart_stack-1), "\n\r")))
            if((*uart_stack == '\r' || *uart_stack == '\n') && (*(uart_stack-1) == '\r' || *(uart_stack-1) == '\n'))
            {
                uart_data = uart_stack - 2;
                uart_stack = uart_buff+2;
            }

            uart_stack++;
        }
    }

и main:

    extern volatile uint32_t systick_counter_ms;
    extern volatile uint8_t *uart_data;

    int main(void){

        init();

        while(1)
        {
            LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_3);
            //delay_ms(1); //without that it doesn't want to work
            if(uart_data)
            {
                adc_transmit_reading(*uart_data);
                uart_data = NULL;
            }
        }
    }

Iнаписал программу на C выше, и это не похоже на работу.Но когда я ввел задержку в основной цикл, она просто волшебным образом возникла.Это почему?Ключевые моменты, на которые следует обратить внимание: от UART есть эхо, так что я уверен, что оно правильно обрабатывает прерывания в обоих случаях, а также я попытался удалить оптимизации компилятора (который оптимизирует размер (Os)) с помощью изменчивых переменных.Кроме того, задержка выполняется циклом while, который ожидает прерывание, которое увеличивает переменную каждую миллисекунду.

Мое дилетантское предположение состоит в том, что, поскольку я зацикливаюсь только вокруг этого указателя uart_data, синхронизация между прерыванием и основным циклом так или иначе не выполняется.не происходит.

Заранее спасибо:)

1 Ответ

0 голосов
/ 27 февраля 2019

Проблема в том, что вы указали, что ваш uart_data указывает на изменчивые данные.Но в вашем цикле вы проверяете указатель, а не данные.

Таким образом, вы должны указать, что ваш указатель также является энергозависимым:

extern volatile uint8_t * volatile uart_data;

Более подробную информацию вы можете найти в этом посте: Почему указатель указывает на переменную, например"volatile int * p", полезно?

...