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

📄 gps source code.txt

📁 用单片机控制GPS模块C51源代码。。希望对大家了解单片机控制GPS有帮助。
💻 TXT
📖 第 1 页 / 共 5 页
字号:
    0xAE00, // ASCII = '.'  1010111
    0xD780, // ASCII = '/'  110101111
    0xB700, // ASCII = '0'  10110111
    0xBD00, // ASCII = '1'  10111101
    0xED00, // ASCII = '2'  11101101
    0xFF00, // ASCII = '3'  11111111
    0xBB80, // ASCII = '4'  101110111
    0xAD80, // ASCII = '5'  101011011
    0xB580, // ASCII = '6'  101101011
    0xD680, // ASCII = '7'  110101101
    0xD580, // ASCII = '8'  110101011
    0xDB80, // ASCII = '9'  110110111
    0xF500, // ASCII = ':'  11110101
    0xDE80, // ASCII = ';'  110111101
    0xF680, // ASCII = '<'  111101101
    0xAA00, // ASCII = '='  1010101
    0xEB80, // ASCII = '>'  111010111
    0xABC0, // ASCII = '?'  1010101111
    0xAF40, // ASCII = '@'  1010111101
    0xFA00, // ASCII = 'A'  1111101
    0xEB00, // ASCII = 'B'  11101011
    0xAD00, // ASCII = 'C'  10101101
    0xB500, // ASCII = 'D'  10110101
    0xEE00, // ASCII = 'E'  1110111
    0xDB00, // ASCII = 'F'  11011011
    0xFD00, // ASCII = 'G'  11111101
    0xAA80, // ASCII = 'H'  101010101
    0xFE00, // ASCII = 'I'  1111111
    0xFE80, // ASCII = 'J'  111111101
    0xBE80, // ASCII = 'K'  101111101
    0xD700, // ASCII = 'L'  11010111
    0xBB00, // ASCII = 'M'  10111011
    0xDD00, // ASCII = 'N'  11011101
    0xAB00, // ASCII = 'O'  10101011
    0xD500, // ASCII = 'P'  11010101
    0xEE80, // ASCII = 'Q'  111011101
    0xAF00, // ASCII = 'R'  10101111
    0xDE00, // ASCII = 'S'  1101111
    0xDA00, // ASCII = 'T'  1101101
    0xAB80, // ASCII = 'U'  101010111
    0xDA80, // ASCII = 'V'  110110101
    0xAE80, // ASCII = 'W'  101011101
    0xBA80, // ASCII = 'X'  101110101
    0xBD80, // ASCII = 'Y'  101111011
    0xAB40, // ASCII = 'Z'  1010101101
    0xFB80, // ASCII = '['  1111101110
    0xF780, // ASCII = '\'  111101111
    0xFD80, // ASCII = ']'  111111011
    0xAFC0, // ASCII = '^'  1010111111
    0xB680, // ASCII = '_'  101101101
    0xB7C0, // ASCII = '`'  1011011111
    0xB000, // ASCII = 'a'  1011
    0xBE00, // ASCII = 'b'  1011111
    0xBC00, // ASCII = 'c'  101111
    0xB400, // ASCII = 'd'  101101
    0xC000, // ASCII = 'e'  11
    0xF400, // ASCII = 'f'  111101
    0xB600, // ASCII = 'g'  1011011
    0xAC00, // ASCII = 'h'  101011
    0xD000, // ASCII = 'i'  1101
    0xF580, // ASCII = 'j'  111101011
    0xBF00, // ASCII = 'k'  10111111
    0xD800, // ASCII = 'l'  11011
    0xEC00, // ASCII = 'm'  111011
    0xF000, // ASCII = 'n'  1111
    0xE000, // ASCII = 'o'  111
    0xFC00, // ASCII = 'p'  111111
    0xDF80, // ASCII = 'q'  110111111
    0xA800, // ASCII = 'r'  10101
    0xB800, // ASCII = 's'  10111
    0xA000, // ASCII = 't'  101
    0xDC00, // ASCII = 'u'  110111
    0xF600, // ASCII = 'v'  1111011
    0xD600, // ASCII = 'w'  1101011
    0xDF00, // ASCII = 'x'  11011111
    0xBA00, // ASCII = 'y'  1011101
    0xEA80, // ASCII = 'z'  111010101
    0xADC0, // ASCII = '{'  1010110111
    0xDD80, // ASCII = '|'  110111011
    0xAD40, // ASCII = '}'  1010110101
    0xB5C0, // ASCII = '~'  1011010111
    0xED40  // ASCII = 127  1110110101
};

// The maximum ASCII length of a PSK 31 message.
#define PSK_MAX_PACKET 160

// State machine constants.
#define PSK_WAIT_MSG 0
#define PSK_TX_SYNC 1
#define PSK_TX_MESSAGE 2
#define PSK_TX_END 3

// The UTC time in seconds to send a PSK31 data stream.
#define PSK31_TIMESLOT 0

// Number of 0 bits to transmit at start of message.
#define PSK_SYNC_LENGTH 32

// Number of 0 bits to transmit at end of message.
#define PSK_END_LENGTH 8

// PSK 31 frequency and amplitude list for time slots 0 through 2.
const uint32_t PSK31_FREQ_LIST[] = { 0x6C2FA66, 0x9615B57, 0xC1124BA };
const uint16_t PSK31_AMP_LIST[] = { 0x14ff, 0x14ff, 0x1300 };

// Counts the number of 1mS time slices in each 32mS of a bit time.
uint8_t pskCount;

// The current PSK output character.
uint16_t pskData;

// The current DDS phase offset where true is 180 degreees and false is 0 degrees.
boolean pskPhase;

// Buffer that holds PSK packet.
char pskBuffer[PSK_MAX_PACKET];

// State machine variable that indicates current transmit state.
uint8_t pskMode;

// Last 4 bits that were transmitted.
uint8_t pskLastBits;

// Index into the PSK packet buffer.
uint8_t pskIndex;

/**
 *
 *   Create the PSK 31 packet.
 */
boolean psk31CreateDataPacket()
{
    int16_t altitude;
    uint16_t dop, speed, heading;
    char *latitude, *longitude;
    uint8_t utcHours, utcMinutes;

    // Wait for the $GPRMC message and parse the speed/heading data from it.
    if (!gpsWaitMessage (GPS_RMC_MSG))
        return false;

    speed = gpsParseSpeed();
    heading = gpsParseHeading();
        
    // Wait for the $GPGGA message and parse the rest of the data elements from it.
    if (!gpsWaitMessage (GPS_GGA_MSG))
        return false;
        
    altitude = gpsParseAltitude();
    latitude = gpsParseLatitude();
    longitude = gpsParseLongitude();
    dop = gpsParseDOP();

    utcHours = gpsParseHours();
    utcMinutes = gpsParseMinutes();

    // Line 1 - Header
    printf (psk31TxByte, "\n\n\nBalloon QSL www.kd7lmo.net\n");
    
    // Line 2 - Data with units.
    printf (psk31TxByte, "%02d%02dutc ", utcHours, utcMinutes);

    if (altitude > 100)
        printf (psk31TxByte, "%ld,", altitude / 100);
        
    printf (psk31TxByte, "%02ld0ft ", altitude % 100);

    psk31TxByte (gpsParseLatitudeOrdinal());
    psk31TxString (latitude, 2);
    psk31TxByte ('d');
    psk31TxString (latitude + 2, 2);
    psk31TxByte ('.');
    psk31TxString (latitude + 5, 2);
    printf (psk31TxByte, "m ");
    
    psk31TxByte (gpsParseLongitudeOrdinal());
    psk31TxString (longitude, 3);
    psk31TxByte ('d');
    psk31TxString (longitude + 3, 2);
    psk31TxByte ('.');
    psk31TxString (longitude + 6, 2);
    printf (psk31TxByte, "m ");
    
    printf (psk31TxByte, "%03ldmph@%03ldd ", speed, heading);

    printf (psk31TxByte, "%ld.%lddop\n", dop / 10, dop % 10);

    // Line 3 - Header / ident
    printf (psk31TxByte, "QSL www.kd7lmo.net de AC7ZT\n");

    // End of message line feeds.
    printf (psk31TxByte, "\n\n");

    // NULL terminate the string.
    psk31TxNull();
    
    return true;
}

/**
 *   Initialize the PSK 31 modulator.
 */
void psk31Init()
{
    pskCount = 0;
    pskData = 0x0000;
    pskIndex = 0;
    pskMode = PSK_WAIT_MSG;
    pskPhase = false;
    pskLastBits = 0x00;
}

/**
 *  Determine if the hardware if ready to a PSK 31 packet.
 *
 *  @return true if ready; otherwise false
 */
boolean psk31IsFree()
{
    if (pskMode == PSK_WAIT_MSG)
        return true;

    return false;
}

/**
 *   This method should be called every 1 milliseconds by the timer interrupt.
 */
void psk31TimeUpdate()
{
    // If we are waiting for a message, just return.
    if (pskMode == PSK_WAIT_MSG)
        return;

    // If our next bit is 0 (zero), ramp down the carrier.
    if (pskCount == 15)
        if ((pskData & 0x8000) == 0x0000)
            output_low (IO_OSK);

    // Every 32mS process the next bit.
    if (++pskCount == 32) {
        pskCount = 0;

        switch (pskMode) {
            case PSK_TX_SYNC:
                // Just toggle the phase during the sync sequence.
                if (pskPhase)
                    pskPhase = false;
                else
                    pskPhase = true;

                ddsPhase (pskPhase);

                // After we send the start sequence, send the message.
                if (--pskIndex == 0) {
                    pskMode = PSK_TX_MESSAGE;
                    pskIndex = 1;
                    pskData = PSK31_VARICODE[pskBuffer[0]];
                    pskLastBits = 0x0f;
                } // END if

                // Ramp the carrier back on.
                output_high (IO_OSK);

                break;

            case PSK_TX_MESSAGE:
                // Keep track of the last 4 bits we transmitted.
                pskLastBits = (pskLastBits << 1) & 0x0f;

                // If the data bit is a zero, toggle the phase.
                if ((pskData & 0x8000) == 0x0000) {
                    if (pskPhase)
                        pskPhase = false;
                    else
                        pskPhase = true;

                    ddsPhase (pskPhase);
                } else
                    pskLastBits |= 0x01;

                // Shift to the next bit.
                pskData = pskData << 1;

                // If the last 2 bits we sent were 0, then get the next byte.
                if ((pskLastBits & 0x0c) == 0x00)
                    // Stop when we find the NULL character.
                    if (pskBuffer[pskIndex] == 0) {
                        pskIndex = PSK_END_LENGTH;
                        pskMode = PSK_TX_END;
                        pskData = 0x0000;
                    } else {
                        // Get the next character in the buffer.
                        pskData = PSK31_VARICODE[pskBuffer[pskIndex++]];

                        // Reset the last bits shift register.
                        pskLastBits = 0x0f;
                    } // END if-else

                output_high (IO_OSK);
            
                break;

            case PSK_TX_END:
                // Just toggle the phase during the end sequence.
                if (pskPhase)
                    pskPhase = false;
                else
                    pskPhase = true;

                ddsPhase (pskPhase);

                if (--pskIndex == 0) {
                    // We are ready for a new mesasge.
                    pskMode = PSK_WAIT_MSG;

                    // Turn off the carrier.
                    output_low (IO_OSK);

                    // Turn off the PA.
                    sysPAOutput (false);
                } else
                    output_high (IO_OSK);

                break;
        } // END switch
    } // END if
}

/** 
 *    Generate and start transmision of PSK-31 message.  If a message is already
 *    being transmitted, nothing occurs.  The UTC time in minutes is required to set
 *    the DDS frequency.
 *
 *    @param minutes UTC time in minutes
 */
void psk31TxPacket(uint8_t minutes)
{
    // We can't create a packet if one is already in progress.
    if (pskMode != PSK_WAIT_MSG || !tncIsFree())
        return;

    // Set the pointer to the start of the buffer.
    pskIndex = 0;
        
    // If the packet generations fails, display a warning message.
    if (!psk31CreateDataPacket()) {
        pskIndex = 0;
        printf (psk31TxByte, "Ballooon QSL www.kd7lmo.net * Unable to generate telemetry\n\n");
        psk31TxNull();
    }
    
    // Select the PSK-31 real-time clock mode.
    timeSetMode (TIME_MODE_PSK31);
    
    // Configure the DDS for PSK-31 mode.
    ddsSetMode (DDS_MODE_PSK31);
    
    // Set the DDS frequency based on the time schedule that repeats every 6 minutes.
    ddsSetFreq (PSK31_FREQ_LIST[minutes % 3]);
    ddsSetAmplitude (PSK31_AMP_LIST[minutes % 3]);
    
    // Turn on the PA.
    sysPAOutput (true);

    // Prepare the variables that are used in the real-time clock interrupt.
    pskIndex = PSK_SYNC_LENGTH;
    pskCount = 0;
    pskData = 0x0000;
    pskMode = PSK_TX_SYNC;
}

/**
 *    Write <b>value</b> to the PSK 31 buffer.  Maintain the pointer
 *    to the buffer.  The value pskIndex must be set to 0 (zero)
 *    before calling this function for the first time.
 * 
 *    @param value to save to telemetry buffer
 */
void psk31TxByte (uint8_t value)
{
    if (pskIndex == PSK_MAX_PACKET)
        return;

    pskBuffer[pskIndex++] = value;
}

/**
 *    Write <b>length</b> characters of <b>string</b>.
 */
void psk31TxString (char *string, uint8_t length)
{
    while (length-- != 0)
        psk31TxByte (*string++);
}

void psk31TxNull ()
{
    psk31TxByte (0x00);
}

// ****************************************************************************
//   Serial port
//
// Note this size must be a power of 2, i.e. 2, 4, 8, 16, etc.
#define SERIAL_BUFFER_SIZE 64

// Mask to wrap around at end of circular buffer.  (SERIAL_BUFFER_SIZE - 1)
#define SERIAL_BUFFER_MASK 0x3f

// Index to the next free location in the buffer.
uint8_t serialHead;

// Index to the next oldest data in the buffer.
uint8_t serialTail;

// Buffer to hold serial data.
uint8_t serialBuffer[SERIAL_BUFFER_SIZE];

/**
 *   Determine if the FIFO contains data.
 *
 *   @return true if data present; otherwise false
 */
boolean serialHasData()
{
    if (serialHead == serialTail)
        return false;

    return true;
}

/** 
 *   Initialize the serial processor.
 */
void serialInit()
{
    serialHead = 0;
    serialTail = 0;
}

/**
 *   Get the oldest character from the FIFO.
 *
 *   @return oldest character; 0 if FIFO is empty
 */
uint8_t serialRead()
{
    uint8_t value;

    // Make sure we have something to return.
    if (serialHead == serialTail)
        return 0;

    // Save the value.
    value = serialBuffer[serialTail];

    // Update the pointer.
    serialTail = (serialTail + 1) & SERIAL_BUFFER_MASK;

    return value;
}

/**
 *   Read and store any characters in the PIC serial port in a FIFO.
 */
void serialUpdate()
{
    // If there isn't a character in the PIC buffer, just leave.
    while (kbhit()) {
        // Save the value in the FIFO.
        serialBuffer[serialHead] = getc();

        // Move the pointer to the next open space.
        serialHead = (serialHead + 1) & SERIAL_BUFFER_MASK;
    }
}


// ****************************************************************************
//   System methods
//

/**
 *    Calculate the CRC-16 CCITT of <b>buffer</b> that is <b>length</b> bytes long.
 *    The <b>crc</b> parameter allow the calculation on the CRC on multiple buffers.
 *
 *    @param buffer Pointer to data buffer.
 *    @param length number of bytes in data buffer
 *    @param crc starting value
 *
 *    @return CRC-16 of buffer[0 .. length]
 */
uint16_t sysCRC16(uint8_t *buffer, uint8_t length, uint16_t crc)
{
    uint8_t i, bit, value;

    for (i = 0; i < length; ++i) {
        value = buffer[i];

        for (bit = 0; bit < 8; ++bit) {
            crc ^= (value & 0x01);
            crc = ( crc & 0x01 ) ? ( crc >> 1 ) ^ 0x8408 : ( crc >> 1 );
            value = value >> 1;
        } // END for
    } // END for

    return crc ^ 0xffff;
}

/**
 *   Control the PA output.
 * 
 *   @param state true to turn on PA; otherwise false
 */
inline void sysPAOutput (boolean state)
{
    if (state)
        output_low (IO_PA);
    else
        output_high (IO_PA);

}

⌨️ 快捷键说明

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