Helpful ReplyHot!Junk characters UART -PIC18LF26K22

Author
Dartmoor
Starting Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/08/24 06:06:17
  • Location: London, United Kingdom
  • Status: offline
2017/09/10 15:56:17 (permalink)
0

Junk characters UART -PIC18LF26K22

Hi, 
I seem to be reading junk characters from the UART. The GPS module is connected to RC6, RC7. The FOSC has been set at 64MHz and the PLL is enabled. I hit a roadblock on the usart library here: http://www.microchip.com/forums/m1014266.aspx
 
Code snippet is taken from here: http://iradan.com/?p=812
 
 
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <p18lf26k22.h>
#include "font.h"
#include "time_delay.h"
#include <string.h>

char ctxt[120], wstr[120]; //buff NMEA string, working string
char str[60], c, latstr, lonstr, setstr;
char buffer[32] = "none"; //temp dump
volatile unsigned int ping, isrcall, index, reading, new_rx;
int ready, gpgga, gprmc, mode; //gps associated vars
long long position_set, position_now;

/*
 * Interrupt Service
 */
void interrupt ISR() {
   
   if (PIR1bits.RCIF){ // see if interrupt caused by incoming data
        isrcall = 0x01;
        char temp;
        temp = RCREG1; // read the incoming data
        
        if(temp=='$' && new_rx==0) //if first char of a GPS string..
        {
            index = 0; //reset index
            reading = 1; //from now on go to else if
            
        }
        else if(reading == 1) //in middle of GPS sentence
        {
            ctxt[index] = temp; //load it up
            index++; //increment index
            ping = 1; //this is for debugging
            if(index > 50) //thats more than enough data
                {
                index = 0; //reset index
                reading = 0; //no longer storing the string
                new_rx = 1; //"ding"
                
                }
        }
   }
}

void uart_xmit(unsigned int mydata_byte) { //send a character to the UART
    while(!TXSTA1bits.TRMT); // make sure buffer full bit is high before transmitting
    TXREG1 = mydata_byte; // transmit data
}

void uart_write(const char *txt) //sent a multiple characters
{
    while(*txt != 0) uart_xmit(*txt++); //this send a string to the TX buffer
                                            //one character at a time
}


void serial_init(void)
{
    //9600 8N1
    TXSTA1bits.BRGH=1; // select low speed Baud Rate
    TXSTA1bits.TX9=0; // select 8 data bits
    TXSTA1bits.TXEN = 1; // enable transmit
    
    RCSTA1bits.SPEN=1; // serial port is enabled
    RCSTA1bits.RX9=0; // select 8 data bits
    RCSTA1bits.CREN=1; // receive enabled
    
       
    SPBRG1=416; // here is calculated value of SPBRGH and SPBRGL
    SPBRGH1=0;
   
    
    PIR1bits.RCIF=0; // make sure receive interrupt flag is clear

    __delay_ms(50); // give time for voltage levels on board to settle
    uart_write("RESET"); // transmit some data for testing

}


/*
 * Append a string with a character
 * append(str, c);
 */


void append(char* s, char c)
{
        int len = strlen(s);
        s[len] = c;
        s[len+1] = '\0';
}

void lat(void){
    str[0] = wstr[17];
    str[1] = wstr[18];
    str[2] = wstr[19];
    str[3] = wstr[20]; // .21 is a decimal place
    str[4] = wstr[22];
    str[5] = wstr[23];
    str[6] = wstr[24];
    str[7] = wstr[25];

    position_now = atol(str);

    uart_write(str);
    uart_write(" ");

        //check to set position
    if (PORTCbits.RC4 && ready) {
        position_set = position_now;
    }

    if (position_set){
        if (position_now > (position_set + 3)) {
            //LATCbits.LATC1 = 1;
        } else {
            //LATCbits.LATC1 = 0;
        }
        
        if (position_now < (position_set - 3)) {
            //LATCbits.LATC0 = 1;
        } else {
            //LATCbits.LATC0 = 0;
        }
    }
        sprintf(buffer, "%lld", position_now);
        uart_write(buffer);
        uart_write(" ");
        sprintf(buffer, "%lld", position_set);
        uart_write(buffer);
    uart_write("\r");
}


void main(void){
int i;
char buffer1[20];
OSCCON = 0b01110000;
OSCTUNEbits.PLLEN = 1; // turn on the PLL 64 MHz
ANSELA = 0; ANSELB = 0; ANSELC = 0; //ANSELD = 0; ANSELE = 0;
PORTA = 0; PORTB = 0; PORTC = 0; PORTE = 0; //PORTD = 0;
TRISA = 0; TRISB = 0; TRISC = 0; TRISE = 0; //TRISD = 0;
INTCONbits.GIE = 0; //no interruptions please
TRISCbits.TRISC6 = 1; // input
TRISCbits.TRISC7 = 1; // input

ping = 0;
new_rx = 0;
isrcall = 0;
    
SPI1_Close();
SPI1_Init();
TFT2_Init();

serial_init();
//RCONbits.IPEN = 0;
PIE1bits.RC1IE = 1; //Enable RX Interrupt
INTCONbits.PEIE = 1; // Enable peripheral interrupt
INTCONbits.GIE = 1; // enable global interrupt
ready = 0;

while (1) {
isrcall = 0;
ping = 0;

if (ready){
    //LATCbits.LATC2 = 1;
}

//LATAbits.LATA2 = 1; //startup heartbeat LED
__delay_ms(1);
//LATAbits.LATA2 = 0;
    if (new_rx == 1) //got our string...
    {
        if (strstr(ctxt, "GPGGA"))
        {
            gpgga = 1;
            strncpy((char*)wstr, (char*)ctxt, sizeof(ctxt));
            
        }
        new_rx=0; //finished with GPS string
    }

    if (gpgga) {
        STS_LED = 0;
        if(ctxt[42] == '1') //this is the 43rd bit but we didn't drop the $ into the buffer
        { //If "$GPGGA" NMEA message has '1' sign in the 43rd
                                //position it means that tha GPS receiver has a position fix
                                //
        ready = 1; //This is my "locked" variable for future code
        STS_LED = 1; //LOCK LED
        }
    }

if (ready) {

    if (mode){

    }
    if (!mode) {
        lat();
    }

}
__delay_ms(149); //delay don't really even need to update this often
}

while(1){}
}

What could I be doing incorrectly? If someone could point me to a more optimal code snippet to set the UART correctly and read the GPS strings that would be of great help.
 
Thanks in advance
 
 
/D
post edited by Dartmoor - 2017/09/10 16:02:02
#1
qhb
Superb Member
  • Total Posts : 5783
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: online
Re: Junk characters UART -PIC18LF26K22 2017/09/10 16:05:11 (permalink)
+1 (1)
Dartmoor
...
The FOSC has been set at 64MHz and the PLL is enabled.

Are you sure you are running at the speed you think you are?
You did not show your config settings, so it's impossible for anyone else to confirm.
 
Did you check the string you are sending on a scope?
 
#2
CinziaG
rome burns :D
  • Total Posts : 3135
  • Reward points : 0
  • Joined: 2016/12/07 14:20:36
  • Location: Wien
  • Status: offline
Re: Junk characters UART -PIC18LF26K22 2017/09/10 16:14:17 (permalink) ☄ Helpfulby Dartmoor 2017/09/11 15:15:19
+1 (1)
Yeah,
and you'd need Error Checking in the USART anyway
#3
Dartmoor
Starting Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/08/24 06:06:17
  • Location: London, United Kingdom
  • Status: offline
Re: Junk characters UART -PIC18LF26K22 2017/09/10 16:24:32 (permalink)
0
qhb
Dartmoor
...
The FOSC has been set at 64MHz and the PLL is enabled.

Are you sure you are running at the speed you think you are?
You did not show your config settings, so it's impossible for anyone else to confirm.
 
Did you check the string you are sending on a scope?
 



#ifndef __BIT_SETTINGS_H
#define __BIT_SETTINGS_H
#include <xc.h>
#define _XTAL_FREQ 64000000
// PIC18F46K22 Configuration Bit Settings
// CONFIG1H
//#pragma config FOSC = HSMP // Oscillator Selection bits (HS oscillator (medium power 4-16 MHz))
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = ON // Primary clock enable bit (Primary clock is always enabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power-up Timer Enable bit (Power up timer disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 190 // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB<5:0> pins are configured as analog input channels on Reset)
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = ON // HFINTOSC Fast Start-up (HFINTOSC output and ready status are not delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit (T3CKI is on RC0)
//#pragma config P2BMX = PORTD2 // ECCP2 B output mux bit (P2B is on RD2)
#pragma config MCLRE = INTMCLR // RE3 input pin enabled; MCLR disabled
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-003FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (004000-007FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (008000-00BFFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (00C000-00FFFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-003FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (004000-007FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (008000-00BFFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (00C000-00FFFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (004000-007FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
#endif

#4
mbrowning
Caffeine Caffeine
  • Total Posts : 530
  • Reward points : 0
  • Joined: 2005/03/16 14:32:56
  • Location: Melbourne, FL
  • Status: offline
Re: Junk characters UART -PIC18LF26K22 2017/09/10 18:22:00 (permalink) ☄ Helpfulby Dartmoor 2017/09/11 15:15:04
+4 (4)
You've overwritten SPBRGH1 with 0
SPBRG1=416; // here is calculated value of SPBRGH and SPBRGL
SPBRGH1=0;

 
The first line sets SPBRG1=416 for 9600 baud (BRGH=1, BRG16=0)
416=0x1a0 so SPBRGL1 = 0xa0 and SPBRGH1 = 0x01
 
The second line sets SPBRGH1 = 0
so the new baud rate is with SPBRG=0xa0 = 160 for baud = 24,845

Mark
#5
Dartmoor
Starting Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/08/24 06:06:17
  • Location: London, United Kingdom
  • Status: offline
Re: Junk characters UART -PIC18LF26K22 2017/09/11 13:51:05 (permalink)
+1 (1)
mbrowning
You've overwritten SPBRGH1 with 0
SPBRG1=416; // here is calculated value of SPBRGH and SPBRGL
SPBRGH1=0;

 
The first line sets SPBRG1=416 for 9600 baud (BRGH=1, BRG16=0)
416=0x1a0 so SPBRGL1 = 0xa0 and SPBRGH1 = 0x01
 
The second line sets SPBRGH1 = 0
so the new baud rate is with SPBRG=0xa0 = 160 for baud = 24,845


Over the last 20 odd hours I've been at it continually and tried several option read as much as I could but I still get junk chars for each combination of options.
Any pointers (pun not intended) will be helpful.
 


#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <p18lf26k22.h>
#include "bit_settings.h"
#include "spi_pic18f.h"
#include "ili9341.h"
#include "font.h"
#include "time_delay.h"
#include <string.h>
char ctxt[120], wstr[120]; //buff NMEA string, working string
char str[60], c, latstr, lonstr, setstr;
char buffer[32] = "none"; //temp dump
volatile unsigned int ping, isrcall, index, reading, new_rx;
int ready, gpgga, gprmc, mode; //gps associated vars
long long position_set, position_now;
char buffer1[20];
unsigned long int ii;
/*
* Interrupt Service
*/
void interrupt ISR() {

if (PIR1bits.RCIF){ // see if interrupt caused by incoming data
isrcall = 0x01;
char temp;
temp = RCREG1; // read the incoming data
if(temp=='$' && new_rx==0) //if first char of a GPS string..
{
index = 0; //reset index
reading = 1; //from now on go to else if

}
else if(reading == 1) //in middle of GPS sentence
{
ctxt[index] = temp; //load it up
index++; //increment index
ping = 1; //this is for debugging
if(index > 50) //thats more than enough data
{
index = 0; //reset index
reading = 0; //no longer storing the string
new_rx = 1; //"ding"

}
}
}
}
void uart_xmit(unsigned int mydata_byte) { //send a character to the UART
while(!TXSTA1bits.TRMT); // make sure buffer full bit is high before transmitting
TXREG1 = mydata_byte; // transmit data
}
void uart_write(const char *txt) //sent a multiple characters
{
while(*txt != 0) uart_xmit(*txt++); //this send a string to the TX buffer
//one character at a time
}
 
void serial_init()
{
TXSTA1bits.BRGH1=0; // select low speed Baud Rate
TXSTA1bits.TX9=0; // select 8 data bits
TXSTA1bits.TXEN = 1; // enable transmit
TXSTA1bits.SYNC = 0;

RCSTA1bits.SPEN=1; // serial port is enabled
RCSTA1bits.RX9=0; // select 8 data bits
RCSTA1bits.CREN=1; // receive enabled
PIR1bits.RCIF=0; // make sure receive interrupt flag is clear
SPBRG1 = 103;
__delay_ms(50); // give time for voltage levels on board to settle
}

/*
* Append a string with a character
* append(str, c);
*/
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
void lat(void){
str[0] = wstr[17];
str[1] = wstr[18];
str[2] = wstr[19];
str[3] = wstr[20]; // .21 is a decimal place
str[4] = wstr[22];
str[5] = wstr[23];
str[6] = wstr[24];
str[7] = wstr[25];
position_now = atol(str);
uart_write(str);
uart_write(" ");
//check to set position
if (PORTCbits.RC4 && ready) {
position_set = position_now;
}
if (position_set){
if (position_now > (position_set + 3)) {
//LATCbits.LATC1 = 1;
} else {
//LATCbits.LATC1 = 0;
}

if (position_now < (position_set - 3)) {
//LATCbits.LATC0 = 1;
} else {
//LATCbits.LATC0 = 0;
}
}
sprintf(buffer, "%lld", position_now);
uart_write(buffer);
uart_write(" ");
sprintf(buffer, "%lld", position_set);
uart_write(buffer);
uart_write("\r");
}

void main(void){
int i;
OSCCON = 0b01110000;
OSCTUNEbits.PLLEN = 1; // turn on the PLL 64 MHz
ANSELA = 0; ANSELB = 0; ANSELC = 0; //ANSELD = 0; ANSELE = 0;
PORTA = 0; PORTB = 0; PORTC = 0; PORTE = 0; //PORTD = 0;
TRISA = 0; TRISB = 0; TRISC = 0; TRISE = 0; //TRISD = 0;
INTCONbits.GIE = 0; //no interruptions please
TRISCbits.TRISC6 = 1; // input
TRISCbits.TRISC7 = 1; // input
ping = 0;
new_rx = 0;
isrcall = 0;

SPI1_Close();
SPI1_Init();
TFT_Init();
serial_init();
//RCONbits.IPEN = 0;
PIE1bits.RC1IE = 1; //Enable RX Interrupt
INTCONbits.PEIE = 1; // Enable peripheral interrupt
INTCONbits.GIE = 1; // enable global interrupt
ready = 0;
isrcall = 0;
ping = 0;
while (1)
{
if (ready){
//LATCbits.LATC2 = 1;
}
//LATAbits.LATA2 = 1; //startup heartbeat LED
__delay_ms(1);
//LATAbits.LATA2 = 0;

if (new_rx == 1) //got our string...
{
if (strstr(ctxt, "GPGGA"))
{
gpgga = 1;
strncpy((char*)wstr, (char*)ctxt, sizeof(ctxt));

}
new_rx=0; //finished with GPS string
}
if (gpgga) {
STS_LED = 0;
if(ctxt[42] == '1') //this is the 43rd bit but we didn't drop the $ into the buffer
{ //If "$GPGGA" NMEA message has '1' sign in the 43rd
//position it means that tha GPS receiver has a position fix
//
ready = 1; //This is my "locked" variable for future code
STS_LED = 1; //LOCK LED
}
}
if (ready) {
if (mode){
}
if (!mode) {
lat();
}
}
__delay_ms(149); //delay don't really even need to update this often
}
}

#6
CinziaG
rome burns :D
  • Total Posts : 3135
  • Reward points : 0
  • Joined: 2016/12/07 14:20:36
  • Location: Wien
  • Status: offline
Re: Junk characters UART -PIC18LF26K22 2017/09/11 14:12:53 (permalink) ☄ Helpfulby Dartmoor 2017/09/11 15:14:56
+1 (1)
same as above. Also, that long delay down there is a good candidate for a possible overrun error...
#7
Aussie Susan
Super Member
  • Total Posts : 2892
  • Reward points : 0
  • Joined: 2008/08/18 22:20:40
  • Location: Melbourne, Australia
  • Status: offline
Re: Junk characters UART -PIC18LF26K22 2017/09/11 20:22:05 (permalink) ☄ Helpfulby Dartmoor 2017/09/13 15:53:02
+2 (2)
- Remove the processor specific #include: the include of the xc.h will do that for you
- in the ISR, check for BOTH the IF and IE bits being set
- you seem to have a lot of additional code in there. Try writing a simple program (with the same config settings) that just sends a known character string through the UART and get that working first.
Susan
#8
Dartmoor
Starting Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/08/24 06:06:17
  • Location: London, United Kingdom
  • Status: offline
Re: Junk characters UART -PIC18LF26K22 2017/09/13 15:53:48 (permalink)
+1 (1)
Aussie Susan
- Remove the processor specific #include: the include of the xc.h will do that for you
- in the ISR, check for BOTH the IF and IE bits being set
- you seem to have a lot of additional code in there. Try writing a simple program (with the same config settings) that just sends a known character string through the UART and get that working first.
Susan


Thanks!! :-) I have the code working now!! Cheers. I have one more problem though, but will put it in a new post.
#9
qhb
Superb Member
  • Total Posts : 5783
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: online
Re: Junk characters UART -PIC18LF26K22 2017/09/13 16:05:13 (permalink) ☄ Helpfulby Dartmoor 2017/09/14 08:03:23
+3 (3)
Dartmoor
...
Thanks!! :-) I have the code working now!! Cheers. I have one more problem though, but will put it in a new post.

Please don't start a new topic. Continue in this one, then you don't have to explain the background again.
 
#10
Jump to:
© 2017 APG vNext Commercial Version 4.5