If statement in C not evaluating properly?

193 Views Asked by At

I'm currently programming a TI MSP430 in C... I'm having a bizarre issue in the debugger that displays the if statement as satisfying the conditions to step forward but not doing so while running. Any ideas? The if statement not being evaluated in the function is between the asterisks.

void gps_parse(void){
  gps_write();
  lcd_out("                ", LCD_LINE_1);
  lcd_out("                ", LCD_LINE_2);
  lcd_out(GPSlat, LCD_LINE_1);
  lcd_out(GPSlong, LCD_LINE_2);
  SW2Press = NOT_PRESSED;
  while(!SW2Press){
    if (GPS_rx_ring_rd != GPS_rx_ring_wr) {
      **if (GPS_Char_Rx[GPS_rx_ring_rd] == '$')**{
        if (++GPS_rx_ring_rd >= (64)) {
          GPS_rx_ring_rd = BEGINNING;
        }
        char GPS_data[64];
        for (int i = 0; i < 64; i++) {
          while(GPS_rx_ring_rd == GPS_rx_ring_wr);
          GPS_data[i] = GPS_Char_Rx[GPS_rx_ring_rd];
          if (++GPS_rx_ring_rd >= (64)) {
            GPS_rx_ring_rd = 0; // Circular buffer back to beginning
          }
        }
    if(GPS_data[0] == 'G' && GPS_data[1] == 'P' && GPS_data[2] == 'R' && GPS_data[3] == 'M' && GPS_data[4] == 'C'){
      if(GPS_data[17] == 'A'){
        //Fill in lats
        GPSlat[4]  = GPS_data[19]; 
        GPSlat[5]  = GPS_data[20]; 
        GPSlat[6]  = GPS_data[21]; 
        GPSlat[7]  = GPS_data[22]; 
        GPSlat[8]  = GPS_data[23]; 
        GPSlat[9]  = GPS_data[24]; 
        GPSlat[10] = GPS_data[25]; 
        GPSlat[11] = GPS_data[26];   
        GPSlat[12] = GPS_data[27];
        GPSlat[15] = GPS_data[29];
        //Fill in longs
        GPSlong[4]  = GPS_data[31]; 
        GPSlong[5]  = GPS_data[32]; 
        GPSlong[6]  = GPS_data[33]; 
        GPSlong[7]  = GPS_data[34]; 
        GPSlong[8]  = GPS_data[35]; 
        GPSlong[9]  = GPS_data[36]; 
        GPSlong[10] = GPS_data[37]; 
        GPSlong[11] = GPS_data[38];   
        GPSlong[12] = GPS_data[39];
        GPSlong[13] = GPS_data[40];
        GPSlong[15] = GPS_data[42];
      } else{
        GPSlat[15]  = '?';
        GPSlong[15] = '?';
      }
      lcd_out(GPSlat, LCD_LINE_1);
      lcd_out(GPSlong, LCD_LINE_2);
    }
    else {
        if (++GPS_rx_ring_rd >= (64)) {
          GPS_rx_ring_rd = 0;
          }    
        }
      }
    }  
 }
}
2

There are 2 best solutions below

0
On

Try disabling compiler optimization. Sometimes, due to optimized code, code paths look bizarre in debugger.

0
On
// the following compiles, but has not been run.
// it corrects the obvious logic errors
// it corrects certain coding errors
// and corrects certain erroneous assumptions
// I added several data definitions so it would compile

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern int SW2Press;
extern int GPS_rx_ring_rd; // contains next char index to extract from circular buffer
extern int GPS_rx_ring_wr; // contains next char index to write to circular buffer
extern char *GPS_Char_Rx;

void gps_parse(void);
void gps_write(void);
void lcd_out( char*, int);

#define LCD_LINE_1 (1)
#define LCD_LINE_2 (2)
#define MASK64     (0x40)
#define NOT_PRESSED (0)


void gps_parse()
{
    // GPS_rx_ring_rd is a counter into a circular buffer
    // GPS_rx_ring_wr is a counter into a circular buffer
    // ??perhaps as head/tail indexes??

    // the variables GPS_Lat[] and GPS_Long[]
    // are set/used locally, so probably should be local variables, on the stack
    char GPSlat[17] = {'\0'};
    char GPSlong[17] = {'\0'};
    strcat(GPSlat, "lat ");
    strcat(GPSlong, "Long");

    // start GPS sending NMEA messages
    gps_write();

    // initialize the LCD display
    lcd_out("                ", LCD_LINE_1);
    lcd_out("                ", LCD_LINE_2);
    lcd_out(GPSlat, LCD_LINE_1);
    lcd_out(GPSlong, LCD_LINE_2);

    SW2Press = NOT_PRESSED; // global variable

    char GPS_data[64];
    int  i = 0;

    while(!SW2Press)
    { // while waiting for button press

        // following assumes that GPS_rx_ring_rd
        // points to next char to consume
        // and should be initialized to same value as GPS_rx_ring_wr


        if ( GPS_rx_ring_rd != GPS_rx_ring_wr )
        { // then, next char(s) has been input

            // code needs to increment/wrap GPS_rs_ring_rd
            // even when current char is NOT a '$'
            // note: always put literal on left so compiler can catch
            // '=' rather than '=='


            // only when current char is a '$'
            // should following code be executed

            if ( '$' == GPS_Char_Rx[GPS_rx_ring_rd] )
            {   // then, current checked char is '$'
                // I.E. start of a new GPS message

                GPS_rx_ring_rd++; // step past '$'
                GPS_rx_ring_rd = (GPS_rx_ring_rd>= MASK64)? GPS_rx_ring_rd : 0;


                // clear old trash from extracted buffer
                memset( GPS_data, 0x00, sizeof(GPS_data) );

                // for next 64 bytes input, extract bytes from
                // circular buffer to array
                // the assumption that each GPS message actually 64 bytes long
                // is not true
                // far better to stop extracting when 'next' char
                // to extract is '$'
                for ( i = 0; i < sizeof(GPS_data); i++)
                {
                    // wait for next available char from GPS??
                    while(GPS_rx_ring_rd == GPS_rx_ring_wr);

                    if( '$' == GPS_Char_Rx[GPS_rx_ring_rd])
                    { // then, all of current GPS message is extracted
                        break;
                    }

                    // extract next GPS char from circular buffer
                    GPS_data[i] = GPS_Char_Rx[GPS_rx_ring_rd];


                    // make special case not special
                    // if at end of circular buffer, wrap to beginning.
                    GPS_rx_ring_rd++;
                    GPS_rx_ring_rd = (GPS_rx_ring_rd>= MASK64)? GPS_rx_ring_rd : 0;
                } // end for


                if(    GPS_data[0] == 'G'
                    && GPS_data[1] == 'P'
                    && GPS_data[2] == 'R'
                    && GPS_data[3] == 'M'
                    && GPS_data[4] == 'C')
                { // then, GPS message type GPRMC - minimum recommended data

                    // for SIRF chip set
                    // $GPRMC,120557.916,A,5058.7456,N,00647.0515,E,0.00,82.33,220503,,*39

                    if(GPS_data[17] == 'A')
                    { // then, full data set available

                        //Fill in latitude
                        GPSlat[4]  = GPS_data[19]; //degree - range 0...90
                        GPSlat[5]  = GPS_data[20]; //degree
                        GPSlat[6]  = GPS_data[21]; //minute - range 0...59
                        GPSlat[7]  = GPS_data[22]; //minute
                        GPSlat[8]  = GPS_data[23]; //decimal point
                        GPSlat[9]  = GPS_data[24]; //fraction of minute
                        GPSlat[10] = GPS_data[25]; //fraction of minute
                        GPSlat[11] = GPS_data[26]; //fraction of minute
                        GPSlat[12] = GPS_data[27]; //fraction of minute
                        GPSlat[15] = GPS_data[29]; // N or S or blank

                        //Fill in longitude
                        GPSlong[4]  = GPS_data[31]; //degree - range 0...360
                        GPSlong[5]  = GPS_data[32]; //degree
                        GPSlong[6]  = GPS_data[33]; //degree
                        GPSlong[7]  = GPS_data[34]; //minute - range 0...59
                        GPSlong[8]  = GPS_data[35]; //minute
                        GPSlong[9]  = GPS_data[36]; //decimal point
                        GPSlong[10] = GPS_data[37]; //fraction of minute
                        GPSlong[11] = GPS_data[38]; //fraction of minute
                        GPSlong[12] = GPS_data[39]; //fraction of minute
                        GPSlong[13] = GPS_data[40]; //fraction of minute
                        GPSlong[15] = GPS_data[42]; // E or W or blank
                    }
                    else
                    { // full data set not available

                        GPSlat[15]  = '?'; // use old data and N/S byte indicates old data
                        GPSlong[15] = '?'; // use old data and E/W byte indicates old data
                    }

                    // update the LCD display
                    lcd_out(GPSlat, LCD_LINE_1);
                    lcd_out(GPSlong, LCD_LINE_2);
                }
                else
                { // else not a $GPRMC message

                    ; // do nothing
                } // end if
            }
            else
            { // else, step to next char

                ; do nothing
            } // end if
        } // end if

        // make special case to be not special
        // if at end of circular buffer, wrap to beginning
        GPS_rx_ring_rd++;
        GPS_rx_ring_rd = (GPS_rx_ring_rd>= MASK64)? GPS_rx_ring_rd : 0;
    } // end while
} // end gps_parse