24、GPS L1电文处理实现

2024-04-27 04:48
文章标签 实现 处理 24 l1 gps 电文

本文主要是介绍24、GPS L1电文处理实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

\qquad 下面是HD-GR GNSS导航软件的GPS L1电文处理实现代码,入口函数gps_process_message (…):

// gps_message.c -- GPS L1 Navigation message processing./* * Copyright (C) 2005 Andrew Greenberg* Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 (June 1991).* See the "COPYING" file distributed with this software for more information.*//* Namuru GPS receiver project* Original : message.c* Mods     : driving LED part has commented/replaced for Namuru HW* version  : V1.1* date     : 8/7/2008*//* * HD-GR GNSS receiver project* Modes    : Inherited the code of message.c in the Namuru GPS receiver project *            V1.0 and made necessary adjustments to adapt to the new RTOS and *            functions.* version  : V1.0* date     : xx/xx/2015*/#include <io.h>
#include <stdio.h>
#include <math.h>
#include "includes.h"
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "gnsstime.h"
#include "gps_message.h"
#include "gps_accum_task.h"
#include "main_ephemeris.h"/******************************************************************************* Defines******************************************************************************/#define LINLIANG_HAMMING_PARITY_CHECK// gps_look_for_preamble is 0x8b, but it's located in the MSBits of a 30 bit word.
#define GPS_PREAMBLE        (0x8b << (30-8))/******************************************************************************* Globals******************************************************************************/// Right now we're declaring a message structure per channel, since the
// messages come out of locked channels.. but you could argue they should be
// in a per satellite array.
gps_message_t  m_gps_messages[GPS_MAX_CHANNELS] __attribute__ ((section(".isrdata.rwdata")));/******************************************************************************* Statics******************************************************************************/static void gps_look_for_preamble( unsigned short ch) __attribute__ ((section(".isrcode.txt")));
static int gps_parity_check( unsigned long word) __attribute__ ((section(".isrcode.txt")));
#ifndef LINLIANG_HAMMING_PARITY_CHECK
static int gps_parity( unsigned long word) __attribute__ ((section(".isrcode.txt")));
#endif // LINLIANG_HAMMING_PARITY_CHECKstatic void gps_store_bit( unsigned short ch, unsigned short bit) __attribute__ ((section(".isrcode.txt")));
static void gps_store_word( unsigned short ch) __attribute__ ((section(".isrcode.txt")));#ifdef LINLIANG_HAMMING_PARITY_CHECK/*************************************************Function: bool gps_parity_check(unsigned word)*Revision: 1.00*Last Update: 24/12/2009*Description:Hamming Parity Check*Input: 32bit unsigned:D29*,D30*,b1-b24,parities*Output: true,gps_parity check ok.*Author:linliang*E-Mail:hxmlinliang@yahoo.com.cn***********************************************/
static int gps_parity_check( unsigned long word)
{unsigned long b_1,b_2,b_3,b_4,b_5,b_6,b_7;unsigned long XorResult,gps_parity;// Parallel XOR can realize the verification process of GPS navigation data, // which can avoid redundant and OR operationb_1 = word & 0xFBFFBF00;b_2 = Rotation_left(word,1) & 0x07FFBF01;b_3 = Rotation_left(word,2) & 0xFC0F8100;b_4 = Rotation_left(word,3) & 0xF81FFE02;b_5 = Rotation_left(word,4) & 0xFC00000E;b_6 = Rotation_left(word,5) & 0x07F00001;b_7 = Rotation_left(word,6) & 0x00003000;XorResult = b_1 ^ b_2 ^ b_3 ^ b_4 ^ b_5 ^ b_6 ^ b_7;// Shift XorResult into 5 blocks, 6 bits each time, then perform XOR to get the // final resultgps_parity = XorResult ^ Rotation_left(XorResult,6) ^ Rotation_left(XorResult,12)^ Rotation_left(XorResult,18) ^ Rotation_left(XorResult,24);gps_parity = gps_parity & 0x3F;return ((word&0x3F) == gps_parity);
}#else// GPS gps_parity bit-vectors
// The last 6 bits of a 30bit GPS word are gps_parity check bits.
// Each gps_parity bit is computed from the XOR of a selection of bits from the
// 1st 24 bits of the current GPS word, and the last 2 bits of the _previous_
// GPS word.
// These gps_parity bit-vectors are used to select which message bits will be used
// for computing each of the 6 gps_parity check bits.
// We assume the two bits from the previous message (b29, b30) and the 24 bits
// from the current message, are packed into a 32bit word in this order:
//   < b29, b30, b1, b2, b3, ... b23, b24, X, X, X, X, X, X > (X = don't care)
// Example: if PBn = 0x40000080,
// The gps_parity check bit "n" would be computed from the expression (b30 XOR b23).
#define PB1     0xbb1f3480
#define PB2     0x5d8f9a40
#define PB3     0xaec7cd00
#define PB4     0x5763e680
#define PB5     0x6bb1f340
#define PB6     0x8b7a89c0/******************************************************************************* Count the number of bits set in the input and return (1) if this count is* odd (0) otherwise.* This is used in the navigation message gps_parity check algorithm.** Note, on the ARM there is probably a more efficient way to do this.******************************************************************************/
static int gps_parity( unsigned long word)
{int count = 0;while (word) {if ((long)word < 0) count++;word <<= 1; // Want to go this way because we typically ignore some LSBits}return (count & 1);
}/******************************************************************************* Return 1 if and only if input 30bit word passes GPS gps_parity check, otherwise* return 0.** The input word is expected to be 32bits, with the 30bit word right justified.* The two most significant bits (b30 and b31) should contain the last two bits* of the _previous_ GPS word.******************************************************************************/
static int gps_parity_check( unsigned long word)
{return (!((word & 0x3f) ^ // Last 6 bits are the message gps_parity bits((gps_parity( word & PB1) << 5) | (gps_parity( word & PB2) << 4) |(gps_parity( word & PB3) << 3) | (gps_parity( word & PB4) << 2) |(gps_parity( word & PB5) << 1) |  gps_parity( word & PB6))));
}#endif // LINLIANG_HAMMING_PARITY_CHECK/******************************************************************************* New satellite in a channel; clear the message. For now that means just* clearing the valid flags (and the current subframe for display purposes)*****************************************************************************/
void gps_clear_messages(unsigned short ch)
{unsigned short i;m_gps_messages[ch].frame_sync = 0;m_gps_messages[ch].subframe = 0;m_gps_messages[ch].set_epoch_flag = 0;for (i = 0; i < 5; ++i)m_gps_messages[ch].subframes[i].valid = 0;
}/******************************************************************************* Load bits into wordbuf0 and wordbuf1. Flip the incoming bit if we're sync'd* onto a subframe and the bits are inverted.** Note, see coments about weird 2+ 30 bit pattern below in the words below.*****************************************************************************/
static void gps_store_bit( unsigned short ch, unsigned short bit)
{// If we're synced on the current message and the data is inverted,// flip the incoming bit.if (m_gps_messages[ch].frame_sync && m_gps_messages[ch].data_inverted)bit ^= 1;// GPS NAV messages come MSBit 1st, so the most recent bit is the LSBit.m_gps_messages[ch].wordbuf0 = (m_gps_messages[ch].wordbuf0 << 1) | bit;// NAV words are 30 bits long and the gps_parity check requires the upper// two bits to be the least two bits of the previous word. Note that we// use wordbuf1 to look for the preamble (TLM and HOW at the same time)if( m_gps_messages[ch].wordbuf0 & (1 << 30))m_gps_messages[ch].wordbuf1 = (m_gps_messages[ch].wordbuf1 << 1) | 1;elsem_gps_messages[ch].wordbuf1 = (m_gps_messages[ch].wordbuf1 << 1);
}/******************************************************************************* Take the message's buffer of 2 + 30 bits (2 from the previous word) and* store it in the subframe's word as 24 bits of data after completing a gps_parity* check.******************************************************************************/
static void gps_store_word( unsigned short ch)
{// If bit 30 is set then flip bits 29 - 6 as per GPS spec.if (m_gps_messages[ch].wordbuf0  & (1 << 30))m_gps_messages[ch].wordbuf0 ^= 0x3fffffc0;if( gps_parity_check(m_gps_messages[ch].wordbuf0)) {// Store the word without the 6 partiy bits and the 2 upper bits// in the subframes arraym_gps_messages[ch].subframes[m_gps_messages[ch].subframe].word[m_gps_messages[ch].wordcount]= (m_gps_messages[ch].wordbuf0 >> 6) & 0x00ffffff;// Mark it as validm_gps_messages[ch].subframes[m_gps_messages[ch].subframe].valid|= (1 << m_gps_messages[ch].wordcount);}
}/******************************************************************************** This function finds the preamble, TLM and HOW in the navigation message and* synchronizes to the nav message.
*******************************************************************************/
static void gps_look_for_preamble( unsigned short ch)
{// TLeMetry, HandOffWordunsigned long   TLM, HOW;unsigned short  current_subframe;unsigned short  previous_subframe;unsigned short  data_inverted;// Note: Bits are stored in wordbuf0/1 in store_bits()// Save local copies of the wordbuf's for local checks of TLM and HOWTLM = m_gps_messages[ch].wordbuf1;HOW = m_gps_messages[ch].wordbuf0;// Test for inverted data. Bit 0 and 1 of HOW must be zero.// Test for inverted dataif (HOW & 1) {TLM = ~TLM;HOW = ~HOW;data_inverted = 1;}else {data_inverted = 0;}// Flip bits 29 - 6 if the previous word's LSB is 1if (TLM  & (1 << 30))TLM ^= 0x3fffffc0;if (HOW  & (1 << 30))HOW ^= 0x3fffffc0;// Test for preambleif ((TLM & 0x3fc00000) != GPS_PREAMBLE)return;// Subframe IDcurrent_subframe = (int)((HOW >> 8) & 7);// subframe range testif ((current_subframe < 1) || (current_subframe > 5))return;// Confirm zerosif (HOW & 3)return;// The advantage of previous checks is saving time on false hits.// They do increase time on true hits though.if (!gps_parity_check(TLM))return;if (!gps_parity_check(HOW))return;// Hooray! We found a valid preamble and a sane HOW word, so for now// we'll assume we're synced. We won't really know until we get the next// subframe and check that the TOW has incremented by exactly 1.m_gps_messages[ch].frame_sync = 1;// Record the current subframe number (from zero)m_gps_messages[ch].subframe = --current_subframe;// Flag whether the bits are inverted, and if so invert wordbuf0 so we// don't lose the next incoming word.if (data_inverted) {m_gps_messages[ch].data_inverted = 1;m_gps_messages[ch].wordbuf0 = ~m_gps_messages[ch].wordbuf0;}else {m_gps_messages[ch].data_inverted = 0;}m_gps_messages[ch].subframes[current_subframe].word[0] = TLM;m_gps_messages[ch].subframes[current_subframe].word[1] = HOW;// We've just stored two words into the current subframem_gps_messages[ch].wordcount = 2;// Flag Words 0 and 1 as valid wordsm_gps_messages[ch].subframes[current_subframe].valid = 3;// Extract and store the TOW from the HOW so we can easily compare it to// future TOWs to verify our frame sync. (TOW == bits 1-17 of 30 bit word)// Maybe this should be a macro. Could be done faster if we assumed 32bits.m_gps_messages[ch].subframes[current_subframe].TOW =(HOW >> (30 - 17)) & ((1 << 17) - 1);previous_subframe = (current_subframe > 0) ? (current_subframe - 1):4;// Even if the previous subframe had valid TLM and HOW words, kill both the// current and previous subframes if their TOW's are not incrementally// different.if (m_gps_messages[ch].subframes[previous_subframe].valid & 3) {if (m_gps_messages[ch].subframes[current_subframe].TOW !=(m_gps_messages[ch].subframes[previous_subframe].TOW + 1)) {// We're not actually synced. Kill everything and start// the sync search over again.gps_clear_messages( ch);GNSS_ENTER_CRITICAL();// We must also go back to pull-in, as the sync process// is done there not in lock. If this is not done// the sync can get corrupted, leading to bad pseudoranges.// (pjm)m_GPS_CH[ch].backto_pull_in = 1;}else {// Now that we have a valid TLM/HOW, we know the actual time of week.// Note that the TOW in the HOW is actually the time at the start// of the next subframe.// Update the GNSS time in seconds (the receiver's main clock)set_time_with_tow( m_gps_messages[ch].subframes[current_subframe].TOW);// Given that we know the current bit// is the last bit of the HOW word (the 60th bit of the subframe), we// can calculate the gps time in bit-counts (1/50 seconds).// Note, time_in_bits is incremented in the tracking.c lock() function.if (m_gps_messages[ch].subframes[current_subframe].TOW) {HOW = m_gps_messages[ch].subframes[current_subframe].TOW * 300 - 240;}// The TOW can be zero so handle this case.else {HOW = BITS_IN_WEEK - 240;}GNSS_ENTER_CRITICAL();// Update the gps "time_in_bits"m_GPS_CH[ch].time_in_bits = HOW;if (!m_gps_messages[ch].set_epoch_flag) {// Finally, flag the tracking loop that the next bit (20ms epoch)// is the beginning of a new word. This will reset the epoch counter// to 0 every 30 bits to track words... but ONLY once.m_GPS_CH[ch].sync_20ms_epoch_count = 1;m_gps_messages[ch].set_epoch_flag = 1;}}}// Hand off the current satellite to the message structurem_gps_messages[ch].prn = m_GPS_CH[ch].prn;GNSS_EXIT_CRITICAL();
}void gps_process_message(OS_FLAGS channels_with_bits, OS_FLAGS channel_bits)
{INT8U err;INT32U pbit;unsigned short ch;OS_FLAGS which_subframe;for (ch = 0, pbit = 1; ch < GPS_MAX_CHANNELS; ch++, pbit <<= 1) {if (channels_with_bits & pbit) {// This channel has a bit to process: store the bit into// wordbuf0 and wordbuf1gps_store_bit( ch, (channel_bits & pbit) ? 1:0);// If the channel isn't sync'd to the message frame,// look for the preambleif (!m_gps_messages[ch].frame_sync) {gps_look_for_preamble(ch);// If we just found sync, then reset the countersif( m_gps_messages[ch].frame_sync) {m_gps_messages[ch].bitcount = 0;}}// Frame is sync'd, so get bits and words.else {// If we have 30 bits, that's a word so store itm_gps_messages[ch].bitcount++;if (m_gps_messages[ch].bitcount >= 30) {m_gps_messages[ch].bitcount = 0;// Store the word in the subframes arraygps_store_word( ch);m_gps_messages[ch].wordcount++;if (m_gps_messages[ch].wordcount >= 10) {// We've got 10 words so we have a subframe. Use// frame_sync to restart the subframe parsing.// Note that preamble will reset wordcount.m_gps_messages[ch].frame_sync = 0;// we assume in the preamble that the bit stream// hasn't been inverted when we check the TLM/HOW.// so if the channel IS inverted, make it non-// inverted as we check the TLM/HOW.if( m_gps_messages[ch].data_inverted)m_gps_messages[ch].wordbuf0 = ~m_gps_messages[ch].wordbuf0;// Only send along complete, error free subframesif (m_gps_messages[ch].subframes[m_gps_messages[ch].subframe].valid == 0x3ff) {
//                          unsigned short sv = m_gps_messages[ch].prn-1;
//                      	if (!m_ephetable[sv].valid) {// Set the flag to wake up the ephemeris threadchannels_with_subframes |= (1 << ch);// Set the subframe flag so we know which// subframe to process. We don't need a// shadow register here because we're only// going to set one subframe per channel// at a time.which_subframe = (1 << m_gps_messages[ch].subframe);OSFlagPost(m_EphemerisSubframeFlags[ch], which_subframe, OS_FLAG_SET, &err);//                      	}}}}}}}
}

这篇关于24、GPS L1电文处理实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/939555

相关文章

AJAX请求上传下载进度监控实现方式

《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

Redis分片集群的实现

《Redis分片集群的实现》Redis分片集群是一种将Redis数据库分散到多个节点上的方式,以提供更高的性能和可伸缩性,本文主要介绍了Redis分片集群的实现,具有一定的参考价值,感兴趣的可以了解一... 目录1. Redis Cluster的核心概念哈希槽(Hash Slots)主从复制与故障转移2.

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

Mybatis 传参与排序模糊查询功能实现

《Mybatis传参与排序模糊查询功能实现》:本文主要介绍Mybatis传参与排序模糊查询功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、#{ }和${ }传参的区别二、排序三、like查询四、数据库连接池五、mysql 开发企业规范一、#{ }和${ }传参的

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文

基于SpringBoot+Mybatis实现Mysql分表

《基于SpringBoot+Mybatis实现Mysql分表》这篇文章主要为大家详细介绍了基于SpringBoot+Mybatis实现Mysql分表的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录基本思路定义注解创建ThreadLocal创建拦截器业务处理基本思路1.根据创建时间字段按年进

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整