il faut attendre la réponse de @fdufnews, je ne vois rien d'autre que la configuration de CKSEL
En mode "Full Swing Oscillator" il n'y a pas d'option qui dépende de la fréquence. Les options concernent le temps de stabilisation de l'oscillateur. Ici en l’occurrence c'est le temps le plus long qui est choisi.
Il ne faut pas négliger le fait qu'un quartz mal adapté peut osciller à la mauvaise fréquence. Il faudrait vérifier la fréquence de l'oscillateur et éventuellement changer la valeur des 2 capas à ses bornes.
La réponse sur cette question dans les forum est: Arduino IDE n'utilise pas la constante F_CPU contrairement à avrstudio. Reste à vérifier le véracité!
On trouve beaucoup d'idioties sur les forums
Si tu regardes la sortie de compilation dans le panneau inférieur de l'IDE tu verras que la définition de F_CPU est passée en argument au compilateur et dans les librairies du core arduino F_CPU est utilisé
Un exemple tiré de .arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.cpp
void HardwareSerial::begin(unsigned long baud, byte config)
{
// Try u2x mode first
uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;
*_ucsra = 1 << U2X0;
// hardcoded exception for 57600 for compatibility with the bootloader
// shipped with the Duemilanove and previous boards and the firmware
// on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
// be > 4095, so switch back to non-u2x mode if the baud rate is too
// low.
if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
{
*_ucsra = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
}
Avec avr studio aec la carte DIP-40 de chez tindie ceci fonctionne jusqu'à 57600
#define F_CPU 20000000UL
//#define CYCLES_PER_US ((F_CPU+500000)/1000000)
#include <avr/io.h>
#include <util/delay.h>
#define BAUDRATE 57600
#define BAUD_PRESCALLER ((F_CPU / (BAUDRATE * 16UL))- 1)
il y a 2 capa à coté du crystal, c'est du cms, mais cette carte fonctionne bien sur arduino à 115200,
ca vient surement du code de avr studio au niveau de uart_init, je suppose.
j'utilise un adaptateur db9 ttl sur les pin D10 et D11 de l'Atmega1284P. 4 fils de 10cm (vcc,gnd,tx et rx),
Est ce qu'il y a un sens pour le crystal ?
Oui, c'est bien pour ça que j'ai dit à vérifier.
Par contre que avrstudio fonctionne moins bien que arduino ide je n'y crois pas une seconde. avrstudio a été fait par atmel avec une library conçue par atmel pour des micros fabriqués par atmel. Si on me dit fonctionne avec arduino mais pas avec avrstudio je chercherais le problème en premier sur Arduino
Non, mais par contre il faut l'implanter au plus près du processeur. Les longues pistes ajoutes des éléments parasites (inductances et capacités)
Le problème du traitement de la macro F_CPU dans arduino ide semble se confirmer dans tous les posts , mais je n'ai pas les outils nécessaire pour vérifier.
Il y a plusieurs tests possibles
Vérifier que bien qu'il y ait des exceptions dans avrstudio il est nécessaire de définir F_CPU avant d'inclure util/delay.h (mode d'emploi avr)
Dans arduino Ide vérifier que la valeur soit prise en compte
#define F_CPU 20000000UL
et pourquoi dans mon arduino ide ces lignes sont compilées, c'est lié à ma config? (je ne connais pratiquement pas arduino ide)
#define F_CPU 2000000L
#ifdef F_CPU
#undef F_CPU
#define BAUDRATE 57600
#define BAUD_PRESCALLER ((F_CPU / (BAUDRATE * 16UL))- 1)
@fdufnews merci si tu as une explication. Sais-tu si le comportement est identique avec VSCode?
Maintenant ca fonctionne en 115200, j'ai remplacé 16 par 8 dans la formule
#define F_CPU 20000000UL
//#define CYCLES_PER_US ((F_CPU+500000)/1000000)
#include <avr/io.h>
#include <util/delay.h>
#define BAUDRATE 115200
#define BAUD_PRESCALLER ((F_CPU / (BAUDRATE * 8UL))- 1)
et dans l'initialisation de USART_Init j'ai ajouté
UCSR1A |= (1<<U2X1);
USART_Init:
void USART_init(unsigned char ubrr){
/*Set baud rate */
UBRR1H = (unsigned char)(ubrr>>8);
UBRR1L = (unsigned char)ubrr;
//_delay_ms(1);
UCSR1C |= (1<<UCSZ11)|(1<<UCSZ10);
UCSR1A |= (1<<U2X1);
//Enable receiver and transmitter
UCSR1B |= (1<<RXEN1)|(1<<TXEN1) | (1<<RXCIE1);
UCSR1B &= ~(1<<UDRIE1);
//_delay_ms(1);
}
J'ai recherché un peu partout sur internet, après techniquement je ne sais pas ce que fait
UCSR1A |= (1<<U2X1);
Je n'ai pas trop compris dans la doc, en tout cas ca fonctionne avec AVR STUDIO.
J'ai ajouté aussi (1<<RXCIE1) mais je pense que je n'en ai pas besoin, je n'utilise pas les IRQ pour recevoir, j'ai copié bêtement.
Ca fonctionne aussi maintenant avec uterm-s, pourquoi 8 a la place de 16, ca je ne sais pas.
L'UART a 2 modes de fonctionnement en asynchrone.
- Mode "Normal": l'horloge CPU est divisée par 16 ce qui permet de sur-échantillonner l'entrée et garantir une meilleur immunité au bruit. Comme l'horloge est divisée par 16 cela limite les baudrates élevés.
- Mode "Double Speed", l'horloge CPU est divisée par 8 ce qui permet d'atteindre des vitesses de transfert plus élevées.
En fait, le choix mode "normal", mode "Double Speed" est un compromis entre le débit, la fréquence de l'horloge CPU et l'erreur acceptable sur la liaison série.
C'est justement l'activation du mode "Double Speed'
A noter, avec un quartz à 20MHz tu devrais pouvoir communiquer sans erreur aussi bien en mode "Normal" qu'en mode "Double Speed"
Je ne comprends pas pourquoi tu t'acharnes à vouloir utiliser AVR STUDIO si tu ne lis pas la datasheet de ton micro dans le détail.
Arduino est justement fait pour permettre de travailler sans devoir aller explorer la doc en profondeur.
Merci pour les explications, Oui en effet, mais j'ai tendance toujours à vouloir développer en C pure, c'est un peu plus optimisé en C avec avr studio mais ca fonctionne sans problème avec Arduino. Si je veux ajouter par exemple un esp8266 ou une sdcard, c'est clair que c'est plus facile avec Arduino, meme si j'ai déjà programmé une sdcard (SPI) avec AVR STUDIO en utilisant des lib mmc.
La fréquence de l'horloge du CPU est défini dans le fichier board.txt qui décrit la constitution des cartes. Ensuite cette fréquence est passée en argument au compilateur.
VS Code n'est qu'un environnement de développement. PlateformIO utilise les mêmes librairies et le même compilateur que l'IDE arduino, il me semble.
Si par contre tu invoques toi même le compilateur il faut lui passer un argument -DFCPU=xxxxxx pour définir la macro afin que les librairies reçoivent l'information.
On pourrait évidemment le mettre en dur dans le code mais c'est dangereux car il risque d'y avoir des définitions multiples et divergentes dans plusieurs librairies et le code n'est plus portable si on change de fréquence d'horloge.
Merci pour la réponse,
La question sur VSCode était dû au fait que VSCode avertit qu'il s'agit d'une redéfinition quand on met une ligne #define F_CPU
Donc si on fait F_CPU 20MHz il ne prend pas en compte mais conserve la valeur du fichier board.txt?
Je ne sais pas dire dans quel ordre c'est interprété par le préprocesseur. Voici ce que dit la doc de GCC pour l'option -D en argument
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a ‘#define’ directive.
Merci, je verrais plus tard je suis parti sur l'esp32
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.



