Bonjour à tous, je suis débutant concernant la programmation de systèmes embarqués, je veux envoyer un chiffre via l'USART.
J'utilise un ATSAMD21J18 et le convertisseur UART->USB est un UM232H
enfaite je sais que le registre DATA ne doit être écrit que lorsque INTFLAG.DRE est mis à '1' mais j'ai déja essayé mais cela ne fonctionne pas dans mon programme.
Si quelqu'un peut m'aider, ce serait très reconnaissant.
voici mes codes :
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_OUT1 |= TXD_LED; // active la sortie REG_PORT_PMUX1 |= PORT_PMUX_PMUXE_D; // sélectionne la fonction périphérique D pour les pins paires //REG_PORT_PMUX1 |= PORT_PMUX_PMUXO_D; // sélectionne la fonction périphérique D pour les pins impaires REG_PORT_PINCFG1 |= PORT_PINCFG_INEN; // REG_PORT_PINCFG1 |= PORT_PINCFG_PMUXEN; // 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. }
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; // mode oscillateur à quartz REG_SYSCTRL_XOSC |= SYSCTRL_XOSC_RUNSTDBY; REG_SYSCTRL_XOSC &= ~(SYSCTRL_XOSC_ONDEMAND); // oscillateur toujours en fonctionnement en mode veille et standby REG_SYSCTRL_XOSC |= SYSCTRL_XOSC_AMPGC; // ajuste automatiquement le gain de l'oscillateur REG_GCLK_GENDIV = GCLK_GENDIV_ID(0x0) | GCLK_GENDIV_DIV(0x1); // sélectionne GCLK_GEN0 // fGCLK0 = fXOSC / GENDIV.DIV // fGCLK0 = 12*10^6 / 1 = 12MHz while(GCLK->STATUS.bit.SYNCBUSY == 1); // attend que la synchronisation entre // les domaines d'horloge est complète REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(0x0) | GCLK_GENCTRL_SRC_XOSC | GCLK_GENCTRL_GENEN; // sélectionne ID GCLK_GEN0 // XOSC comme source d'horloge // GCLK_GEN0 activé while(GCLK->STATUS.bit.SYNCBUSY == 1); // attend que la synchronisation entre // les domaines d'horloge est complète REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_SERCOM4_CORE | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; // sélectionne l'ID SERCOM4 // sélectionne GCLK_GEN0 // active l'horloge générique REG_PM_APBASEL |= PM_APBASEL_APBADIV_DIV1; // l'horloge APBA est divisée par 1 REG_PM_APBAMASK |= PM_APBAMASK_SYSCTRL; // L'horloge APBA pour SYSCTRL est activée. REG_PM_APBAMASK |= PM_APBAMASK_GCLK; // L'horloge APBA pour GCLK est activée. REG_PM_APBAMASK |= PM_APBAMASK_PM; // L'horloge APBA pour PM est activée. REG_PM_CPUSEL |= PM_CPUSEL_CPUDIV_DIV1; // fCPU = fGCLK0 / 1 // fCPU = 12MHz REG_PM_APBCSEL |= PM_APBCSEL_APBCDIV_DIV1; // fAPBC = fCPU = 12MHz REG_PM_APBCMASK |= PM_APBCMASK_SERCOM4; // active le bus d'horloge SERCOM4 }
usart_tx.c :Code:#include "sam.h" void usart_config() { REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_MODE_USART_INT_CLK; // sélectionne une horloge interne REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_CMODE; // choisis le mode synchrone //REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_RXPO(0x1); // SERCOM_PAD[1] est utilisé pour la réception REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_TXPO(0x0); // SERCOM_PAD[0] est utilisé pour la transmission REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_RUNSTDBY; REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_CHSIZE(0x0); // choisis une taille de caractère : 8 bits while(SERCOM4->USART.SYNCBUSY.bit.CTRLB == 1); // attend la que synchro 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); // pas de bit de parité REG_SERCOM4_USART_CTRLB &= ~(SERCOM_USART_CTRLB_SBMODE); // 1 bit stop while(SERCOM4->USART.SYNCBUSY.bit.CTRLB == 1); // attend la que synchro est complète REG_SERCOM4_USART_BAUD |= SERCOM_USART_BAUD_BAUD(0x270); // je veux une fBAUD = 9600 // fBAUD = FXOSC / 2*(BAUD + 1) // donc BAUD = (FXOSC / 2*fBAUD) - 1 // BAUD = 624 <=> 0x270 en hexa REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_TXEN; // active la transmission de données while(SERCOM4->USART.SYNCBUSY.bit.CTRLB == 1); // attend la que synchro est complète //REG_SERCOM4_USART_CTRLB |= SERCOM_USART_CTRLB_RXEN; // active la réception de données //while(SERCOM4->USART.SYNCBUSY.bit.CTRLB == 1); // attend la que synchro est complète REG_SERCOM4_USART_CTRLA |= SERCOM_USART_CTRLA_ENABLE; // active le périphérique SERCOM4 while(SERCOM4->USART.SYNCBUSY.bit.ENABLE == 1); // attend la que synchro est complète }
main.c :Code:#include "sam.h" int usart_tx() { if (SERCOM4->USART.INTFLAG.bit.DRE == 1) // si INTFLAG.DRE = 1, alors { REG_SERCOM4_USART_DATA |= 0x1; // écris "1" dans le registre DATA } }
Code:#include "sam.h" #include "definitions.h" #include "pin_config.h" #include "clock_config.h" #include "usart_config.h" #include "usart_tx.h" int main(void) { pin_config(); clock_config(); usart_config(); usart_tx(); while (1); }
-----