Последовательная связь Uart не может отобразиться обратно Atmega16a

Я новичок в avr (8bit uc) и недавно столкнулся с проблемой при использовании последовательной связи (uart) с ПК. Микроконтроллер не отвечает в терминале шпатлевки, где он должен возвращать все, что я отправил.


Спасибо за ваш ответ всем.

Прошу прощения за поврежденный код. Я понятия не имел, что делаю, так как я новичок в этом отступе кода в обмене стеками.


Новый код прикреплен ниже, пожалуйста, предложите

#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>

volatile char data;

void USARTInit(uint16_t ubrr_value) {
    UBRRL = ubrr_value;
    UBRRH = (ubrr_value >> 8);
    UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
    UCSRB = (1 << RXEN) | (1 << TXEN);
}

void USARTWriteChar(char data) {
    while (!(UCSRA & (1 << UDRE)))
        { }

    //Now write the data to USART buffer
    UDR = data;                                                               
}                                                                             

void main() {                                                                 
    sei();                                                                    
    UCSRB |= (1 << RXCIE);                                                    
    USARTInit(51);                                                            

    while (1) {                                                               
        if (data == 'a') {                                                    
            USARTWriteChar(data);
        }
    }
}

ISR(USARTRXC_vect) {
    data = UDR;
}

поэтому здесь foo просто представляет мои данные = 'a', к сожалению, avr не отвечает на мои входные данные. когда я набираю "а".

Что ж, вы закомментировали строку, которая будет запрашивать данные из вашего UART, надеясь, что ваше прерывание сработает. Если вы используете подход опроса вместо прерываний, у вас есть какой-либо успех?
@brhans Похоже, он пытается использовать для этого прерывание, но это трудно сказать из-за этого плохо отформатированного кода, а также он выглядит усеченным с этим if(data==1) }в конце ...
@Majenko Да, форматирование кода сначала обмануло меня, и этот бит в конце тоже не имеет никакого смысла.
@brhans Я пропустил его через астиль, чтобы немного почистить. Действительно выделяет неработающую часть кода...

Ответы (1)

Во-первых, этот код не будет компилироваться. Последняя его часть (ISR) выглядит поврежденной — возможно, вы захотите повторно опубликовать этот фрагмент.

Во-вторых, неудивительно, что если вы наберете «FOO», он не ответит, так как код ждет, пока вы нажмете «a», после чего он ответит «[a][a][a][a] [a][a]....", пока вы не нажмете что-то еще.

В-третьих, вы должны научиться правильно форматировать свой код или, по крайней мере, использовать один из хороших автоформатеров, например Artistic Style.

К сожалению, у меня нет ATMega16A, чтобы протестировать ваш код, и я не разбираюсь в прерываниях Atmel, поэтому все, что я могу сделать, это предложить кое-что попробовать:

  1. Убедитесь, что ваш код действительно работает, а сам серийный номер работает: заставьте его печатать сообщение «Hello» в начале вашего main()после настройки UART.
  2. Убедитесь, что прерывание действительно срабатывает — сделайте так, чтобы при срабатывании прерывания загорался светодиод.
  3. Заставьте его мигать другим светодиодом как «пульс» в вашем основном while(1)цикле, чтобы убедиться, что он не застревает.

Редактировать: после некоторого копания и чтения (я обнаружил, что таблицы данных Atmel ужасно плохо написаны), я обнаружил, что ваш вектор прерывания назван неправильно.

Все они перечислены на этой странице: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

Там, после некоторого поиска, вы можете найти, что для ATMega16 вектор RX должен быть назван:

    USART_RXC_vect 

После изменения имени на это я вижу из декомпиляции, что ISR правильно устанавливается в векторную таблицу:

00000000 <__vectors>:
   0:   0c 94 2a 00     jmp 0x54    ; 0x54 <__ctors_end>
   4:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
   8:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
   c:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  10:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  14:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  18:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  1c:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  20:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  24:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  28:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  2c:   0c 94 5c 00     jmp 0xb8    ; 0xb8 <__vector_11>   // <-- ISR
  30:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  34:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  38:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  3c:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  40:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  44:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  48:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  4c:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  50:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>

... чего не было раньше.

Я также новичок в форматах кодирования, как вы сказали о художественном стиле, я установил его в atmel studio 5.2, но, похоже, в формате нет никакой разницы.
Я никогда не использовал Artistic Style от Atmel Studio. Я не знаю, поддерживается ли он вообще в нем. Я использую его только как инструмент командной строки или из своей собственной IDE (UECIDE, которую я настроил специально, чтобы опробовать ваш код).
Прерывание uart, о котором я упоминал, по какой-то неизвестной причине работает в atmel studio 5.2. Если я даю прерывание, как вы упомянули, оно, кажется, выдает мне ошибку «MISSTYPED HANDLER».., и я могу получать как TX/ RX, протестировал его, используя int вместо char ... кажется, я должен использовать (strcmp (x, y) == 0) ... спасибо за беспокойство, друг ..