Hola compañeros, hace siglos que no me paso por aquí. Mi vida ha dado unas cuantas vueltas y, después de unos añitos en la nevera, por fin vuelvo a programar un micro.
Esta vez me toca lidiar con un dsPIC33EP64GP502, es la primera vez que me meto con un dsPIC. Llevo ya unos días leyendo y aprendiendo cosas como el PPS que me parecen interesantísimas.
Bueno, al lío, lo que intento conseguir:
-Micro a 60MHz con reloj externo de 8MHz
-2 UART en el mismo micro
-La UART1 se dedica a la comunicación con el PC y va a 9600 baudios (RX en RP39 y TX en RP38)
-La UART2 va a tope (15Mbps) (RX en RP43 y TX en RP42)
-Utilizo MPLAB como compilador
Basicamente tengo todo funcionando, salvo la UART2, no consigo ver nada en la patilla RP42 con el osciloscopio. Si activo la función loopback funciona perfectamente, por lo que supongo que sera algun tema o de configuración o del mapeo de puertos. El resto de cosas están bien, consigo los 60MHZ de FCY, muestro las cadenas en el PC a traves de la UART1, etc.
Os pongo el código a ver si alguien me aporta algo de luz, estoy atascado
#include "p33EP64gp502.h"
#ifndef __DELAY_H
#define FOSC 120000000LL // clock-frequecy in Hz with suffix LL (64-bit-long), eg. 32000000LL for 32MHz
#define FCY (FOSC/2) // MCU is running at FCY MIPS
#define delay_us(x) __delay32(((x*FCY)/1000000L)) // delays x us
#define delay_ms(x) __delay32(((x*FCY)/1000L)) // delays x ms
#define __DELAY_H 1
#include <libpic30.h>
#include <uart.h>
#include <stdio.h>
#endif
#define BAUDRATE 15000000
#define BRGVAL ((FCY/BAUDRATE)/4)-1 //Valor para UART2 a 15Mbps
unsigned int i;
_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_EC & IOL1WAY_OFF);//Configuro clock externo
_FICD(JTAGEN_OFF); //Deshabilito JTAG
char Inicio[] = {'I','n','t','r','o','d','u','z','c','a',' ','c','a','r','a','c','t','e','r',' ','a',' ','e','n','v','i','a','r','\r','\n','\0'};
char Error[] = {'C','a','r','a','c','t','e','r',' ','r','e','t','o','r','n','a','d','o',' ','e','r','r','o','n','e','o','\r','\n','\0'};
char Retornado[] = {'C','a','r','a','c','t','e','r',' ','r','e','t','o','r','n','a','d','o',':',' ','\0'};
char Retardo[] = {'H','a',' ','t','a','r','d','a','d','o',':','\0'};
char Ns[] = {'n','s','\r','\n','\0'};
char Espacio[] = {'\r','\n','\0'};
char caracter;
char retorno;
char temp[10];
long tiempo;
int dato = 0;
/* Interrupción por recepción en UART2*/
void __attribute__((interrupt, no_auto_psv)) _U2RXInterrupt(void) {
tiempo = (TMR1*16.6)-1245;
T1CONbits.TON = 0;
retorno = U2RXREG;
dato =1;
IFS1bits.U2RXIF = 0;
LATA=2;
}
/* Main*/
int main ()
{
PLLFBD = 58;
CLKDIVbits.PLLPOST = 0;
CLKDIVbits.PLLPRE = 0; //Configuración 60MHz con EC a 8MHz
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);//Iniciamos cambio de clock
while (OSCCONbits.COSC != 0x3);//Esperamos a que se cumpla
/* Configuración UART1 a 9600*/
U1BRG = 389; //Baudrate
U1MODEbits.PDSEL = 00;
U1MODEbits.STSEL = 0;
U1MODEbits.ABAUD = 0;
U1MODEbits.BRGH = 0;//Modo baja velocidad
U1MODEbits.LPBACK = 0;
U2MODEbits.RXINV=1;
U2STAbits.UTXINV=1;
U1MODEbits.UARTEN = 1;
U1STAbits.UTXEN = 1;
RPOR2 = 0000000000000001;
RPINR18bits.U1RXR=39; //UART1 RX en RP39 y TX en RP38
/* Configuración UART2 a 15Mbps. Habilito interrupcion por recepción*/
U2BRG = BRGVAL; //0
U2MODEbits.PDSEL = 00;
U2MODEbits.STSEL = 0;
U2MODEbits.ABAUD = 0;
U2MODEbits.BRGH = 1;//modo alta velocidad
U2MODEbits.LPBACK = 0;
U2MODEbits.RXINV=1;
U2STAbits.UTXINV=1;
U2STAbits.URXISEL = 0;
IFS1bits.U2RXIF=0;
IEC1bits.U2RXIE=1;
U2MODEbits.UARTEN = 1;
U2STAbits.UTXEN = 1;
RPOR4 = 0000000000000011;
RPINR19bits.U2RXR=43;//UART2 RX en RP43 y TX en RP42
TRISA = 0x0000; //Puerto A como salida
ANSELA = 0xFFFC;//Los puertos A0 y A1 configurados como digitales para LED
T1CONbits.TON = 0; // Deshabilito Timer
T1CONbits.TCS = 0; // Reloj interno
T1CONbits.TGATE = 0; // Deshabilito el modo Gated Timer
T1CONbits.TCKPS = 0; // Preescaler 1:1
TMR1 = 0x00; // Pongo a 0 el registro
PR1 = 65535; // Valor del periodo
while(1){
putsUART1 ((unsigned int *)Inicio);//Mando cadena Inicio por la Uart lenta (comunica con el PC)
delay_ms(300);
LATA=1;
while(DataRdyUART1()==0);//Espero una entrada de caracter por teclado por Uart lenta
TMR1 = 0x00;
caracter = U1RXREG;// Almaceno el caracter introducido en una variable
T1CONbits.TON = 1;
U2TXREG = caracter;//Mando el caracter introducido a la uart rapida, iniciando antes el timer.
//Espero a que se active la interrupción por la RX de la uart rapida y ponga la variable datos a 1
while (dato == 0){};
//Muestro en pantalla mensajes con lo retornado
putsUART1 ((unsigned int *)Retornado);
delay_ms(100);
U1TXREG = retorno;
delay_ms(100);
putsUART1 ((unsigned int *)Espacio);
delay_ms(100);
if (retorno == caracter){
putsUART1 ((unsigned int *)Retardo);
delay_ms(100);
sprintf(temp,"%ld",tiempo);
putsUART1((unsigned int *)temp);
delay_ms(100);
putsUART1 ((unsigned int *)Espacio);
}
else{
putsUART1 ((unsigned int *)Error);
delay_ms(100);
putsUART1 ((unsigned int *)Espacio);
}
}
}
Muchísimas gracias de antemano