Risposta Atmega16 imprevista su UART
Breve riassunto del problema
Ho trasmesso un Atmega16 con un codice che dovrebbe comportare la restituzione di Atmega16 da qualsiasi carattere che gli invio tramite un terminale. Ricevo una risposta, ma raramente è il personaggio che ho inviato. Posso vedere l'output corretto modificando il baud rate ma non capisco perché il baud rate corretto funzioni.
Più dettaglio
Sto cercando di saperne di più sulla programmazione del firmware ai miei tempi perché mi diverto abbastanza. Finora nella programmazione del firmware che ho fatto in uni, ci sono stati dati file di codice scheletro che eseguono molte interfacce periferiche e sono stati configurati per noi, ma vorrei impararlo da solo. Ho alcune domande su cosa sto facendo qui, sparse in tutto il post, ma le farò alla fine. Se prendessi in considerazione incomprensioni o potenziali lacune nella mia conoscenza, apprezzerei molto qualsiasi input tu possa avere.
Il codice
Il codice che ho visualizzato sul mio Atmega16 è preso quasi riga per riga dal tutorial "Uso di USART in AVR-GCC" trovato in questa pagina . Tutto quello che ho aggiunto è #define per F_CPU. Il codice originale non aveva un #define per F_CPU, quindi il mio codice non sarebbe stato compilato in AtmelStudio 7. Qualcuno potrebbe spiegare perché l'autore non avrebbe definito F_CPU nel suo file originale? Immagino che stiano usando un altro strumento o compilatore diverso da Atmel Studio 7, ma non posso dirlo con certezza.
#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
}
}
La configurazione dell'hardware
- MCU: Atmega16;
- Toolchain: Atmel Studio 7, lampeggiante con drago AVR;
- Alimentazione: rotaia da 5 V presa da una scheda di sviluppo fornita dall'università (che viene presa dal computer USB). Condensatore a disco ceramico 100nF utilizzato per bypassare le linee elettriche della breadboard
- Convertitore da USB a seriale: questo . TXD sul convertitore da USB a seriale collegato a RXD Atmega (Pin 15). RXD sul convertitore collegato a RXD su Atmega (Pin 14).
Software terminale: PuTTY (con baudrate di 9600).
Prova delle risposte errate
Per ribadire, l'Atmega dovrebbe restituire ciò che gli è stato inviato, ovvero OUTPUT dovrebbe essere esattamente lo stesso di INPUT.
Uscita PuTTY
Cattura dell'oscilloscopio
Ho usato il mio Picoscope con decodifica seriale per verificare che l'Atmega stia ricevendo l'input corretto, che sembra essere. Ad esempio, quando premo il tasto 'f', viene ricevuto correttamente. L'uscita è ancora un '6' (o una e commerciale '&' a volte).
Una soluzione su cui mi sono imbattuto è che non capisco
Se cambio il baudrate a 2500 in PuTTY, tutto viene visualizzato correttamente. Ho scelto questo valore a caso e non so perché funzioni (mi porta a credere di aver fatto un errore da qualche parte a che fare con il baudrate ma non vedo dove dato ho copiato il tutorial quasi esattamente ... I pensiero).
Domande
- Cosa ho fatto di sbagliato / cosa sta succedendo qui?
- Perché il tutorial originale non è #define F_CPU?
- Perché l'impostazione del baud rate su 2500 risolve il problema? (Sospetto che a questa risposta verrà data risposta alla domanda 1)