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

Parents Reply Children
No data