tablero de demostración PIC USART

1

Estoy tratando de crear una aplicación gps pero no obtengo buenos datos. He escuchado que el error más común es usar una velocidad de baudios no válida, pero por eso he tratado de verlo pero sin éxito. El PIC que estoy usando es un pic18f45k20 con el oscilador interno. El problema es que la variable rx en la función getPosition no obtiene un buen valor. También traté de cambiar ReadUSART a getcUsart pero obtengo el mismo valor con esas dos funciones. Estoy usando MPLAB X con el compilador xc8. También el módulo gps es enlace

Mi código para init:

#define _XTAL_FREQ 16000000
void initUsart(){
TRISCbits.RC6 = 0; //TX pin set as output
TRISCbits.RC7 = 1; //RX pin set as input

CloseUSART();
UART1Config = USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH ;
baud = 103;
OpenUSART(UART1Config,baud);

//compare with the table above
RCIF = 0; //reset RX pin flag
RCIP = 1; //High priority
RCIE = 1; //Enable RX interrupt
PEIE = 1; //Enable pheripheral interrupt (serial port is a pheripheral)

ei();       //remember the master switch for interrupt?

}

void setupClock()
{
OSCCONbits.IRCF0 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF2 = 1;
}

#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"
#define PMTK_SET_BAUD_9600 "$PMTK251,9600*17"

void initGps(){
for(int i = 0; i < 16; i++){
    WriteUSART(PMTK_SET_BAUD_9600[i]);
}
for(int i = 0; i < 15; i++){
    WriteUSART(PMTK_SET_NMEA_UPDATE_10HZ[i]);
}
for(int i = 0; i < 49; i++){
    WriteUSART(PMTK_SET_NMEA_OUTPUT_RMCONLY[i]);
}
}

código para leer:

void interrupt interrupts(){

if(PIR1bits.RCIF == 1)
{
    handleUsartRx();
}
if(INTCONbits.TMR0IF == 1)
{
    handleTmr0();
}
}

void handleUsartRx(){
struct Position position = getPosition();
//do stuff with position
PIR1bits.RCIF = 0; // clear rx flag
}
struct Position getPosition(){
struct Position position;
position.fixed = -1;
rx = ReadUSART(); //read the byte from rx register

if(rx == '$'){
    rxIndex = 0;
    for(int i = 0; i < 50; i++){
        receivedData[i] = '
#define _XTAL_FREQ 16000000
void initUsart(){
TRISCbits.RC6 = 0; //TX pin set as output
TRISCbits.RC7 = 1; //RX pin set as input

CloseUSART();
UART1Config = USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH ;
baud = 103;
OpenUSART(UART1Config,baud);

//compare with the table above
RCIF = 0; //reset RX pin flag
RCIP = 1; //High priority
RCIE = 1; //Enable RX interrupt
PEIE = 1; //Enable pheripheral interrupt (serial port is a pheripheral)

ei();       //remember the master switch for interrupt?

}

void setupClock()
{
OSCCONbits.IRCF0 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF2 = 1;
}

#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"
#define PMTK_SET_BAUD_9600 "$PMTK251,9600*17"

void initGps(){
for(int i = 0; i < 16; i++){
    WriteUSART(PMTK_SET_BAUD_9600[i]);
}
for(int i = 0; i < 15; i++){
    WriteUSART(PMTK_SET_NMEA_UPDATE_10HZ[i]);
}
for(int i = 0; i < 49; i++){
    WriteUSART(PMTK_SET_NMEA_OUTPUT_RMCONLY[i]);
}
}
'; } } receivedData[rxIndex] = rx; rxIndex++; //Dont know which is the end string if(strstr(&receivedData,"<CR><LF>") == NULL && strstr(&receivedData,"<CR> <LF>") == NULL){ return position; } //EndString is found, start parsing; char *parsedString[9]; splitNmeaString(parsedString); position = createPosition(parsedString); return position; }
    
pregunta user1842278

1 respuesta

1

Está procesando mucho dentro de su función handleUsartRx() antes de borrar el indicador de interrupción, y sospecho que su problema es que simplemente se están perdiendo muchos datos entrantes.

En particular, llama a strstr() dos veces, y esta es una función relativamente costosa en términos de ciclos de CPU.

Además, sus llamadas strstr() nunca tendrán éxito, ya que <CR> , etc. no es la manera correcta de denotar un carácter de control en una cadena C. Para un retorno de carro, por ejemplo, use \r o \x0D . El salto de línea sería \n o \x0A .

Como nunca encuentras el final de la cadena, tu búfer de datos sigue creciendo, lo que significa que el procesamiento de cada nuevo carácter lleva más tiempo.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas