GPS导航电文编码与校验
?導(dǎo)航電文包含衛(wèi)星的時(shí)間和位置信息,是進(jìn)行導(dǎo)航定位不可缺少的起算數(shù)據(jù)。導(dǎo)航電文,又稱為數(shù)據(jù)碼或 D 碼,包含有關(guān)衛(wèi)星的星歷、衛(wèi)星工作狀態(tài)、時(shí)間系統(tǒng)、衛(wèi)星鐘運(yùn)行狀態(tài)等信息,是衛(wèi)星信號(hào)的重要組成部分,也是用戶利用衛(wèi)星進(jìn)行定位的數(shù)據(jù)基礎(chǔ)。
1 編碼及校驗(yàn)計(jì)算
根據(jù) GPS ICD-200 規(guī)定,導(dǎo)航電文子幀以字為單位組成,字結(jié)構(gòu)如圖所示,每個(gè)字由24 位比特?cái)?shù)據(jù)位和 6 比特的奇偶校驗(yàn)位組成。采用奇偶校驗(yàn)可以檢驗(yàn)接受端和發(fā)送端數(shù)據(jù)是否一致,從而提高數(shù)據(jù)傳輸質(zhì)量。下面給出傳輸導(dǎo)航電文的校驗(yàn)過程。
D1 = d1⊕D*30
D2 = d2⊕D*30
D3 = d3⊕D*30
D4 = d4⊕D*30
......
D24 = d24⊕D*30
D25 =D*29⊕d1⊕d2⊕d3⊕d5⊕d6⊕d10⊕d11⊕d12⊕d14⊕d14⊕d17⊕d18⊕d20⊕d23
D26 =?D*30⊕d2⊕d3⊕d4⊕d6⊕d7⊕d11⊕d12⊕d14⊕d14⊕d15⊕d18⊕d19⊕d21⊕d24
D27 =?D*29⊕d1⊕d3⊕d4⊕d5⊕d7⊕d8⊕d12⊕d13⊕d14⊕d15⊕d16⊕d19⊕d20⊕d22
D28 =?D*30⊕d2⊕d4⊕d5⊕d6⊕d8⊕d9⊕d13⊕d14⊕d15⊕d16⊕d17⊕d20⊕d21⊕d23
D29 =?D*30⊕d1⊕d3⊕d5⊕d6⊕d7⊕d9⊕d10⊕d14⊕d15⊕d16⊕d17⊕d18⊕d21⊕d22⊕d24
D30 =?D*29⊕d3⊕d5⊕d6⊕d8⊕d9⊕d10⊕d11⊕d13⊕d15⊕d19⊕d22⊕d23⊕d24
?
式中d1-d24為原始數(shù)據(jù)位;D25-D30為通過公式計(jì)算得到的6比特奇偶校驗(yàn)碼位;D1-D30為傳輸?shù)谋忍匚?#xff1b;D*29,D*30為每一子幀中上一個(gè)字的最后兩位數(shù)據(jù)。需要注意的是第 1 子幀第 2字奇偶校驗(yàn)最后兩位必須設(shè)置為 0,每一個(gè)子幀的最后一個(gè)字的奇偶校驗(yàn)最后兩位也必須為0,為了保證該兩位置零,通常利用該字的第 23、24 位配合實(shí)現(xiàn);當(dāng) D*29,D*30為子幀第一個(gè)字時(shí),D*29,D*30通常置零處理。
2?編碼及校驗(yàn)程序
兩個(gè)函數(shù):
unsigned int computeChecksum(unsigned int source, int nib);// nib= 1?表示要通過配d23 d24使校驗(yàn)值的最后兩位為0
unsigned int countBits(unsigned int v);
?
unsigned int countBits(unsigned int v) {unsigned long c;const int S[] = {1, 2, 4, 8, 16};const unsigned long B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};c = v;c = ((c >> S[0]) & B[0]) + (c & B[0]);c = ((c >> S[1]) & B[1]) + (c & B[1]);c = ((c >> S[2]) & B[2]) + (c & B[2]);c = ((c >> S[3]) & B[3]) + (c & B[3]);c = ((c >> S[4]) & B[4]) + (c & B[4]);return(c); }unsigned int computeChecksum(unsigned int source, int nib) {/*Bits 31 to 30 = 2 LSBs of the previous transmitted word, D29* and D30*Bits 29 to 6 = Source data bits, d1, d2, ..., d24Bits 5 to 0 = Empty parity bits*//*Bits 31 to 30 = 2 LSBs of the previous transmitted word, D29* and D30*Bits 29 to 6 = Data bits transmitted by the SV, D1, D2, ..., D24Bits 5 to 0 = Computed parity bits, D25, D26, ..., D30*//*1 2 3bit 12 3456 7890 1234 5678 9012 3456 7890--- -------------------------------------D25 11 1011 0001 1111 0011 0100 1000 0000D26 01 1101 1000 1111 1001 1010 0100 0000D27 10 1110 1100 0111 1100 1101 0000 0000D28 01 0111 0110 0011 1110 0110 1000 0000D29 10 1011 1011 0001 1111 0011 0100 0000D30 00 1011 0111 1010 1000 1001 1100 0000*/unsigned long bmask[6] = {0x3B1F3480UL, 0x1D8F9A40UL, 0x2EC7CD00UL,0x1763E680UL, 0x2BB1F340UL, 0x0B7A89C0UL };unsigned long D;unsigned long d = source & 0x3FFFFFC0UL;unsigned long D29 = (source>>31)&0x1UL;unsigned long D30 = (source>>30)&0x1UL;if (nib) // Non-information bearing bits for word 2 and 10{/*Solve bits 23 and 24 to presearve parity checkwith zeros in bits 29 and 30.*/if ((D30 + countBits(bmask[4] & d)) % 2)d ^= (0x1UL<<6);if ((D29 + countBits(bmask[5] & d)) % 2)d ^= (0x1UL<<7);}D = d;if (D30)D ^= 0x3FFFFFC0UL;D |= ((D29 + countBits(bmask[0] & d)) % 2) << 5;D |= ((D30 + countBits(bmask[1] & d)) % 2) << 4;D |= ((D29 + countBits(bmask[2] & d)) % 2) << 3;D |= ((D30 + countBits(bmask[3] & d)) % 2) << 2;D |= ((D30 + countBits(bmask[4] & d)) % 2) << 1;D |= ((D29 + countBits(bmask[5] & d)) % 2);D &= 0x3FFFFFFFUL;//D |= (source & 0xC0000000UL); // Add D29* and D30* from source data bitsreturn(D); }3?解碼
GPS的IDC文件中給出了解碼和校驗(yàn)的流程圖如下
4?解校驗(yàn)程序
其中:dta的bit23-bit存放導(dǎo)航電文比特的d1-d24,parity是參考校驗(yàn)值
unsigned int GPS_ParityCheck(int data,int parity,int D29,int D30) {unsigned int i,j,S[6];int temp,S_temp,P;int GPSX_Flag_Data_Parity;unsigned int GPS_H[6]={0xEC7CD2,0x763E69,0xBB1F34,0x5D8F9A,0xAEC7CD,0x2DEA27};temp=0;P=0;GPSX_Flag_Data_Parity=0;if (D30==1) data=(~data)&0xFFFFFF;for(i=0;i<6;i++){S[i]=GPS_H[i]&data;S_temp=S[i];temp=0;for(j=0;j<24;j++){temp+=S_temp&1;S_temp=S_temp>>1;}if (temp%2==0)temp=0;elsetemp=1;if ((i==0)||(i==2)||(i==5))temp=temp^D29;elsetemp=temp^D30;P=P|(temp<<(5-i));}//printf("P = %d\r\n",P);if(P==parity)GPSX_Flag_Data_Parity=1;return GPSX_Flag_Data_Parity; }5?應(yīng)用
#include <stdio.h> #include <stdlib.h> #include "GPSfun.h" //#include "datafile.h" int main() {//D29 = 1//D30 = 0;int dat[32] = {0,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,1,0,0,1,0,0,0,0,1,0,0,1,0,1};//已編碼已校驗(yàn)的測(cè)試序列int i;unsigned int tmp;tmp = 2; //D29 D30 : 10//for(i=0;i<24;i++){tmp = tmp<<1;tmp = tmp+dat[i];}tmp = tmp<<6;//第六位留空 存放校驗(yàn)位tmp = computeChecksum(tmp,0); //該值的bit29-bit0應(yīng)與dta一致printf("tmp = %d\n",tmp);tmp = 0;for(i=0;i<24;i++){tmp = tmp<<1;tmp = tmp+dat[i];}tmp = GPS_ParityCheck(tmp,37,1,0);//37為參考校驗(yàn)值為dta的高六位,即六位校驗(yàn)碼的值printf("tmp = %d\n",tmp);}?
總結(jié)
以上是生活随笔為你收集整理的GPS导航电文编码与校验的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java实现UDP功能
- 下一篇: javaUDP逐步实现多线程发送和接收消