Please note: We are aware of an issue affecting replies on the Arm Community forums, which may not be loading as expected.

We apologize for any inconvenience and appreciate your patience while we investigate and work to resolve the issue.

Thank you for your understanding.


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 of the SAMD21

I have a problem running the UART, the microcontroller I am using is the SAMD21G18A and this is the code:

this 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_ */

this 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 pin configuration

#ifndef _gpio_H_
#define _gpio_H_

/* DEFINICIONES DE PUERTOS */
#define PORTB PORT->Group[1]

extern void GPIO_Init(void);

#endif /* _gpio_H_ */

this 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);
}

#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;
}
	

The exercise that I try to do is the famous ECO, that is to say that I try that what I write in the Tx sends it again by the Rx bus, I modified it and I have tried it by the debug and it stays in the line of the uart.c

while(UART5.SYNCBUSY.reg&SERCOM_USART_SYNCBUSY_ENABLE); //Espera a que se habilite el UART

i don't know if the uart configuration is wrong or missing, i got this code from a book:

"Atmel ARM Programming for Embedded Systems"

authors:

Muhammad Ali Mazidi,
Shujen Chen,
Eshragh Ghaemi.

i want to know if this book is wrong and so recommended is that book or I have it wrong, thank you very much and i hope your answer soon. Before I forget, the operating frequency of the microcontroller is 8 MHz