首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GNU无线电中有限状态机的曼彻斯特-L(两相-L)实现

GNU无线电中有限状态机的曼彻斯特-L(两相-L)实现
EN

Stack Overflow用户
提问于 2018-02-28 20:53:35
回答 1查看 1.4K关注 0票数 2

我正在实现行编码块,因为GnuRadio中的选择有限。我已经使用有限状态机(FSM)完成了NRZ (L\M\S)的实现和测试,它们似乎工作得很好。现在,我正在尝试实现曼彻斯特(L\M\S),从L开始作为基线。波形可以在下面的图表中看到,该图表摘自NASA的深空网络遥测数据解码(208)

如下所示构造了一个有限状态机。我决定使用FSM,因为在我看来,它是实现行代码的一种非常标准化的方式。

下面是用于测试实现的gnuradio流程图。测试通过向能够接收信号和处理遥测的外部设备发送BPSK信号(具有CCSDS Reed-Solomon + Scrambler)来执行。这种实现已经成功地使用NRZ-L\M\S进行了测试。CCSDS帧从文件中读取,解包并发送到用于曼彻斯特编码的OOT块debug_linecode_bp (曼彻斯特-L的代码为0)。曼彻斯特编码之后是OOT块debug_pulseshape_pam_2块,它将滤波器抽头和每个符号的样本数作为参数。之后是一个OOT块debug_bpsk_modulator,它执行简单的BPSK映射(同相= ini,正交= 0)。

头文件的代码如下所示

代码语言:javascript
复制
#ifndef INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H
#define INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H

#include <baseband/debug_linecode_bp.h>

namespace gr {
namespace baseband {

class debug_linecode_bp_impl : public debug_linecode_bp
{
 private:
  char last_state;
  int d_code;
  void fsm_decode_state(char state, unsigned char &bit0, unsigned char &bit1);
  void fsm_encode_state(int code, unsigned char input, char last_state, char &next_state);
 public:
  debug_linecode_bp_impl(int code);
  ~debug_linecode_bp_impl();

  // Where all the action really happens
  int work(int noutput_items,
     gr_vector_const_void_star &input_items,
     gr_vector_void_star &output_items);
};

 } // namespace baseband
 } // namespace gr

#endif /* INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H */

下面是实现文件

代码语言:javascript
复制
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "debug_linecode_bp_impl.h"
#include <iostream>
using namespace std;
namespace gr {
namespace baseband {

debug_linecode_bp::sptr
debug_linecode_bp::make(int code)
{
  return gnuradio::get_initial_sptr
    (new debug_linecode_bp_impl(code));
}

/*
 * The private constructor
 */
debug_linecode_bp_impl::debug_linecode_bp_impl(int code)
  : gr::sync_interpolator("debug_linecode_bp",
              gr::io_signature::make(1, 1, sizeof(unsigned char)),
              gr::io_signature::make(1, 1, sizeof(unsigned char)), 2),
d_code(code),last_state('a')
{}

/*
 * Our virtual destructor.
 */
debug_linecode_bp_impl::~debug_linecode_bp_impl()
{
}
void
debug_linecode_bp_impl::fsm_decode_state(char state, unsigned char &bit0, unsigned char &bit1)
{
  switch(state)
{
case 'a':
  bit0 = 0x00;
  bit1 = 0x00;
  break;
case 'b':
  bit0 = 0x00;
  bit1 = 0x01;
  break;
case 'c':
  bit0 = 0x01;
  bit1 = 0x01;
  break;
case 'd':
  bit0 = 0x01;
  bit1 = 0x00;
  break;
}
}

void
debug_linecode_bp_impl::fsm_encode_state(int code, unsigned char input, char last_state, char &next_state)
{
  switch(code)
{
case 0://Biphae-L
  switch(last_state)
    {
    case 'a': //Illegal state
      next_state = 'b';
      cout << "Illegal state [a] encountered" << endl;
      break;
    case 'b':
      next_state = (input & 0x01) ? 'd' : 'b';
      break;
    case 'c': //Illegal state
      next_state = 'b';
      cout << "Illegal state [b] encountered" << endl;
      break;
    case 'd':
      next_state = (input & 0x01) ? 'd' : 'b';
      break;
    }
  break;
case 1://Biphase-S
  switch(last_state)
    {
    case 'a':
      next_state = (input & 0x01) ? 'c' : 'd';
      break;
    case 'b':
      next_state = (input & 0x01) ? 'a' : 'b';
      break;
    case 'c': 
      next_state = (input & 0x01) ? 'a' : 'b';
      break;
    case 'd':
      next_state = (input & 0x01) ? 'c' : 'd';
      break;
    }
  break;
case 2://Biphase-M
  switch(last_state)
    {
    case 'a':
      next_state = (input & 0x01) ? 'd' : 'c';
      break;
    case 'b':
      next_state = (input & 0x01) ? 'b' : 'a';
      break;
    case 'c': 
      next_state = (input & 0x01) ? 'b' : 'a';
      break;
    case 'd':
      next_state = (input & 0x01) ? 'd' : 'c';
      break;
    }
  break;
}
}

int
debug_linecode_bp_impl::work(int noutput_items,
             gr_vector_const_void_star &input_items,
             gr_vector_void_star &output_items)
{
  const unsigned char *in = (const unsigned char *) input_items[0];
  unsigned char *out = (unsigned char *) output_items[0];

  char next_state;
  unsigned char bit0;
  unsigned char bit1;
  for (int i = 0; i < noutput_items/2; i++) {
fsm_encode_state(d_code,in[i],last_state, next_state);
fsm_decode_state(next_state, bit0, bit1);
for (int j = 0; j < 2; j++) {
  out[i + j]     = bit0;
  out[i + j + 1] = bit1;
}
last_state = next_state;
  }

  // Tell runtime system how many output items we produced.
  return noutput_items;
}

} /* namespace baseband */
} /* namespace gr */

到目前为止,测试还没有成功。我用来接收来自这个流程图的信号的设备甚至连一个数据包都不能识别。我的结论是错误来自曼彻斯特编码器。任何关于上面代码的想法都是受欢迎的。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-28 22:08:10

过了一段时间,我发现了代码中的bug。实际上,问题出在我复制输出的方式上。我所要做的就是删除内部的for循环,并直接使用memcpy复制输出。这就是功函数现在的样子

代码语言:javascript
复制
 int
debug_linecode_bp_impl::work(int noutput_items,
             gr_vector_const_void_star &input_items,
             gr_vector_void_star &output_items)
{
  const unsigned char *in = (const unsigned char *) input_items[0];
  unsigned char *out = (unsigned char *) output_items[0];

  char next_state;
  unsigned char bit0;
  unsigned char bit1;
  vector<unsigned char> bits;
  for (int i = 0; i < noutput_items/2; i++) {
      fsm_encode_state(d_code,in[i],last_state, next_state);
      fsm_decode_state(next_state, bit0, bit1);
      bits.push_back(bit0);
      bits.push_back(bit1);
      memcpy(out,bits.data(),2);
      bits.clear();
      out+=2;
      last_state = next_state;
  }

  // Tell runtime system how many output items we produced.
  return noutput_items;
}

这是调制器输出端的波形

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49030085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档