This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problems using the UART module of the SAMD21

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