26、BDS B1I电文处理实现

2024-04-27 04:48
文章标签 实现 处理 26 电文 bds b1i

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

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

// b1i_message.c -- BDS B1I 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 <string.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 "b1i_message.h"
#include "b1i_accum_task.h"
#include "main_ephemeris.h"/******************************************************************************* Defines******************************************************************************/#define B1I_PREAMBLE        (0x712 << (30-11))	// b1i_look_for_preamble is 0x712, but it's// located in the MSBits of a 30 bit word.// ROM table list for BDS error correction
unsigned short m_BCH1511_ErrCorrTable[] __attribute__ ((section(".isrdata.rwdata"))) = {0x0000, 0x0001, 0x0002, 0x0010, 0x0004, 0x0100, 0x0020, 0x0400,0x0008, 0x4000, 0x0200, 0x0080, 0x0040, 0x2000, 0x0800, 0x1000};/*
unsigned short m_BCH1511_ErrCorrTable[] = {	// reverse bit-order0x0000, 0x4000, 0x2000, 0x0400, 0x1000, 0x0040, 0x0200, 0x0010,0x0800, 0x0001, 0x0020, 0x0080, 0x0100, 0x0002, 0x0008, 0x0004};
*//******************************************************************************* 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.
b1i_message_t m_b1i_messages[B1I_MAX_CHANNELS] __attribute__ ((section(".isrdata.rwdata")));/******************************************************************************* Statics******************************************************************************/static void b1i_look_for_preamble( unsigned short ch) __attribute__ ((section(".isrcode.txt")));
static int DecodeBCH1511(unsigned short *pus) __attribute__ ((section(".isrcode.txt")));
static int DecodeBCH3022(unsigned long *pul) __attribute__ ((section(".isrcode.txt")));static void b1i_store_bit( unsigned short ch, unsigned short bit) __attribute__ ((section(".isrcode.txt")));
static void b1i_store_word( unsigned short ch) __attribute__ ((section(".isrcode.txt")));/******************************************************************************* 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 b1i_clear_messages(unsigned short ch)
{unsigned short i;m_b1i_messages[ch].frame_sync = 0;m_b1i_messages[ch].subframe = 0;m_b1i_messages[ch].set_epoch_flag = 0;m_b1i_messages[ch].wordbuf0 = 0;m_b1i_messages[ch].wordbuf1 = 0;for (i = 0; i < 5; ++i)m_b1i_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 b1i_store_bit( unsigned short ch, unsigned short bit)
{// If the data is inverted, flip the incoming bit.if (m_b1i_messages[ch].data_inverted) {bit ^= 1;}unsigned short G1;unsigned short idx = m_b1i_messages[ch].bitcount / 2;bchdc_t *pbch_dc = (m_b1i_messages[ch].bitcount & 1) ?(&m_b1i_messages[ch].bch_dc2):(&m_b1i_messages[ch].bch_dc1);// decoder:// G1 = D[3];// D[3] = D[2];// D[2] = D[1];// D[1] = D[0] ^ G1;// D[0] = bit ^ G1;G1 = pbch_dc->D & 8;pbch_dc->D <<= 1;pbch_dc->D |= bit;if (G1) {pbch_dc->D ^= 3;}pbch_dc->swd |= bit;if (idx<14) {pbch_dc->swd <<= 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 parity* check.******************************************************************************/
static void b1i_store_word( unsigned short ch)
{unsigned short sf = m_b1i_messages[ch].subframe;unsigned short wc = m_b1i_messages[ch].wordcount;// error correctionunsigned short sw1 = m_b1i_messages[ch].bch_dc1.swd ^ m_BCH1511_ErrCorrTable[m_b1i_messages[ch].bch_dc1.D & 0xf];unsigned short sw2 = m_b1i_messages[ch].bch_dc2.swd ^ m_BCH1511_ErrCorrTable[m_b1i_messages[ch].bch_dc2.D & 0xf];// re-encoderunsigned short i, bit;unsigned short G1, D1=0, D2=0;unsigned short us1 = sw1;unsigned short us2 = sw2;for (i=0; i<11; i++, us1<<=1, us2<<=1) {bit = (us1 & 0x4000) ? 1:0;G1 = ((D1 & 8) ? 1:0) ^ bit;D1 <<= 1;if (G1) {D1 ^= 3;}bit = (us2 & 0x4000) ? 1:0;G1 = ((D2 & 8) ? 1:0) ^ bit;D2 <<= 1;if (G1) {D2 ^= 3;}}// parity checkif ((D1 & 0xf) == (sw1 & 0xf) && (D2 & 0xf) == (sw2 & 0xf)) {// Store the word in the subframes arraym_b1i_messages[ch].subframes[sf].word[wc] =((unsigned long)(sw1 & 0xfff0) << 15)|((unsigned long)(sw2 & 0xfff0) << 4) |((unsigned long)(sw1 & 0x000f) << 4) |((unsigned long)(sw2 & 0x000f));// Mark it as validm_b1i_messages[ch].subframes[sf].valid |= (1 << wc);}
}static int DecodeBCH1511(unsigned short *pus)
{unsigned short i, us, bit;unsigned short G1, D=0, DEC=0;// decoder:// G1 = D[3];// D[3] = D[2];// D[2] = D[1];// D[1] = D[0] ^ G1;// D[0] = bit ^ G1;us = *pus;for (i=0; i<15; i++, us<<=1) {bit = (us & 0x4000) ? 1:0;G1 = (D & 8);D <<= 1;D |= bit;if (G1) {D ^= 3;}}// error correction*pus ^= m_BCH1511_ErrCorrTable[D & 0xf];// re-encoder// G1 = D[3]^bit;// D[3] = D[2];// D[2] = D[1];// D[1] = D[0] ^ G1;// D[0] = G1;us = *pus;for (i=0; i<11; i++, us<<=1) {bit = (us & 0x4000) ? 1:0;G1 = ((DEC & 8) ? 1:0) ^ bit;DEC <<= 1;if (G1) {DEC ^= 3;}}// parity checkif ((DEC & 0xf) == (*pus & 0xf)) {return 1;}return 0;
}static int DecodeBCH3022(unsigned long *pul)
{unsigned long ul;unsigned short i, us1, us2;ul = *pul;i = us1 = us2 = 0;while (i < 15) {if (ul & 0x20000000)us1 |= 1;ul <<= 1;if (ul & 0x20000000)us2 |= 1;ul <<= 1;i ++;if (i < 15) {us1 <<= 1;us2 <<= 1;}}if (DecodeBCH1511(&us1) && DecodeBCH1511(&us2)) {*pul = ((unsigned long)(us1 & 0xfff0) << 15)|((unsigned long)(us2 & 0xfff0) << 4) |((unsigned long)(us1 & 0x000f) << 4) |((unsigned long)(us2 & 0x000f));return 1;}return 0;
}/******************************************************************************** This function finds the preamble, TLM and HOW in the navigation message and* synchronizes to the nav message.
*******************************************************************************/
static void b1i_look_for_preamble( unsigned short ch)
{unsigned long TLM, SOW;unsigned short current_subframe;unsigned short previous_subframe;unsigned short data_inverted, us;// Note: Bits are stored in wordbuf0/1 in store_bits()// Save local copies of the wordbuf's for local checks of TLMTLM = m_b1i_messages[ch].wordbuf1;SOW = m_b1i_messages[ch].wordbuf0;// Test for preambleif ((TLM & 0x3ff80000) == B1I_PREAMBLE) {data_inverted = 0;}else {TLM = ~TLM;if ((TLM & 0x3ff80000) == B1I_PREAMBLE) {SOW = ~SOW;data_inverted = 1;}else {return;}}us = TLM & 0x7fff;if (!DecodeBCH1511(&us)) {return;}TLM = (TLM & 0xffff8000) | us;if (!DecodeBCH3022(&SOW)) {return;}// Subframe IDcurrent_subframe = (int)((TLM >> 12) & 7);// subframe range testif ((current_subframe < 1) || (current_subframe > 5)) {return;}// Hooray! We found a valid preamble and a SOW 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 SOW has incremented by exactly 6.m_b1i_messages[ch].frame_sync = 1;// Record the current subframe number (from zero)m_b1i_messages[ch].subframe = --current_subframe;// Flag whether the bits are inverted.m_b1i_messages[ch].data_inverted = data_inverted;// We've just stored two words into the current subframem_b1i_messages[ch].subframes[current_subframe].word[0] = TLM;m_b1i_messages[ch].subframes[current_subframe].word[1] = SOW;m_b1i_messages[ch].wordcount = 2;// Flag Words 0 and 1 as valid wordsm_b1i_messages[ch].subframes[current_subframe].valid = 3;// Extract and store the SOW from the TPW and SOW so we can easily compare// it to future SOWs to verify our frame sync.m_b1i_messages[ch].subframes[current_subframe].SOW =((TLM & 0xff0) << 8) | ((SOW >> 18) & 0xfff);previous_subframe = (current_subframe > 0) ? (current_subframe - 1):4;// Even if the previous subframe had valid TLM and SOW words, kill both the// current and previous subframes if their SOW's are not incrementally// different.if (m_b1i_messages[ch].subframes[previous_subframe].valid & 3) {unsigned long time_in_ms;unsigned short IsInvalid = 0;unsigned short D1Msg = IS_D1_NAVMESSAGE(m_b1i_messages[ch].prn);if (D1Msg) {if ((m_b1i_messages[ch].subframes[current_subframe].SOW) !=(m_b1i_messages[ch].subframes[previous_subframe].SOW + 6)) {IsInvalid = 1;}}else {if (current_subframe == 0) {if ((m_b1i_messages[ch].subframes[current_subframe].SOW) !=(m_b1i_messages[ch].subframes[previous_subframe].SOW + 3)) {IsInvalid = 1;}}else {if ((m_b1i_messages[ch].subframes[current_subframe].SOW) !=(m_b1i_messages[ch].subframes[previous_subframe].SOW)) {IsInvalid = 1;}}}if (IsInvalid) {// We're not actually synced. Kill everything and start// the sync search over again.b1i_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.m_B1I_CH[ch].backto_pull_in = 1;}else {// Now that we have a valid TLM/SOW, we know the actual time of week.time_in_ms = m_b1i_messages[ch].subframes[current_subframe].SOW * 1000;if (D1Msg) {// Note that the SOW in the SOW word is actually the time at the start// of the subframe.// Update the gps "time_in_ms". Given that we know the current bit// is the last bit of the SOW word (the 60th bit of the subframe), we// can calculate the gps time in ms. Note, time_in_bits is incremented// in the tracking.c lock() function.time_in_ms += 1200;}else {time_in_ms += current_subframe * 600 + 120;}// Update the GNSS time in seconds (the receiver's main clock).set_time_with_sow(time_in_ms/1000.0);time_in_ms /= 20;if (time_in_ms >= BITS_IN_WEEK_50HZ)time_in_ms -= BITS_IN_WEEK_50HZ;GNSS_ENTER_CRITICAL();m_B1I_CH[ch].time_in_bits = time_in_ms;m_B1I_CH[ch].ms_count_20 = 19;if (!m_b1i_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_B1I_CH[ch].sync_20ms_epoch_count = 50 + (time_in_ms % 50);m_b1i_messages[ch].set_epoch_flag = 1;}}}// Hand off the current satellite to the message structurem_b1i_messages[ch].prn = m_B1I_CH[ch].prn;GNSS_EXIT_CRITICAL();
}void b1i_sync_frame(unsigned short ch, unsigned short bit)
{// NAV messages come MSBit 1st, so the most recent bit is the LSBit.m_b1i_messages[ch].wordbuf0 = (m_b1i_messages[ch].wordbuf0 << 1) | bit;// NAV words are 30 bits long. Note that we use wordbuf1 to look for the// preamble (TLM and SOW at the same time)if( m_b1i_messages[ch].wordbuf0 & (1 << 30))m_b1i_messages[ch].wordbuf1 = (m_b1i_messages[ch].wordbuf1 << 1) | 1;elsem_b1i_messages[ch].wordbuf1 = (m_b1i_messages[ch].wordbuf1 << 1);b1i_look_for_preamble(ch);// If we just found sync, then reset the countersif( m_b1i_messages[ch].frame_sync) {m_b1i_messages[ch].bitcount = 0;memset(&m_b1i_messages[ch].bch_dc1, 0, sizeof(bchdc_t));memset(&m_b1i_messages[ch].bch_dc2, 0, sizeof(bchdc_t));}
}void b1i_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 < B1I_MAX_CHANNELS; ch++, pbit <<= 1) {if (channels_with_bits & pbit) {// If the channel isn't sync'd to the message frame,// store the bit and look for the preambleif (!m_b1i_messages[ch].frame_sync) {
#ifndef SYNC_PROCESS_FRAME_SYNCb1i_sync_frame( ch, (channel_bits & pbit) ? 1:0);
#endif // SYNC_PROCESS_FRAME_SYNC}// Frame is sync'd, so get bits and words.else {// Store the bitb1i_store_bit( ch, (channel_bits & pbit) ? 1:0);// If we have 30 bits, that's a word so store itm_b1i_messages[ch].bitcount++;if (m_b1i_messages[ch].bitcount >= 30) {// Store the word in the subframes arrayb1i_store_word( ch);m_b1i_messages[ch].bitcount = 0;memset(&m_b1i_messages[ch].bch_dc1, 0, sizeof(bchdc_t));memset(&m_b1i_messages[ch].bch_dc2, 0, sizeof(bchdc_t));m_b1i_messages[ch].wordcount++;if (m_b1i_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_b1i_messages[ch].frame_sync = 0;m_b1i_messages[ch].wordbuf0 = 0;m_b1i_messages[ch].wordbuf1 = 0;// Only send along complete, error free subframesif (m_b1i_messages[ch].subframes[m_b1i_messages[ch].subframe].valid == 0x3ff) {// 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_b1i_messages[ch].subframe);OSFlagPost(m_EphemerisSubframeFlags[GPS_MAX_CHANNELS+ch], which_subframe, OS_FLAG_SET, &err);}}}}}}
}
  • 我的新浪博客账号
  • 我的存档免费软件
  • 我的存档学习资料

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



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

相关文章

pandas中位数填充空值的实现示例

《pandas中位数填充空值的实现示例》中位数填充是一种简单而有效的方法,用于填充数据集中缺失的值,本文就来介绍一下pandas中位数填充空值的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是中位数填充?为什么选择中位数填充?示例数据结果分析完整代码总结在数据分析和机器学习过程中,处理缺失数

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Pandas使用AdaBoost进行分类的实现

《Pandas使用AdaBoost进行分类的实现》Pandas和AdaBoost分类算法,可以高效地进行数据预处理和分类任务,本文主要介绍了Pandas使用AdaBoost进行分类的实现,具有一定的参... 目录什么是 AdaBoost?使用 AdaBoost 的步骤安装必要的库步骤一:数据准备步骤二:模型

使用Pandas进行均值填充的实现

《使用Pandas进行均值填充的实现》缺失数据(NaN值)是一个常见的问题,我们可以通过多种方法来处理缺失数据,其中一种常用的方法是均值填充,本文主要介绍了使用Pandas进行均值填充的实现,感兴趣的... 目录什么是均值填充?为什么选择均值填充?均值填充的步骤实际代码示例总结在数据分析和处理过程中,缺失数

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http