Réponse Atmega16 inattendue sur UART
Bref résumé du problème
J'ai flashé un Atmega16 avec du code qui devrait entraîner le renvoi par Atmega16 du caractère que je lui envoie via un terminal. J'obtiens une réponse, mais c'est rarement le personnage que j'ai envoyé. Je peux voir la sortie correcte en modifiant le débit en bauds mais je ne comprends pas pourquoi le bon débit en bauds fonctionne.
Plus de détails
J'essaie d'en savoir plus sur la programmation de microprogrammes à mon rythme, car je l'apprécie beaucoup. Jusqu'à présent, dans la programmation du firmware que j'ai faite à uni, nous avons reçu des fichiers de code squelette qui effectuent une grande partie de l'interface périphérique et configurés pour nous, mais je voudrais l'apprendre moi-même. J'ai quelques questions sur ce que je fais ici saupoudré tout au long du post mais je vais les détailler à la fin. Si vous relevez des malentendus ou des lacunes potentielles dans mes connaissances, j'apprécierais grandement toute contribution que vous pourriez avoir.
Le code
Le code que j'ai flashé sur mon Atmega16 est pris presque ligne pour ligne du tutoriel `` Utilisation de l'USART dans AVR-GCC '' sur cette page . Tout ce que j'ai ajouté est le #define pour F_CPU. Le code d'origine n'avait pas de # définition pour F_CPU, donc mon code ne se compilerait pas dans AtmelStudio 7. Quelqu'un pourrait-il expliquer pourquoi l'auteur n'aurait pas défini F_CPU dans son fichier d'origine? Je suppose qu'ils ont peut-être utilisé un autre outil ou compilateur qu'Atmel Studio 7, mais je ne peux pas le dire avec certitude.
#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 configuration matérielle
- MCU: Atmega16;
- Chaîne d'outils: Atmel Studio 7, clignotant avec AVR dragon;
- Alimentation: rail 5 V provenant d'une carte de développement fournie par l'université (qui provient de l'ordinateur USB). Condensateur à disque en céramique 100nF utilisé pour le bypass sur les lignes électriques de la maquette
- Convertisseur USB vers série: celui-ci . TXD sur le convertisseur USB vers série connecté à RXD Atmega (broche 15). RXD sur le convertisseur connecté à RXD sur Atmega (broche 14).
Logiciel du terminal: PuTTY (avec un débit en bauds de 9600).
Preuve des réponses incorrectes
Pour réitérer, l'Atmega devrait retourner ce qui lui a été envoyé, c'est-à-dire que OUTPUT devrait être exactement la même chose que INPUT.
Sortie PuTTY
Captures d'oscilloscope
J'ai utilisé mon Picoscope avec décodage série pour vérifier que l'Atmega reçoit la bonne entrée, ce qui semble être le cas. Par exemple, lorsque j'appuie sur la touche «f», il est correctement reçu. La sortie est toujours un «6» (ou une esperluette «&» à l'occasion).
Une solution sur laquelle je suis tombé et que je ne comprends pas
Si je change la vitesse de transmission en 2500T PuTTY, tout s'affiche correctement. J'ai choisi cette valeur au hasard et je ne sais pas pourquoi cela fonctionne (cela me porte à croire que j'ai fait une erreur quelque part avec le débit en bauds mais je ne vois pas où étant donné j'ai copié le tutoriel presque exactement ... Je pensée).
Des questions
- Qu'est-ce que j'ai fait de mal / qu'est-ce qui se passe ici?
- Pourquoi le didacticiel d'origine n'est-il pas #define F_CPU?
- Pourquoi la définition du débit en bauds à 2500 résout-elle le problème? (Je soupçonne que ce sera répondu si la question 1 est répondue)