AVR - не работает высокоскоростной код UART, управляемый прерываниями - PullRequest
0 голосов
/ 15 мая 2018

Я хочу создать программу UART, управляемую прерываниями, чтобы отправлять большие объемы данных на высоких скоростях с абсолютным минимальным объемом служебных данных процессора.Я объединил существующий код и чтение таблицы, чтобы создать этот код.Он компилируется без ошибок или предупреждений в Atmel Studio 7 на платформе atmega328p (Atmega328p Xplained Mini).

Проблема, с которой я сталкиваюсь, заключается в том, что данные ошибочны, иногда они посылают «привет!»иногда ничего не на некоторое время.'H' часто пропускается, я не понимаю этого, поскольку ISR не должен выполняться до того, как будет скопировано 'H' из UDR0 для отправки.

Любая помощь будет принята с благодарностью!

Привет,

Берт.

#define F_CPU 16000000

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>

volatile uint8_t transmit_index = 0;
volatile char str[] = "Hello!\n";
volatile uint8_t len = 6;

int main(void){
    UCSR0A = 0b00000010;
    UCSR0B = 0b00111000;
    UCSR0C = 0b00000110;

//9600 baud
    UBRR0L = 207; 
    UBRR0H = 0;

    DDRD |= 0x02;

    sei();

    //Flash led
    DDRB |= 0b00100000;
    PORTB |= 0b00100000;
    _delay_ms(1000);
    PORTB &= ~0b00100000;
    _delay_ms(1000);

    while (1){  
        transmit_index = 1;

        //Enable udre interrupt
        UCSR0B |= 0b00100000; //enable interrupt

        //Send first byte in main()
        while (!(UCSR0A & 0b00100000)) {} //Wait for register empty
        UDR0 = str[0]; //send first byte

        _delay_ms(1000);
    }
}

ISR(USART_UDRE_vect) {
    //Buffer empty, ready for new data
    if (transmit_index < (len + 1)) {
        UDR0 = str[transmit_index];
        transmit_index++;
    } else {
        UCSR0B &= ~0b00100000; //disable interrupt
    }
}

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

В вашем основном цикле измените эту строку:

transmit_index = 1;

для этой строки:

transmit_index = 0;

str [0] = 'H', но вы начинаете с индекса [1] ...

0 голосов
/ 15 мая 2018

за лист:

"Когда бит разрешения пустого прерывания регистра данных (UDRIE) в UCSRnB записывается в '1', пустое прерывание регистра данных USART будет выполняется до тех пор, пока UDRE установлен "

Как только вы включаете прерывание, запускается ISR, пропуская, таким образом, букву "H". У вас есть несколько вариантов. 1) Включить прерывание после отправки H. 2) Просто используйте ISR для отправки всего сообщения, включая H (например, не отправляйте ничего в основной процедуре). 3) Используйте прерывание Tramsmit Complete ((TXC). Если вы используете это, отправьте H в основной подпрограмме, и после ее передачи ISR сработает, а ваш ISR отправит остальную часть сообщения.

Наконец, замените «Transfer_index <(len + 1)» на Transfer_index <= len. Нет необходимости тратить инструкции внутри ISR </p>

...