AVR Xmega USART проблема чтения полной строки - PullRequest
0 голосов
/ 26 сентября 2018

У меня какая-то проблема и странное поведение при попытке прочитать полную строку.Я использую самодельную демонстрационную плату, оснащенную ATXMEGA32A4U, и в основном я хотел бы установить параметр (заданное значение выходного напряжения) через последовательную связь, в то время как MCU делает свое дело (управляет понижающим преобразователем и отправляет обратно через последовательный интерфейс).данные как напряжение и ток).Давайте посмотрим на код: здесь у нас есть основная функция

int main(void)
{   
osc_init();
PORTC_OUTSET = PIN7_bm; //Let's make PC7 as TX
PORTC_DIRSET = PIN7_bm; //TX pin as output

PORTC_OUTCLR = PIN6_bm;
PORTC_DIRCLR = PIN6_bm; //PC6 as RX

adc_init();
timer_init();
timer1_init();              //init all the peripheral
Serial_init();
stdout = stdin = &usart_str;

char l[100];


while (1) 
{

    if(!((USARTC1_STATUS & USART_RXCIF_bm)==0))
    {
        printf("**MAIN**\n");
        uart_getstring(l);
        printf("**DIGITATO %s **\n ",l);
    }
    printf("tensione: %f V corrente: %f A\n",v_bat,cur);
}

}

Как вы можете видеть во внешнем цикле while, я просто отправляю данные обратно с помощью функции printf (которая работает очень хорошо и дает мне хорошую отформатированную строку дляотображать в последовательном мониторе, как Arduino Ide).Вложенный цикл начинается, когда обнаруживается установленный флаг USART_RXCIF, означающий, что входящий буфер ожидает чтения.Затем он вызывает функцию uart_getstring (), которая здесь у нас есть:

void uart_getstring(char* line)
{   
int z=0;

while( !(USARTC1_STATUS & USART_RXCIF_bm) ); //Wait until data has been received.

char data='a';

while((data!='\r')){

        while( !(USARTC1_STATUS & USART_RXCIF_bm) );

        data = USARTC1_DATA; //Temporarly store received data
        printf("**GOT** %d carattere %c \n",z,data);

        line[z] = data;
        z++;

    }
    line[z]='\0';   
}

Обратите внимание, что все элементы управления были сделаны в функции ISR, а последовательный процесс выполняется в основном цикле без прерывания usart.Однако я также попытался отключить все остальные процессы и запустить только основную функцию в одиночку, но получил ту же проблему

Так что я попытался сделать это с помощью последовательного монитора arduino ide, который позволяет мне отправлять команду на доску и получать ответ обратно,Что бывает сложно, если я отправляю строку только 1 или 2 символа, она работает отлично!Но если я отправляю более длинную строку, она терпит неудачу, она просто отправляет мне обратно строку, так как в ней было всего 2 символа.Давайте посмотрим на некоторый пример:

>> a
<<
**MAIN**
**GOT** 0 carattere a 
**GOT** 1 carattere  
**DIGITATO a **

>> aa
<<
**MAIN**
**GOT** 0 carattere a 
**GOT** 1 carattere a
**GOT** 2 carattere 
**DIGITATO aa **

and then if i send something longer it fails

>> fail
<<
**MAIN**
**GOT** 0 carattere f
**GOT** 1 carattere a
**GOT** 2 carattere 
**DIGITATO fa **

Я также попробовал это через скрипт на python, а также просто с помощью команды screen, но результат был всегда одинаковым.Любая помощь будет оценена.Большое спасибо

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Общий полученный буфер НЕ является вашей проблемой.Проблема возникает, потому что время выполнения

printf("**GOT** %d carattere %c \n",z,data);

блокирует код слишком долго, в то время как остальная часть строки отправляется терминалом.Приемный буфер XMEGA состоит из двухуровневого FIFO.

Давайте рассмотрим случай, когда вы пытались отправить «fail».

while((data!='\r')){

    // This blocks until the first char 'f' is received, which is OK.
    while( !(USARTC1_STATUS & USART_RXCIF_bm) );

    // At this point, 'f' is located in the DATA buffer.
    // The reception of the next char 'a' immediately starts next and is handled
    // by the UART receiver hardware.
    data = USARTC1_DATA; //Temporarly store received data

    // You just cleared the DATA buffer by reading it, so there is room for 'a'
    // after it has been received completely.

    // printf() blocks the code for a very long time
    printf("**GOT** %d carattere %c \n",z,data);

    // While you sent data using printf(), the terminal program sent the remaining
    // characters 'i' and 'l'. However, because DATA was already holding 'a' and
    // it wasn't cleared in between, the other chars got lost.

    line[z] = data;
    z++;

}

Надеюсь, это проясняет ситуацию.

0 голосов
/ 26 сентября 2018

Ладно, я получил ответ сам, глядя на таблицу.Кажется, что буфер rx и tx используется совместно, поэтому я попытался закомментировать отладочный printf внутри функции, и он просто сработал!надеюсь, что это может помочь кому-то, однако

...