论坛风格切换切换到宽版
  • 4460阅读
  • 29回复

关于数字信号传输 [复制链接]

上一主题 下一主题
离线永远的FM
 
发帖
12113
只看楼主 倒序阅读 0楼 发表于: 2009-06-09
传输一组串行二进制码,只能用一条线传送(数据),能否在收发设备时钟不同步情况下正确传送?如何实现?
离线BG7JNS
发帖
289
只看该作者 1楼 发表于: 2009-06-09
差分编码
离线danju
发帖
415
只看该作者 2楼 发表于: 2009-06-09
可采用含有时钟信号的编码方式,在接收端对信号进行时钟恢复,用恢复的时钟来对信号进行解码
离线汤圆
发帖
1157
只看该作者 3楼 发表于: 2009-06-09
com口就是
离线BA5RW
发帖
48263
只看该作者 4楼 发表于: 2009-06-09
防盗遥控器不都是?
离线永远的FM
发帖
12113
只看该作者 5楼 发表于: 2009-06-10
我对那个曼彻斯特编码有兴趣,不知有没有具体实现方案?用单片机的。fpga成本太高了。
离线BD6KF
发帖
1126
只看该作者 6楼 发表于: 2009-06-10
[quote=永远的fm]传输一组串行二进制码,只能用一条线传送(数据),能否在收发设备时钟不同步情况下正确传送?如何实现?[/quote]
严格的说是两条线,还要有个地线,在加你的一个数据线,用单片机是很容易的事情,主要是判断,起始位和结束位,在一个就是时钟的正确判断。
离线永远的FM
发帖
12113
只看该作者 7楼 发表于: 2009-06-10
'
严格的说是两条线,还要有个地线,在加你的一个数据线,用单片机是很容易的事情,主要是判断,起始位和结束位,在一个就是时钟的正确判断。
'

如果在时钟能对应情况下这个实现这个易如反掌。但关键是时钟无法对应。
离线danju
发帖
415
只看该作者 8楼 发表于: 2009-06-10
低速的用异步传输是可行的,高速的还是需要时钟恢复和同步的,看实际应用的需求吧
编码有很多种,只要能将时钟信息也包含进去,那么接收端就可以想一些办法来实现同步了
离线danju
发帖
415
只看该作者 9楼 发表于: 2009-06-10
以太局域网就用曼彻斯特编码的,大部分用硬件实现的,网上有曼彻斯特编码的c实现:

//----------------------------------------------------------------------------   |
// 标题: 曼彻斯特和差分曼彻斯特编码的实现                           |
// 分析:曼彻斯特编码是将每个码元的中央实现跳变,具体的码字表示为:                                             |
//     1->10,0->01.                                         |
//     差分曼彻斯特编码每个码元依前一码元而定,遇1跳变,遇0保持                                           |
//     若前为:01,则1->10 0->01                               |
//     若前为:10,则1->01 0->10                                 |
// 实现:定义两个数组,一个用来放置输入要编码的序列,另一个用来放编码后的序列                                                 |
//                                                   |
//                                                   |
//----------------------------------------------------------------------------

/**/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 头文件
#include <stdio.h>
#include <assert.h>
#include<string.h>

/**/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 全局变量

#define m 10
int j;   //指向编码后序列的数组下标
int i;   //输入码字的数组下标
int length;   //求值输入数组的长度

/**/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 参数表

int direct_code(char str0[]) //直接编码
...{
char dirct_code[2*m];
memset(dirct_code,0,2*m);
dirct_code[0]=Ɔ'
dirct_code[1]=Ƈ'
j=2;
extern length;
for(i=0;i<length;i++)
...{
  // 循环入口数据
  printf("current character is: %c ",str0);

    // 循环处理,0 ->01 1 ->10
if(str0==Ɔ')   ...{dirct_code[j++]=Ɔ'dirct_code[j++]=Ɔ'}
else if(str0==Ƈ') ...{dirct_code[j++]=Ƈ'dirct_code[j++]=Ƈ'}
    else ...{printf("input error,exit........ "); return 1;} // 输入出错
    // 循环处理后数据
  printf("-----");
  printf("after process: %c%c ",dirct_code[j-2],dirct_code[j-1]);
}
 
  // 结果字符串加上终结符
  dirct_code[j]=0;

  // 输出结果
printf("------------------------------------------- ");
printf("direct_code coding is:%s ",dirct_code);
return 0;
}


int manchester(char str0[])   //曼彻斯特编码
...{
char manchester[2*m];
memset(manchester,0,2*m);
manchester[0]=Ɔ'
manchester[1]=Ƈ'
j=2;
extern length;

for(i=0;i<length;i++)
...{
  // 循环入口数据
  printf("current character is: %c ",str0);

    // 循环处理,0 ->01 1 ->10
if(str0==Ɔ')   ...{manchester[j++]=Ɔ'manchester[j++]=Ƈ'}
else if(str0==Ƈ') ...{manchester[j++]=Ƈ'manchester[j++]=Ɔ'}
    else ...{printf("input error,exit........ "); return 1;} // 输入出错
    // 循环处理后数据
  printf("-----");
  printf("after process: %c%c ",manchester[j-2],manchester[j-1]);
}
 
  // 结果字符串加上终结符
  manchester[j]=0;
 
  // 输出结果
printf("------------------------------------------- ");
printf("manchester coding is :%s ",manchester);
return 0;
}


int dif_manchester(char str0[]) //差分曼彻斯特编码
...{
char dif_manch[2*m];
memset(dif_manch,0,2*m);   //初始化数组
dif_manch[0]=Ɔ'
dif_manch[1]=Ƈ'
j=2;
extern length;

for(i=0;i<length;i++)
...{
  // 循环入口数据
  printf("current character is: %c ",str0);

    // 循环处理,0 ->01 1 ->10
if(str0==Ɔ')
...{
  dif_manch[j++]=dif_manch[j-3];
  dif_manch[j++]=dif_manch[j-2];
}
else if(str0==Ƈ')
...{
  dif_manch[j++]=dif_manch[j-2];
  dif_manch[j++]=dif_manch[j-3];
}
    else ...{printf("input error,exit........ "); return 1;} // 输入出错
    // 循环处理后数据
  printf("-----");
  printf("after process: %c%c ",dif_manch[j-2],dif_manch[j-1]);
}
 
  // 结果字符串加上终结符
  dif_manch[j]=0;
 
  // 输出结果
printf("------------------------------------------- ");
printf("dif_manchester coding is :%s ",dif_manch);
return 0;
}

/**/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
// 入口点
int main(int argc, char* argv[])
...{


  char str0[m];

// 获取输入数据
printf("please input the number string u want(it must less than 10): ");
scanf("%s",str0);
  // 验证输入数据是否正确,可以用assert之类
printf("what u input is------:: %s ",str0);
length=strlen(str0);
  assert(length <m ); //设置断言,数组越界检查
 
  // 输出数据区置0
  //memset(str1,0,2*m);
 
direct_code(str0);
manchester(str0);
dif_manchester(str0);
 
return 0;
}
/**///////////////////////////////////////////////////////////////////////////////

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/**/////////////////////////////////////////这是刚刚开始自己写的程序////////////////////////////////////////////////////////////////////////

#define m 10
#include<stdio.h>


void main()……


正确与否不清楚哦,自己验证吧
离线小比尔/5
发帖
2582
只看该作者 10楼 发表于: 2009-06-10
晕...
简单的程序搞得那么复杂...

0编为10
1编为01
按一定的时钟发就可以了
同步靠边沿,测出边沿的时间就可以恢复为0或者1了
离线BG7YDO
发帖
3654
只看该作者 11楼 发表于: 2009-06-10
真羡慕会编程的!
离线danju
发帖
415
只看该作者 12楼 发表于: 2009-06-10
如果信号速率很高的话,接收端和发送端的时钟频率和相位差会造成严重误码,所以232那样的以起始位的方式,异步传送是很难保证传输质量的,所以进行一定方式的编码还是有意义的
离线易水寒
发帖
1978
只看该作者 13楼 发表于: 2009-06-10
v.24 rs232 就是异步串行模式嘛
离线radiolee
发帖
6050
只看该作者 14楼 发表于: 2009-06-10
1wire?
离线永远的FM
发帖
12113
只看该作者 15楼 发表于: 2009-06-10
rs232还有2条线可以传输时钟和数据。
我现在要做的是,接收方时钟和发送方无法同步(2个完全不同类型的单片机收发数据,而且不能用串口),他们传输是用无线发射方式的。这种情况下有什么方法实现传输?
离线小比尔/5
发帖
2582
只看该作者 16楼 发表于: 2009-06-10
rs232没有时钟,只要收发时钟误差小于6%(?)就可正常接收
---  -- …… -  ---
  |  |     |  |
  |  |     |  |
  ----     ----
 下沿、起始位 数据  拉高:停止条件

另外,如果晶振足够准确,rs232可以达到比较高的速度,有同学用115200bps的波特率和arm进行通信,完全没问题(要求usb->rs232使用外部晶振)
用在ask时的主要问题是基线漂移和起始位误差
因为1和0的数目不等,所以信号中有直流分量,ask不允许长连0和长连1,否则就会出现误码

曼彻斯特码:
用上下沿的位置表示0和1,例如:
此时真正的0和1电平数目相等,就没有基线漂移问题
---    --- ------
  |    | | |    |
  |    | | |    |
  ------ ---    ---
  0    1   1    0

脉宽调制码:
例如:用1/3占空比表示0,2/3占空比表示1
---     ------ ------ ---
| |     |    | |    | | |
| |     |    | |    | | |
| |------    ---    --- ------
0       1      1      0
这种编码调制解调比较方便,用单片机的pca单元或者异步解调都可以,但存在基线漂移问题,最好先将要发送的数据扰乱,使0和1的概率相等

另外,ask接收模块的边沿位置有时不是很准确,想上下沿一起传数据比较困难(甚是头疼)

fsk over ask
先做fsk,然后调制在ask上
太慢了,不是很实用
离线小比尔/5
发帖
2582
只看该作者 17楼 发表于: 2009-06-11
看单片机版
有pt2262和pt2272的介绍
融会贯通哦 ^_^
离线永远的FM
发帖
12113
只看该作者 18楼 发表于: 2009-06-11
!!!!!!!!!!!!!!!!!!!!!!!
我也想到了楼上说的2262解码那个例子。这是个突破点
离线FMer
发帖
2549
只看该作者 19楼 发表于: 2009-06-11
曼彻斯特才是正解,不过此种编码由于加入了自同步脉冲,信道利用率要除以二,换句话讲波特率会翻倍.
若时钟精度较高,也可以考虑类似usb的nrz编码+长不变电平同步脉冲插入.这样信道利用率在随机数据下只会降低1%不到,不过编程稍稍复杂.