Неожиданный ответ Atmega16 через UART
Краткое описание проблемы
Я прошил Atmega16 с кодом, который должен привести к тому, что Atmega16 отправит обратно любой символ, который я отправлю ему через терминал. Я получаю ответ, но это редко когда отправляется персонаж. Я могу видеть правильный вывод, изменяя скорость передачи, но я не понимаю, почему работает правильная скорость передачи.
Подробнее
Я пытаюсь узнать больше о программировании прошивки в свое время, потому что мне это очень нравится. До сих пор в программировании микропрограммного обеспечения, которое я выполнял в универе, нам были предоставлены файлы кода скелета, которые выполняют большую часть периферийного интерфейса и настраиваются для нас, но я хотел бы изучить это сам. У меня есть несколько вопросов о том, что я делаю здесь, разбросанных по всему посту, но я опишу их в конце. Если вы обнаружите какие-либо недоразумения или потенциальные пробелы в моих знаниях, я был бы очень признателен за любые ваши комментарии.
Код
Код, который я поместил на мой Atmega16, взят почти строка за строкой из руководства «Использование USART в AVR-GCC», приведенного на этой странице . Все, что я добавил, это #define для F_CPU. В исходном коде не было #define для F_CPU, поэтому мой код не будет компилироваться в AtmelStudio 7. Может ли кто-нибудь объяснить, почему автор не определил F_CPU в их исходном файле? Я предполагаю, что они, возможно, использовали какой-то другой инструмент или компилятор, кроме Atmel Studio 7, но я не могу сказать наверняка.
#include <avr/io.h>
#define F_CPU 7372800 //this was chosen because the tutorial states this is the frequency we want to operate at
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((( F_CPU / 16) + ( USART_BAUDRATE / 2)) / ( USART_BAUDRATE )) - 1)
int main ( void )
{
char ReceivedByte ;
UCSRB = (1 << RXEN ) | (1 << TXEN ); // Turn on the transmission and reception circuitry
UCSRC = (1 << URSEL ) | (1 << UCSZ0 ) | (1 << UCSZ1 ); // Use 8- bit character sizes
UBRRH = ( BAUD_PRESCALE >> 8); // Load upper 8- bits of the baud rate value into the high byte of the UBRR register
UBRRL = BAUD_PRESCALE ; // Load lower 8- bits of the baud rate value into the low byte of theUBRR register
for (;;) // Loop forever
{
while (( UCSRA & (1 << RXC )) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
ReceivedByte = UDR ; // Fetch the received byte value into the variable " ByteReceived "
while (( UCSRA & (1 << UDRE )) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte ; // Echo back the received byte back to the computer
}
}
Настройка оборудования
- MCU: Atmega16;
- Набор инструментов: Atmel Studio 7, мигает с помощью дракона AVR;
- Электропитание: 5-вольтовое напряжение, взятое с разработанной университетом платы разработки (которая берется с компьютера USB) Керамический дисковый конденсатор емкостью 100 нФ для обхода линий электропередачи
- Конвертер USB в последовательный: этот . TXD на преобразователе USB в последовательный порт, подключенный к RXD Atmega (контакт 15). RXD на преобразователе, подключенном к RXD на Atmega (контакт 14).
Терминальное программное обеспечение: PuTTY (со скоростью передачи 9600).
Доказательства неправильных ответов
Чтобы повторить, Atmega должен вернуть то, что было отправлено ему, т.е. OUTPUT должен быть точно таким же, как INPUT.
PuTTY выход
Захваты осциллографа
Я использовал свой Picoscope с последовательным декодированием, чтобы проверить, что Atmega получает правильный вход, который, по-видимому, и есть. Например, когда я нажимаю клавишу «F», он принимается правильно. Выход по-прежнему «6» (или амперсанд «&» в некоторых случаях).
Исправление я наткнулся на то, что я не понимаю
Если я изменю скорость передачи данных на 2500in PuTTY, все будет отображаться правильно. Я выбрал это значение случайным образом, и я не знаю, почему это работает (это заставляет меня думать, что я где-то сделал ошибку, связанную с скоростью передачи данных, но я не вижу, где, учитывая, что я скопировал учебник почти точно ... Я думал).
Вопросов
- Что я сделал не так / что здесь происходит?
- Почему оригинальный учебник не #define F_CPU?
- Почему установка скорости 2500 в бод решает проблему? (Я подозреваю, что это будет дан ответ, если ответ на вопрос 1)