Manejo de EUSART

Hola,

Estoy probando a enviar un byte usando la EUSART con un PIC18F2550. Os doy algunos datos:

- Uso MPLAB X con C18
- Usaré un cristal de 12MHz y posteriormente deberé configurar el PIC internamente para conseguir los 48MHz para el USB.
- El baudrate que necesito es de 250k pero no tengo claro si debo calcularlo a partir de los 12Mhz o de los 48Mhz (250000 = FOSC/(16 ([SPBRGH:SPBRG] + 1))) :unsure:


He ojeado el datasheet y he deducido que debo usar la siguiente configuración para usar la EUSART, aunque seguro que algo falla o está mal. Por lo que si alguien me echa una mano..:

Código:
#include <stdio.h>
#include <stdlib.h>
#include <usart.h>

//Declaracion de funciones
void init();
void send_byte();


void main(void)
{
    init();
    send_byte();
}

void init()
{
    // Puerto C
    PORTC = 0x00;               // Inicializar puerto C
    TRISCbits.RC6 = 0;         // Configurar puerto como salida

    // ::: USART :::
    BAUDCONbits.RXDTP = 0;
    BAUDCONbits.TXCKP = 0;      // Datos de envio no invertidos
    BAUDCONbits.BRG16 = 0;      // Generador de baudrate de 8 bits, SPBRG
    //BAUDCONbits.WUE = 0;      // Deshabilitar Wake-up
    BAUDCONbits.ABDEN = 0;      // Autodetección de baudrate desactivada
    

    TXSTAbits.TX9 = 1;          // Activar transmision del 9º bit
    TXSTAbits.TXEN = 1;         // Habilitar transmision
    TXSTAbits.SYNC = 0;         // Seleccionar transmisión asíncrona
    TXSTAbits.SENDB = 0;        // No envío señal de break.
    TXSTAbits.BRGH = 1;         // Alta velocidad
    TXSTAbits.TX9D = 1;         // El 9º bit es un 1


    RCSTAbits.SPEN = 1;         // Activamos los puertos

    SPBRG = 11;              // 250 KBaudios a partir de 48 MHz. ¿¿¿correcto???

}

void send_byte()
{

    /* TXREG envía automáticamente (a TSR) y pone TRMT a 1 cuando ha
     acabado para que se le pueda cargar un nuevo BYTE (supongo)*/
    
    while(1)
    {
          TXREG = 0xFF; // Registro de 8 bits
          while (TXSTAbits.TRMT == 0); //TRMT is set when the TSR register is empty
    }
 
}

El código compila sin errores y al simularlo con proteus y un oscilador virtual veo la gráfica de la imagen adjunta.

La pregunta es, si estoy enviando continuamente 8+1 bytes en valor alto ¿por qué aparece ese pico en el osciloscopio? ¿no debería aparecer una línea siempre en valor alto?

¿podéis echarme una mano con el cálculo del baud rate que comentaba al principio?

Ni que decir tiene que soy un novato en estos temas ;)

Gracias!
 

Adjuntos

  • sim.gif
    sim.gif
    66.1 KB · Visitas: 13
Hola,
El "pico" que te aparece en el osciloscopio está bien. Lo que está mostrando el osciloscpio es una transmisión serial periódica del dato 0xFF. La parte a la que llamas pico es porque en las comunicaciones seriales de este tipo la trama está dada por: bit de inicio, 1 byte de datos, bit de fin.

El bit de inicio es 0, siempre 0 y eso es lo que ves. Luego hay 8 bits (1 byte) de 1s (0xFF) y por último el bit de fin que es 1.

Para el baud rate utilizá el valor de tu oscilador que es 12MHz*4 = 48MHz.

Cualquier duda preguntá.

Saludos!
 
Gracias por tu respuesta kuropatula!

Edito, que he dicho una tontería. Estaba un poco confuso pero se me han despejado las dudas con tu respuesta!
 
Última edición:
Hola espero me puedan ayudar ya que nunca he trabajado con este modulo, estoy trabajando con el 18f4550 en Mplab C18, por ahora solo estoy haciendo que si se pulsa RB0 envie un pulso y active RB0 en el otro, pero en si el fin del proyecto es tener 4 botones diferentes y dependiendo del que active en el otro pic pueda encender diferentes leds.

codigo:
Código:
/******************************* Archivos de cabecera ***************************/
#include <p18cxxx.h>
#include <stdio.h>

/**************************** Bits de configuracion *****************************/
#pragma config PLLDIV   = 5
#pragma config CPUDIV   = OSC1_PLL2	
#pragma config USBDIV   = 2         
#pragma config FOSC     = HSPLL_HS
#pragma config LVP      = OFF
#pragma config WDT      = OFF
#pragma config PWRT     = OFF
#pragma config MCLRE    = ON
#pragma config VREGEN   = ON
#pragma config BOR      = ON
#pragma config BORV     = 3
#pragma config CCP2MX   = ON
#pragma config STVREN   = ON
#pragma config WRTB     = ON
#pragma config FCMEN    = OFF
#pragma config IESO     = OFF
#pragma config WDTPS    = 32768
#pragma config LPT1OSC  = OFF
#pragma config PBADEN   = OFF
#pragma config ICPRT    = OFF       
#pragma config XINST    = OFF       
#pragma config CP0      = OFF
#pragma config CP1      = OFF
#pragma config CP2      = OFF
#pragma config CP3      = OFF
#pragma config CPB      = OFF
#pragma config CPD      = OFF
#pragma config WRT0     = OFF
#pragma config WRT1     = OFF
#pragma config WRT2     = OFF
#pragma config WRT3     = OFF       
#pragma config WRTC     = OFF
#pragma config WRTD     = OFF
#pragma config EBTR0    = OFF
#pragma config EBTR1    = OFF
#pragma config EBTR2    = OFF
#pragma config EBTR3    = OFF
#pragma config EBTRB    = OFF

/************************ Variables y redefiniciones ****************************/
#define			byteAlto	21	
#define			byteBajo	160
#define 		LED4		LATCbits.LATC1
unsigned char 	Ticks 		= 0;
unsigned char 	flag 		= 0;
unsigned char 	flag2 		= 0;

/****************************** Prototipos de funcion ********************************/
//void _startup(void);
void miInterrupcionAlta(void);
void inicializar(void);
void configurar_TMR0(void);
void configurar_EUSART(void);

/***************************** Remapeo ******************************************/
/*#pragma code reset = 0x1000
void reset(void)
{
	_asm goto _startup _endasm
}*/

#pragma code alto = 0x08
void alto(void)
{
	_asm goto miInterrupcionAlta _endasm
}
#pragma code

#pragma interrupt miInterrupcionAlta
void miInterrupcionAlta(void)
{
	if((INTCONbits.T0IE && INTCONbits.T0IF) == 1)
	{
		TMR0L = byteBajo;
		TMR0H = byteAlto;
		INTCONbits.T0IF = 0;
		
		Ticks ++;
	}
	if((PIE1bits.RCIE && PIR1bits.RCIF) == 1)
	{
		//TXREG = RCREG;
	}
}

/******************************* Programa principal **********************************/
void main(void)
{
	inicializar();
	
	while(1)
	{
		if(Ticks == flag && PORTBbits.RB0 == 1)
		{
			flag = Ticks + 2;
			PORTBbits.RB1 ^=1;
			TXREG=0xFF;
			while (TXSTAbits.TRMT == 0);
			//printf("Hola como estas?%c%c",13);
		}
		if (flag2 == Ticks)
		{
			flag2 = 50 + Ticks;
			LED4 ^= 1;
		}
	}
}
/************************ Prototipos de funcion, definiciones ************************/
void inicializar(void)
{
	TRISCbits.TRISC1 = 0;
	configurar_TMR0();
	configurar_EUSART();
}
void configurar_TMR0(void)
{
	INTCON = 0b10100000;
	TMR0L = byteBajo;
	TMR0H = byteAlto;
	T0CON = 0b10000000;
}
void configurar_EUSART(void)
{
	TRISBbits.TRISB0 = 1;
	TRISBbits.TRISB1 = 0;
	TRISCbits.TRISC7 = 1;	//Entrada para Rx
	TRISCbits.TRISC6 = 0;	//Salida para Tx
	TXSTA	= 0b00100110;
	RCSTA	= 0b10010000;
	BAUDCONbits.BRG16 = 1;
	SPBRG =	0xE1;
	SPBRGH = 0x4;
	PIE1bits.RCIE = 1;		//habilitamos interrupcion por recepcion USART
	//PIE1bits.TXIE = 1;		//habilitamos interrupcion por transmision USART
	INTCONbits.PEIE = 1;	//por perifericos
}

codigo del otro pic:
Código:
/******************************* Archivos de cabecera ***************************/
#include <p18cxxx.h>
#include <stdio.h>

/**************************** Bits de configuracion *****************************/
#pragma config PLLDIV   = 5
#pragma config CPUDIV   = OSC1_PLL2	
#pragma config USBDIV   = 2         
#pragma config FOSC     = HSPLL_HS
#pragma config LVP      = OFF
#pragma config WDT      = OFF
#pragma config PWRT     = OFF
#pragma config MCLRE    = ON
#pragma config VREGEN   = ON
#pragma config BOR      = ON
#pragma config BORV     = 3
#pragma config CCP2MX   = ON
#pragma config STVREN   = ON
#pragma config WRTB     = ON
#pragma config FCMEN    = OFF
#pragma config IESO     = OFF
#pragma config WDTPS    = 32768
#pragma config LPT1OSC  = OFF
#pragma config PBADEN   = OFF
#pragma config ICPRT    = OFF       
#pragma config XINST    = OFF       
#pragma config CP0      = OFF
#pragma config CP1      = OFF
#pragma config CP2      = OFF
#pragma config CP3      = OFF
#pragma config CPB      = OFF
#pragma config CPD      = OFF
#pragma config WRT0     = OFF
#pragma config WRT1     = OFF
#pragma config WRT2     = OFF
#pragma config WRT3     = OFF       
#pragma config WRTC     = OFF
#pragma config WRTD     = OFF
#pragma config EBTR0    = OFF
#pragma config EBTR1    = OFF
#pragma config EBTR2    = OFF
#pragma config EBTR3    = OFF
#pragma config EBTRB    = OFF

/************************ Variables y redefiniciones ****************************/
#define			byteAlto	21	
#define			byteBajo	160
#define 		LED4		LATCbits.LATC1
unsigned char 	Ticks 		= 0;
unsigned char 	flag 		= 0;
unsigned char 	flag2 		= 0;

/****************************** Prototipos de funcion ********************************/
//void _startup(void);
void miInterrupcionAlta(void);
void inicializar(void);
void configurar_TMR0(void);
void configurar_EUSART(void);

/***************************** Remapeo ******************************************/
/*#pragma code reset = 0x1000
void reset(void)
{
	_asm goto _startup _endasm
}*/

#pragma code alto = 0x08
void alto(void)
{
	_asm goto miInterrupcionAlta _endasm
}
#pragma code

#pragma interrupt miInterrupcionAlta
void miInterrupcionAlta(void)
{
	if((INTCONbits.T0IE && INTCONbits.T0IF) == 1)
	{
		TMR0L = byteBajo;
		TMR0H = byteAlto;
		INTCONbits.T0IF = 0;
		
		Ticks ++;
	}
	if((PIE1bits.RCIE && PIR1bits.RCIF) == 1)
	{
		//TXREG = RCREG;
			if ( RCREG== 1)
				PORTBbits.RB0=1;
			else
				PORTBbits.RB0=0;

	}
}

/******************************* Programa principal **********************************/
void main(void)
{
	inicializar();
	
	while(1)
	{
		if(Ticks == flag)
		{
			flag = Ticks + 2;
			//printf("Hola como estas?%c%c",13);
		
		}
		if (flag2 == Ticks)
		{
			flag2 = 50 + Ticks;
			LED4 ^= 1;
		}
	}
}
/************************ Prototipos de funcion, definiciones ************************/
void inicializar(void)
{
	TRISCbits.TRISC1 = 0;
	configurar_TMR0();
	configurar_EUSART();
}
void configurar_TMR0(void)
{
	INTCON = 0b10100000;
	TMR0L = byteBajo;
	TMR0H = byteAlto;
	T0CON = 0b10000000;
}
void configurar_EUSART(void)
{
	TRISBbits.TRISB0 = 0;
	TRISCbits.TRISC7 = 1;	//Entrada para Rx
	TRISCbits.TRISC6 = 0;	//Salida para Tx
	TXSTA	= 0b00100110;
	RCSTA	= 0b10010000;
	BAUDCONbits.BRG16 = 1;
	SPBRG =	0xE1;
	SPBRGH = 0x4;
	PIE1bits.RCIE = 1;		//habilitamos interrupcion por recepcion USART
	//PIE1bits.TXIE = 1;		//habilitamos interrupcion por transmision USART
	INTCONbits.PEIE = 1;	//por perifericos
}

Dejo una imagen de como lo conecto y de mi respuesta en el osciloscopio y muchas gracias.!!
 

Adjuntos

  • Osciloscopio.jpg
    Osciloscopio.jpg
    225.9 KB · Visitas: 6
Atrás
Arriba