Sinon il faudra sortir l'oscilloscope pour voir ce qui se passe réellement sur Tx.
-----
Sinon il faudra sortir l'oscilloscope pour voir ce qui se passe réellement sur Tx.
non cela fonctionne toujours pasJe soupçonne un problème de synchronisation.
Ta valeur pour fixer le baud-rate me semble bonne si j'en crois la doc, mais tu utilises la base de temps interne et je ne suis pas certain que ce soit judicieux pour un UART de prendre une telle fréquence interne.
Peux-tu essayer avec par exemple 1MHz? Ce qui donnerait 0xEC57 avec s=8 si je ne me trompe pas.
Ce qui serait intéressant ce serait de voir le signal dont tu parles.
Poste une capture d'écran.
j'ai modifié mon code mais cela ne fonctionne toujours pas.
definitions.h :
pin_config.c :Code:#ifndef DEFINITIONS_H_ #define DEFINITIONS_H_ #define TXD_LED PORT_PB08D_SERCOM4_PAD0 #define RXD_LED PORT_PB09D_SERCOM4_PAD1 #endif /* DEFINITIONS_H_ */
clock_config.c :Code:#include "sam.h" #include "definitions.h" void pin_config() { REG_PORT_DIR1 = TXD_LED; // configure TXD_LED comme une sortie REG_PORT_DIR1 &= ~(RXD_LED); // configure RXD_LED comme une entrée REG_PORT_OUT1 &= ~(RXD_LED); // active l'entrée avec pull down REG_PORT_PMUX1 = PORT_PMUX_PMUXE_D | PORT_PMUX_PMUXO_D; // sélectionne la fonction périphérique D pour les broches paires et impaires REG_PORT_PINCFG1 = PORT_PINCFG_INEN | PORT_PINCFG_PULLEN | PORT_PINCFG_PMUXEN; // Le tampon d'entrée pour la broche d'E / S est activé; // la résistance de tirage interne est activée; La sélection du multiplexeur périphérique est activée }
usart_config.c :Code:void clock_config() { REG_PM_APBCMASK |= PM_APBCMASK_SERCOM4; // active le bus d'horloge du SERCOM4 REG_SYSCTRL_XOSC = SYSCTRL_XOSC_ENABLE | SYSCTRL_XOSC_XTALEN | SYSCTRL_XOSC_RUNSTDBY | SYSCTRL_XOSC_AMPGC; // active l'oscillateur; active l'oscillateur à quartz externe; // l'oscillateur fonctionne tout le temps en mode veille et standby; Le contrôle automatique du gain d'amplitude est activé; REG_GCLK_GENDIV = GCLK_GENDIV_ID (0x0) | GCLK_GENDIV_DIV (0x1); // sélectionne GCLKGEN0; fGCLKGEN0 = fGCLKGEN0 / 1 while (REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY){} // attend jusqu'à ce que la synchronisation est complète REG_GCLK_GENCTRL = GCLK_GENCTRL_ID (0x0) | GCLK_GENCTRL_SRC_XOSC | GCLK_GENCTRL_GENEN; // sélectionne GCLKGEN0; sélectionne XOSC comme source d'horloge; GCLKGEN0 est activée while (REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY){} // attend jusqu'à ce que la synchronisation est complète REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_SERCOM4_CORE | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0; // sélectionne GCLK_SERCOM4_CORE; GCLK0 est activée; GCLKGEN0 }
usart_tx.c :Code:#include "sam.h" void usart_config() { REG_SERCOM4_USART_CTRLA = 0; // désactive le périphérique SERCOM4 while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_ENABLE){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_RUNSTDBY; // L'horloge générique est activée dans tous les modes de veille. REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_MODE_USART_INT_CLK; // UART avec horloge interne REG_SERCOM4_USART_CTRLA &= ~(SERCOM_USART_CTRLA_CMODE); // communication asynchrone REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_RXPO(0x1); // SERCOM PAD[1] est utilisé pour la réception de données REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_TXPO(0x2); // SERCOM PAD[1] est utilisé pour la transmission de données REG_SERCOM4_USART_CTRLB = 0; // désactive le registre CTRLB while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_CHSIZE(0x0); // caractère de 8 bits while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_DORD; // le bit LSB est envoyé en premier REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_FORM(0x0); // trame UART sans parité REG_SERCOM4_USART_CTRLB &= ~(SERCOM_USART_CTRLB_SBMODE); // 1 bit stop while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_BAUD = 0; // désactive le registre BAUD REG_SERCOM4_USART_BAUD = 0xFCB9; // je veux une fBAUD = 9600 // fBAUD = FXOSC/16*(1-BAUD/65536) // donc BAUD = 65536*(1-16*fBAUD/fXOSC) // BAUD = 64697 <=> 0xFCB9 en hexa REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_RXEN; // la réception de données est activée while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_TXEN; // la transmission de données est activée while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLA = 1; // active le périphérique SERCOM4 while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_ENABLE){} // attend jusqu'à ce que la synchronisation est complète }
usart_rx.c :Code:#include "sam.h" int usart_tx() { while(!(REG_SERCOM4_USART_INTFLAG & SERCOM_USART_INTFLAG_DRE)); // attent que le bit du registre d'envoi de donnée soit vide REG_SERCOM4_USART_DATA = 0x31; // écris "1" dans le registre DATA return REG_SERCOM4_USART_DATA; }
main.c :Code:#include "sam.h" int usart_rx() { while(!(REG_SERCOM4_USART_INTFLAG & SERCOM_USART_INTFLAG_RXC)); // attent que le bit du registre de réception de donnée soit vide return REG_SERCOM4_USART_DATA; }
Code:#include "sam.h" #include "definitions.h" #include "pin_config.h" #include "clock_config.h" #include "usart_config.h" #include "usart_tx.h" #include "usart_rx.h" int main(void) { pin_config(); clock_config(); usart_config(); while(1) { usart_tx(); // envoi de la donnée sur l'UART usart_rx(); // réception de la donnée sur l'UART } }
C'est tout?photo du signal :
Pièce jointe 426929
Normal que tu ne reçoives rien sur ton terminal si tu n'as que ça.
En principe tu devrais 1 octet contenant (0x31) et avoir un bit de stop à 1.
Tu es bien certain d'avoir capturé toute la trame?
Vérifie ta base de temps et tes registres USART dans ton code.
Utilise un des ports en sortie pour debugguer en utilisant la même base de temps que l'UART pour inverser cette variable.
As-tu tenté?Envoyé par ExotiquePeux-tu essayer avec par exemple 1MHz? Ce qui donnerait 0xEC57 avec s=8 si je ne me trompe pas.
Vérifie tout de même la valeur que je t'ai indiqué.
Et essaye de juste émettre pour le moment, histoire de ne pas ajouter de problème supplémentaire
Maintenant j'arrive à envoyer "1" en ASCII ^^. c'est la configuration des pins qui posaient problème.
@Exotique : Je vous remercie beaucoup pour votre aide.
Je reviens dans cette discussion pour mettre mon code pour ceux à qui cela pourrait servir.
J'ai rajouté aussi une fonction pour recevoir "1" lorsqu'on on envoie un "1" dans le terminal
voici mon code :
definitions.h :
pin_config.c :Code:#ifndef DEFINITIONS_H_ #define DEFINITIONS_H_ #define TXD_LED PORT_PB08D_SERCOM4_PAD0 #define RXD_LED PORT_PB09D_SERCOM4_PAD1 #endif /* DEFINITIONS_H_ */
clock_config.c :Code:#include "sam.h" void pin_config() { PORT->Group[1].PMUX[4].reg = PORT_PMUX_PMUXE_D | PORT_PMUX_PMUXO_D; // sélectionne la fonction périphérique D pour les pins paires et impaires PORT->Group[1].PINCFG[8].reg = PORT_PINCFG_PMUXEN; PORT->Group[1].PINCFG[9].reg = PORT_PINCFG_INEN | PORT_PINCFG_PMUXEN | PORT_PINCFG_PULLEN; // Le tampon d'entrée pour la broche d'E / S est activé; // La sélection du multiplexeur périphérique est activée et la fonction périphérique // sélectionnée contrôle la direction et la valeur de commande de sortie. // active la résistance de tirage interne }
usart_config.c :Code:#include "sam.h" void clock_config() { REG_SYSCTRL_XOSC |= SYSCTRL_XOSC_ENABLE; // active l'oscillateur REG_SYSCTRL_XOSC |= SYSCTRL_XOSC_XTALEN; // active l'oscillateur à quartz externe REG_SYSCTRL_XOSC |= SYSCTRL_XOSC_STARTUP(0x0); // temps de démarrage de l'oscillateur = 31µs REG_SYSCTRL_XOSC &= ~(SYSCTRL_XOSC_ONDEMAND); // l'oscillateur fonctionne tout le temps en mode veille et standby while(!SYSCTRL->PCLKSR.bit.XOSCRDY); // attend que XOSCRDY est mis à 1 REG_SYSCTRL_XOSC |= SYSCTRL_XOSC_AMPGC; // Le contrôle automatique du gain d'amplitude est activé REG_SYSCTRL_XOSC |= SYSCTRL_XOSC_RUNSTDBY; REG_GCLK_GENDIV = GCLK_GENDIV_ID(0x0) | GCLK_GENDIV_DIV(0x1); // sélectionne GCLKGEN0; fGCLKGEN0 = fGCLKGEN0 / 1 while (REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY){} // attend jusqu'à ce que la synchronisation est complète REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(0x0) | GCLK_GENCTRL_SRC_XOSC | GCLK_GENCTRL_GENEN; // sélectionne GCLKGEN0; sélectionne XOSC comme source d'horloge; GCLKGEN0 est activée while (REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY){} // attend jusqu'à ce que la synchronisation est complète REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_SERCOM4_CORE | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; // sélectionne GCLK_SERCOM4_CORE; GCLKGEN0; GCLK0 est activée; REG_PM_APBCSEL |= PM_APBCSEL_APBCDIV_DIV1; REG_PM_APBCMASK |= PM_APBCMASK_SERCOM4; // active le bus d'horloge du SERCOM4 }
usart_tx.c :Code:#include "sam.h" void usart_config() { REG_SERCOM4_USART_CTRLA &= ~(SERCOM_USART_CTRLA_ENABLE); // désactive le périphérique SERCOM4 while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_ENABLE){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_RUNSTDBY; // L'horloge générique est activée dans tous les modes de veille. REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_MODE_USART_INT_CLK; // UART avec horloge interne REG_SERCOM4_USART_CTRLA &= ~(SERCOM_USART_CTRLA_CMODE); // communication asynchrone REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_RXPO(0x1); // SERCOM PAD[1] est utilisé pour la réception de données REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_TXPO(0x2); // SERCOM PAD[0] est utilisé pour la transmission de données REG_SERCOM4_USART_CTRLB = 0; // désactive le registre CTRLB while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_CHSIZE(0x0); // caractère de 8 bits while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_DORD; // le bit LSB est envoyé en premier REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_FORM(0x0); // trame UART sans parité REG_SERCOM4_USART_CTRLB &= ~(SERCOM_USART_CTRLB_SBMODE); // 1 bit stop while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_BAUD = 0; // désactive le registre BAUD REG_SERCOM4_USART_BAUD = SERCOM_USART_BAUD_BAUD(0xFCB9); // je veux une fBAUD = 9600 // fBAUD = FXOSC/16*(1-BAUD/65536) // donc BAUD = 65536*(1-16*fBAUD/fXOSC) // BAUD = 64697 <=> 0xFCB9 en hexa REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_RXEN; // la réception de données est activée while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_TXEN; // la transmission de données est activée while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_CTRLB){} // attend jusqu'à ce que la synchronisation est complète REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_ENABLE; // active le périphérique SERCOM4 while (REG_SERCOM4_USART_SYNCBUSY & SERCOM_USART_SYNCBUSY_ENABLE){} // attend jusqu'à ce que la synchronisation est complète }
usart_rx.c :Code:#include "sam.h" void usart_tx() { while(!(REG_SERCOM4_USART_INTFLAG & SERCOM_USART_INTFLAG_DRE)); // attend que le bit du registre d'envoi de donnée soit à 1 REG_SERCOM4_USART_DATA = 0x31; // écris "1" dans le registre DATA }
main.c :Code:#include "sam.h" void usart_rx() { while(!(REG_SERCOM4_USART_INTFLAG & SERCOM_USART_INTFLAG_RXC)); // attend que le bit du registre de réception de donnée soit à 1 return REG_SERCOM4_USART_DATA; }
Code:#include "sam.h" #include "definitions.h" #include "pin_config.h" #include "clock_config.h" #include "usart_config.h" #include "usart_tx.h" #include "usart_rx.h" int main(void) { clock_config(); usart_config(); pin_config(); while(1) { usart_tx(); // envoi de la donnée sur l'UART usart_rx(); // réception de la donnée sur l'UART } }