⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gps source code.txt

📁 单片机串口控制GPS模块的程序
💻 TXT
📖 第 1 页 / 共 5 页
字号:

    setup_timer_3(T3_INTERNAL | T3_DIV_BY_1);
    setup_ccp2 (CCP_CAPTURE_RE | CCP_USE_TIMER3);
}

/**
 *   Verify the GPS engine is sending GGA and RMC messages.  If not,
 *   configure the GPS engine to send the proper data.
 *
 *   @return TRUE if GPS engine operation; otherwise FALSE
 */
boolean gpsSetup()
{
    uint8_t startTime;

    // We wait 3 seconds for a GPS update to give the engine time to start.
    startTime = timeGetTicks();

    while (timeGetTicks() - startTime < 30) {
        // Read the serial FIFO and process the GPS messages.
        gpsUpdate();

        // If the GPS state changed, then the GPS is running.
        if (gpsState != GPS_WAIT_MSG) {
            timeSetDutyCycle (TIME_DUTYCYCLE_10);
            return true;
        }
    } // END while

    // Set the baud rate for the Motorola binary mode.
    set_uart_speed(9600);

    // Wait for the UART buffer to empty.
    delay_ms(10);

    // Put the GPS engine in NMEA mode.
    puts ("@@Ci\001\053\015\012");

    // Wait for the GPS to switch modes.
    delay_ms(500);

    // Set the baud rate for NMEA-0183 messages.
    set_uart_speed(4800);

    // Send a couple <CR><LF> to clear the GPS engine buffer.
    delay_ms(100);
    puts ("\015\012");
    delay_ms(100);
    puts ("\015\012");
    delay_ms(100);

    // Tell the GPS to send GGA and RMC NMEA messages.
    puts ("$PMOTG,GGA,0001\015\012");
    delay_ms(100);
    puts ("$PMOTG,RMC,0001\015\012");
    delay_ms(100);

    return false;
}

/**
 *   Parse the altitude in tens of feet from the NMEA-0183 $GPGGA message.
 *
 *   @return altitude in tens of feet; otherwise 0 if invalid message
 */
int16_t gpsParseAltitude()
{
    uint8_t i, count;
    int32_t altitude;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 9)
        if (gpsBuffer[i++] == ',')
            ++count;

    if (count != 9)
        return 0;

    // Convert meters to tens of feet.  ft = (10000 * meters) / 30480
    altitude = atoi32(gpsBuffer + i) * 10000l;
    altitude /= 30480l;

    return altitude;
}

/**
 *   Parse the DOP in tenths from the NMEA-0183 $GPGGA message.
 *
 *   @return DOP; otherwise 0 if invalid message
 */
uint16_t gpsParseDOP()
{
    uint8_t i, count, dop;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 8)
        if (gpsBuffer[i++] == ',')
            ++count;

    if (count != 8)
        return 0;

    // Parse the DOP value x.x or xx.x.  Return 0 if the field is NULL.
    dop = 0;

    while (gpsBuffer[i] != 0 && gpsBuffer[i] != ',') {
        if (gpsBuffer[i] >= '0' && gpsBuffer[i] <= '9')
            dop = (dop * 10) + (gpsBuffer[i] - '0');

        ++i;
    } // END while

    return dop;
}

uint16_t gpsParseHeading()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 8)
        if (gpsBuffer[i++] == ',')
            ++count;
            
    // Convert knots to MPH
    return atol(gpsBuffer + i);
}

/**
 *   Determine if NMEA-0183 $GPGGA navigation fix is valid.
 *
 *   @return true for valid fix; otherwise false
 */
boolean gpsParseIsGGAValid()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 6)
        if (gpsBuffer[i++] == ',')
            ++count;

    // Indicate the solution is bad if the parse failed or the fix valid is set to '0'.
    if (count != 6 || gpsBuffer[i] != '1')
        return false;

    return true;
}

/**
 *   Determine if NMEA-0183 $GPRMC navigation fix is valid.
 *
 *   @return true for valid fix; otherwise false
 */
boolean gpsParseIsRMCValid()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 2)
        if (gpsBuffer[i++] == ',')
            ++count;

    // Indicate the solution is bad if the parse failed or the fix valid is set to 'V'.
    if (count != 2 || gpsBuffer[i] != 'A')
        return false;

    return true;
}

/**
 *   Parse the altitude in tens of feet from the NMEA-0183 $GPGGA message.
 *
 *   @return altitude in tens of feet; otherwise 0 if invalid message
 */
char *gpsParseLatitude()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 2)
        if (gpsBuffer[i++] == ',')
            ++count;

    return gpsBuffer + i;
}

char gpsParseLatitudeOrdinal()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 3)
        if (gpsBuffer[i++] == ',')
            ++count;
            
    return gpsBuffer[i];
}
/**
 *   Parse the altitude in tens of feet from the NMEA-0183 $GPGGA message.
 *
 *   @return altitude in tens of feet; otherwise 0 if invalid message
 */
char *gpsParseLongitude()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 4)
        if (gpsBuffer[i++] == ',')
            ++count;

    return gpsBuffer + i;
}
char gpsParseLongitudeOrdinal()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 5)
        if (gpsBuffer[i++] == ',')
            ++count;
            
    return gpsBuffer[i];
}

/**
 *   Parse the tracking satelite count from the NMEA-0183 $GPGGA message.
 *
 *   @return sat count; otherwise 0 if invalid message
 */
uint8_t gpsParseSatCount()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 7)
        if (gpsBuffer[i++] == ',')
            ++count;

    if (count != 7)
        return 0;

    // Parse the sat count field.
    return ((gpsBuffer[i] - '0') * 10) + (gpsBuffer[i + 1] - '0');
}

/**
 *   Parse the seconds from the UTC time in the NMEA-0183 $GPGGA or $GPRMC message.
 *
 *   @return GPS seconds; otherwise 0xff if invalid message
 */
uint8_t gpsParseSeconds()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 1)
        if (gpsBuffer[i++] == ',')
            ++count;

    if (count != 1)
        return 0xff;

    // Make sure our time stamp field contains all digits.
    while (gpsBuffer[i] != 0 && isdigit(gpsBuffer[i]) && i < 13)
        ++i;

    if (i != 13)
        return 0xff;

    return ((gpsBuffer[11] - '0') * 10) + (gpsBuffer[12] - '0');
}

/**
 *   Parse the minutes from the UTC time in the NMEA-0183 $GPGGA or $GPRMC message.
 *
 *   @return GPS minutes; otherwise 0xff if invalid message
 */
uint8_t gpsParseMinutes()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 1)
        if (gpsBuffer[i++] == ',')
            ++count;

    if (count != 1)
        return 0xff;

    // Make sure our time stamp field contains all digits.
    while (gpsBuffer[i] != 0 && isdigit(gpsBuffer[i]) && i < 13)
        ++i;

    if (i != 13)
        return 0xff;

    return ((gpsBuffer[9] - '0') * 10) + (gpsBuffer[10] - '0');
}

/**
 *   Parse the hours from the UTC time in the NMEA-0183 $GPGGA or $GPRMC message.
 *
 *   @return GPS minutes; otherwise 0xff if invalid message
 */
uint8_t gpsParseHours()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 1)
        if (gpsBuffer[i++] == ',')
            ++count;

    if (count != 1)
        return 0xff;

    // Make sure our time stamp field contains all digits.
    while (gpsBuffer[i] != 0 && isdigit(gpsBuffer[i]) && i < 13)
        ++i;

    if (i != 13)
        return 0xff;

    return ((gpsBuffer[7] - '0') * 10) + (gpsBuffer[8] - '0');
}

uint16_t gpsParseSpeed()
{
    uint8_t i, count;

    // Count the number of field delimiters until we find the desired one.
    i = 0;
    count = 0;

    while (gpsBuffer[i] != 0 && count != 7)
        if (gpsBuffer[i++] == ',')
            ++count;
            
    // Convert knots to MPH            
    return (atol (gpsBuffer + i) * 23l) / 20l;
}


/**
 *   Read the serial FIFO and process complete GPS messages.
 */
void gpsUpdate() 
{
    uint8_t value;

    // Only update the buffer if we are waiting for a message.
    if (gpsState != GPS_WAIT_MSG)
        return;

    // Continue to process until the FIFO is empty.
    while (serialHasData()) {
        // Get the character value.
        value = serialRead();

        // Save each character to the telemetry buffer to transmit later.
        gpsBuffer[gpsIndex] = value;

        // If we filled the buffer, then something is wrong and we need to reset.
        if (gpsIndex == GPS_BUFFER_SIZE - 1)
            gpsIndex = 0;

        // At the EOL determine and set the GPS state.
        if (value == 10) {
            if (gpsIndex > 15) {
                // NULL terminate the buffer.
                gpsBuffer[gpsIndex] = 0;

                // Reset the index pointer for the next message.
                gpsIndex = 0;

                // Set a flag for the desired message, otherwise we'll wait for the next one.
                if (strncmp(gpsBuffer, GPS_GGA_TEXT, 6) == 0) {
                    gpsState = GPS_GGA_MSG;
                    return;
                } // END if

                if (strncmp(gpsBuffer, GPS_RMC_TEXT, 6) == 0) {
                    gpsState = GPS_RMC_MSG;
                    return;
                } // END if
            }

            // This wasn't a valid message, so just start over.
            gpsIndex = 0;

        } else
            ++gpsIndex;

    } // END while
}

/**
 *   Wait up to 2.0 seconds for the GPS message of <b>messageType</b>.
 *
 *   @param messageType desired GPS message type <i>GPS_GGA_MSG</i> or <i>GPS_RMC_MSG</i>
 *
 *   @return TRUE if successful; otherwise false
 */
boolean gpsWaitMessage(uint8_t messageType)
{
    uint8_t startTime;

    // We already have the one we are looking for.
    if (gpsState == messageType)
        return true;

    // Clear the message type and wait for the new one.
    gpsState = GPS_WAIT_MSG;

    // Record the current time so we can time out.
    startTime = timeGetTicks();

    while (timeGetTicks() - startTime < 20) {
        gpsUpdate();

        // If we have the correct one, we are done.
        if (gpsState == messageType)
            return true;

        gpsState = GPS_WAIT_MSG;
    } // END while

    return false;
}


// ****************************************************************************
//   PSK 31 modulator
//

const uint16_t PSK31_VARICODE[] = 
{
    0xAAC0, // ASCII =   0  1010101011
    0xB6C0, // ASCII =   1  1011011011
    0xBB40, // ASCII =   2  1011101101
    0xDDC0, // ASCII =   3  1101110111
    0xBAC0, // ASCII =   4  1011101011
    0xD7C0, // ASCII =   5  1101011111
    0xBBC0, // ASCII =   6  1011101111
    0xBF40, // ASCII =   7  1011111101
    0xBFC0, // ASCII =   8  1011111111
    0xEF00, // ASCII =   9  11101111
    0xE800, // ASCII =  10  11101
    0xDBC0, // ASCII =  11  1101101111
    0xB740, // ASCII =  12  1011011101
    0xF800, // ASCII =  13  11111
    0xDD40, // ASCII =  14  1101110101
    0xEAC0, // ASCII =  15  1110101011
    0xBDC0, // ASCII =  16  1011110111
    0xBD40, // ASCII =  17  1011110101
    0xEB40, // ASCII =  18  1110101101
    0xEBC0, // ASCII =  19  1110101111
    0xD6C0, // ASCII =  20  1101011011
    0xDAC0, // ASCII =  21  1101101011
    0xDB40, // ASCII =  22  1101101101
    0xD5C0, // ASCII =  23  1101010111
    0xDEC0, // ASCII =  24  1101111011
    0xDF40, // ASCII =  25  1101111101
    0xEDC0, // ASCII =  26  1110110111
    0xD540, // ASCII =  27  1101010101
    0xD740, // ASCII =  28  1101011101
    0xEEC0, // ASCII =  29  1110111011
    0xBEC0, // ASCII =  30  1011111011
    0xDFC0, // ASCII =  31  1101111111
    0x8000, // ASCII = ' '  1
    0xFF80, // ASCII = '!'  111111111
    0xAF80, // ASCII = '"'  101011111
    0xFA80, // ASCII = '#'  111110101
    0xED80, // ASCII = '$'  111011011
    0xB540, // ASCII = '%'  1011010101
    0xAEC0, // ASCII = '&'  1010111011
    0xBF80, // ASCII = '''  101111111
    0xFB00, // ASCII = '('  11111011
    0xF700, // ASCII = ')'  11110111
    0xB780, // ASCII = '*'  101101111
    0xEF80, // ASCII = '+'  111011111
    0xEA00, // ASCII = ','  1110101
    0xD400, // ASCII = '-'  110101

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -