hello, good morning everyone!I'm having trouble getting the UART of the SAMD21G18A microcontroller to work. This is the configuration code of the SERCOM 5 module in UART mode:
1.This code is uart.h
#ifndef _uart_H_ #define _uart_H_ /* DEFINICIONES DEL UART */ #define UART5 SERCOM5->USART extern void UART_Init(void); extern void UART_Tx(unsigned char DATO); extern unsigned char UART_Rx(void); #endif /* _uart_H_ */
2.This code is uart.c:
#include <samd21.h> #include "uart.h" void UART_Init(void) { GCLK->GENCTRL.reg=GCLK_CLKCTRL_ID_SERCOM5_CORE|GCLK_CLKCTRL_GEN_GCLK0; //Conecta el Generador generico 0 al SERCOM5 PM->APBCMASK.reg|=PM_APBCMASK_SERCOM5; //Habilita el bus que conecta al SERCOM 5 UART5.CTRLA.reg= UART5.CTRLA.reg|=SERCOM_USART_CTRLA_DORD; //LSB se transmite primero UART5.CTRLA.reg&=~SERCOM_USART_CTRLA_CMODE; //Seleccionamos la comunicacion asincrono UART5.CTRLA.reg|=SERCOM_USART_CTRLA_FORM(0x0); //Sin paridad UART5.CTRLA.reg|=SERCOM_USART_CTRLA_TXPO(0x1)|SERCOM_USART_CTRLA_RXPO(0x3); //Configuramos el PAD[2] como Tx y el PAD[3] como Rx UART5.CTRLA.reg|=SERCOM_USART_CTRLA_SAMPR(0x3);//Selecionamos una tasa de muestreo de 8x con BAUD fracional UART5.CTRLA.reg|=SERCOM_USART_CTRLA_MODE(0x1); //Usa el reloj interno UART5.CTRLB.reg|=SERCOM_USART_CTRLB_RXEN|SERCOM_USART_CTRLB_TXEN; //Habilita los pines Rx y Tx UART5.CTRLB.reg&=~SERCOM_USART_CTRLB_SBMODE; //Con un bit de stop UART5.CTRLB.reg|=SERCOM_USART_CTRLB_CHSIZE(0x0); //Selecciona el formato de 8 bits UART5.BAUD.reg=SERCOM_USART_BAUD_FRAC_BAUD(0x68)|SERCOM_USART_BAUD_FRAC_FP(0x4); UART5.CTRLA.reg|=SERCOM_USART_CTRLA_ENABLE; //Habilita el UART 5 while(UART5.SYNCBUSY.reg&SERCOM_USART_SYNCBUSY_ENABLE); //Espera a que se habilite el UART } void UART_Tx(unsigned char DATO) { while(UART5.INTFLAG.reg&SERCOM_USART_INTFLAG_DRE); UART5.DATA.reg=DATO; } unsigned char UART_Rx(void) { while(UART5.INTFLAG.reg&SERCOM_USART_INTFLAG_RXC); return (unsigned char)UART5.DATA.reg; }
and this is the function that configures the PB22(Tx) and PB23(Rx) ports as PAD [2] and PAD [3]
3.This code is gpio.h
#ifndef _gpio_H_ #define _gpio_H_ /* DEFINICIONES DE PUERTOS */ #define PORTB PORT->Group[1] extern void GPIO_Init(void); #endif /* _gpio_H_ */
4.This code is gpio.c
#include <samd21.h> //Device header #include "gpio.h" void GPIO_Init(void) { //Configuramos el PIN PB22 Tx PORTB.DIRSET.reg=PORT_PB22; PORTB.PINCFG[22].reg=PORT_PINCFG_PMUXEN; PORTB.PMUX[11].reg=PORT_PMUX_PMUXE(0x3); //Configuramos el PIN PB23 Rx PORTB.DIRCLR.reg=PORT_PB23; PORTB.PINCFG[23].reg=PORT_PINCFG_INEN|PORT_PINCFG_PMUXEN; PORTB.PMUX[11].reg=PORT_PMUX_PMUXO(0x3); }
and this is the main
#include <samd21.h> //Device header #include <stdbool.h> #include <stdint.h> #include "gpio.h" #include "uart.h" //VARIABLE GLOBALES static unsigned char c; int main(void) { SystemInit(); GPIO_Init(); UART_Init(); while(true) { c=UART_Rx(); UART_Tx(c); } }
According to what I try to do in this code is the ECO, I send and receive the same letter that I write in the PC. But it doesn't work, I made a debug but it stays in this line of code:
"while(UART5.SYNCBUSY.reg&SERCOM_USART_SYNCBUSY_ENABLE); //Espera a que se habilite el UART"
from uart.c, i don't know where the code is wrong. If you could help me I thank you in advance, thank you and have a nice day!
P.D: The operating frequency of the microcontroller is 8MHz and according to me it is asynchronous because it is connected to the GCLK0 which feeds the MAIN