Resposta inesperada do Atmega16 sobre o UART
Breve resumo do problema
Eu exibi um Atmega16 com um código que deveria resultar no envio do Atmega16 para qualquer caractere que eu enviar através de um terminal. Eu recebo uma resposta, mas raramente é o personagem que enviei. Consigo ver a saída correta alterando a taxa de transmissão, mas não entendo por que a taxa de transmissão correta funciona.
Mais detalhes
Estou tentando aprender mais sobre programação de firmware no meu tempo livre, porque gosto bastante. Até agora, na programação de firmware que fiz na uni, recebemos arquivos de código de esqueleto que fazem grande parte da interface periférica e configurados para nós, mas eu mesmo gostaria de aprender isso. Eu tenho algumas perguntas sobre o que estou fazendo aqui espalhadas por todo o post, mas vou descrevê-las no final. Se você perceber algum mal-entendido ou possíveis lacunas em meu conhecimento, eu apreciaria muito qualquer contribuição que você possa ter.
O código
O código que atualizei no meu Atmega16 está quase na linha do tutorial 'Usando o USART no AVR-GCC' encontrado nesta página . Tudo o que eu adicionei é o #define para F_CPU. O código original não tinha um #define para F_CPU, portanto meu código não seria compilado no AtmelStudio 7. Alguém poderia explicar por que o autor não teria definido F_CPU em seu arquivo original? Suponho que eles possam estar usando alguma outra ferramenta ou compilador que não seja o Atmel Studio 7, mas não posso dizer com certeza.
#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
}
}
A configuração do hardware
- MCU: Atmega16;
- Conjunto de ferramentas: Atmel Studio 7, piscando com o dragão AVR;
- Fonte de alimentação: barramento de 5V retirado de uma placa de desenvolvimento fornecida pela universidade (retirada do USB do computador). Capacitor de disco de cerâmica de 100nF usado para contornar as linhas de energia da placa de ensaio
- Conversor USB para serial: Este . TXD no conversor USB para serial conectado ao RXD Atmega (pino 15). RXD no conversor conectado ao RXD no Atmega (pino 14).
Software do terminal: PuTTY (com taxa de transmissão de 9600).
Evidência de respostas incorretas
Para reiterar, o Atmega deve retornar o que foi enviado a ele, ou seja, OUTPUT deve ser exatamente o mesmo que INPUT.
Saída PuTTY
Capturas de osciloscópio
Eu usei meu Picoscope com decodificação serial para verificar se o Atmega está recebendo a entrada correta, o que parece ser. Por exemplo, quando pressiono a tecla 'f', ela é recebida corretamente. A saída ainda é um '6' (ou um e comercial '&' na ocasião).
Uma correção que me deparei que eu não entendo
Se eu alterar a taxa de transmissão para 2500in PuTTY, tudo será exibido corretamente. Escolhi esse valor aleatoriamente e não sei por que ele funciona (isso me leva a acreditar que cometi um erro em algum lugar relacionado à taxa de transmissão, mas não vejo onde, pois copiei o tutorial quase exatamente ... pensamento).
Questões
- O que eu fiz de errado / o que está acontecendo aqui?
- Por que o tutorial original não # define F_CPU?
- Por que definir a taxa de transmissão para 2500 corrige o problema? (Eu suspeito que isso será respondido se a pergunta 1 for respondida)