[讨论] 帖子刷新太快,再发求救贴

linjingui   2009-8-28 13:41 楼主
用上位机发送
“a123456789012345678901234567890” (串口调试工具,ascii码)
下位机用串口中断响应
当接到“a”时,将后面的30个数据保存到d【30】数组里。
有很好的解决方案吗?
如果直接用d【i】= RXBUF0的话 波特率的误差会导致有时出错。
请大侠们提供个好的方案和参考代码。谢谢啦!

回复评论 (10)

回复 楼主 linjingui 的帖子

用过dsp的串口,有握手通行的机制的。
https://bbs.eeworld.com.cn/thread-83529-1-1.html
希望对你有所帮助。。。。。。
我的邮箱gaoxiaoan123@163.com!回帖是一种美德!互相帮助,共同进步! 口头禅:生活在于创造机会,把握机会!
点赞  2009-8-28 14:16
烙铁的回复
  1. #include
  2. ungigned char date[30];
  3. static int i = 0;
  4. bit flag_uart=0;
  5. void init_uart()
  6. {
  7. SCON = 0x50; //串口方式1,允许接收
  8. TMOD = 0x20; //定时器1定时方式2
  9. TCON = 0x40; //设定时器1开始计数
  10. TH1 = 0xF4; //11.0592MHz 2400波特率
  11. TL1 = 0xF4;
  12. EA=1;
  13. ES=1;
  14. TR1 = 1; //启动定时器
  15. }
  16. void main(void)
  17. {
  18. unsigned char p;
  19. init_uart();
  20. while(1)
  21. {
  22. if(flag_uart)
  23. {
  24. //进行数据处理
  25. ES=0;
  26. for(p=0;p<30;p++) //发送数据
  27. {
  28. SBUF=date[p];
  29. while(TI==0);
  30. TI=0;
  31. }
  32. flag_uart=0;
  33. ES=1;
  34. }
  35. }


  36. }
  37. void usart1(void)interrupt 4
  38. {
  39. while(RI==0);
  40. RI=0;
  41. date[i++]=SBUF; //接收数据
  42. if(date[0]!=97) i=0;
  43. if(i>30)
  44. {
  45. i=0;
  46. flag_uart=1;
  47. }


没有编译,试试吧
加油!在电子行业默默贡献自己的力量!:)
点赞  2009-8-28 14:43
一般双机或者多机通信,都会制定通信协议,通信协议的一般格式是:
起始字节  地址码  指令码  中间数据  校验码  结束字节
起始字节    起始字节一般占用一个字节长度   用来建立双方的通信过程,确认是否开始通信。主机发送起始字节,从机收到后进行判断,如果从机判断起始码正确,从机开始接收后面的数据,否则不接受
地址码     地址码一般占一个或两个字节长度   主要用于多机通信的场合,主机发送地址码后  ,从机根据地址码判断是否是本机地址,如果是,继续接收数据,否则不再接收后续数据
指令码      指令码一般也是一个或两个字节   从机根据收到的指令码执行相应的操作
中间数据    中间数据的字节可以有很多字节组成
校验码      校验码一般占一个字节或者2、3个字节,一般是:地址码+指令码+中间数据,对结果进行求和或者求和后取反,或者进行CRC校验,从机对前面接受的数据也进行相应校验计算,然后将结果跟这个校验码比较,如果相等,说明数据接收正确,否则数据有错误
结束字节   一般占一个字节,用于确认一个数据发送和接收的结束,从机收到后进行判断,如果确认为结束字节,则结束本次数据的接收。
点赞  2009-8-28 15:41

5楼 yjj 

比较好懂!呵呵
点赞  2009-8-28 15:53
这个一般格式和描述,懂了
可是怎么实现呢?
要涉及到很多寄存器吧
点赞  2009-8-28 16:05
这个主要靠编程实现,用不到很多寄存器,甚至可以说不牵涉别的寄存器,还是靠串口收发数据的那个寄存器。
举例来说吧,比如一个系统由一个上位机和2个下位机(分别是1#,2#)组成,上位机和下位机就是我们常说的主机和从机,
主机要给1#发一条指令,那么按照上面我们说的通信协议:起始码  地址码 指令码 数据码  校验和 结束码
假设上位机给1#机发送1234这几个数据,
起始码设为5A,
地址码为01,
指令码为00,
数据就是01,02,03,04,占4个字节,
校验码就采用地址码+指令码+数据,然后将这些加起来求和(注意,按字节相加,结果只取最低8位,也即校验和只占一个字节),那么校验码计算如下:01(地址码)+00(指令码)+01+02+03+04=0b,
结束码设为A5,
那么主机要发送的数据就是5A,01,00,01,02,03,04,0b,A5,将这些数据放在一个数组里面,比如A【9】。然后通过串口,将这个数组的数据发送出去。

1#从机收到串口中断信号后,开始接收数据,判断收到的第一个字节是不是5A,如果是,继续接受第二个字节,判断是不是01,是01,那就是上位机给自己发的信号(2#机受到01后,判断不是给自己的数据,就不再接受后面的数据);那么就会继续接受后面的数据,接收第三个字节为指令码00(假设这条指令是要1#机给上位机回发数据的指令,那么,接收完这些数据后,1#机还要给上位机回发数据)。然后接收后面的数据字节,接下来的连续4个字节都是数据,从机在接收这些数据的同时,还要把地址码,指令码,数据进行相加,得到一个值,然后把这个值与从串口收到的第8个字节比较,如果相等,则说明数据传输过程没有错误,可以正常处理这些数据,否则要抛弃这些数据。最后接受第9个字节,看看是不是A5,如果是,这次数据接收过程完全正确,否则出错,抛弃这些数据。
从机接收数据的时候,可以把所有收到的数据放到一个数组里(比如B【9】),确认所有收到的数据正确后,可以从这个数组里分检出有用的信息,分别处理,
如果需要向上位机回送信息,按照上述方法发送信息即可。

呵呵,啰里啰嗦说了这么多,如果说得不好,还请见谅
点赞  2009-8-28 16:42

回复 7楼 tiankai001 的帖子

厉害!!
点赞  2009-8-28 16:45

回复 8楼 小志 的帖子

呵呵,正好知道一点这方面的东西,
顺便拿出来晾晾,有不对的地方也好请大家指正


包包昨天收到了,呵呵,空包重量3斤2量,真是很有“分量”啊
点赞  2009-8-28 16:52
呵呵,还很漂亮呢!
点赞  2009-8-28 17:00

回复 10楼 admin 的帖子

确实很漂亮,而且质量也是没的说
感谢EEWORLD,
点赞  2009-8-28 17:16
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复