串口问题
时间:10-02
整理:3721RD
点击:
通过串口助手(9600-8-0-1)发送三个字节,如果首字节为0x34,则返回两个字节0x03、0x00,继续等待接受新输入;如果首字节不是0x34,则不作应答,等待接受新输入。调试发现如果连续手动输入34 01 02返回结果正确,可一旦输入首字节不是34(如01 02 03),则再输入34 01 02也没有反应了。通过观察窗发现最后输的34 01 02没有被读进数组receive。然后加入else那一段,即首字节不是34的话就返回ff,这样两种情况都正常返回,且可以连续输入。看上去好像要再接受字符的话必须要先发送字符?没道理啊,请各位帮帮忙。
我用的是C8051F310。本来是在编modbus从机端程序如果从机号不对的话就不响应,结果也是不能接受新的命令帧了。
我用的是C8051F310。本来是在编modbus从机端程序如果从机号不对的话就不响应,结果也是不能接受新的命令帧了。
- #include "initial.h"
- #include <string.h>
- typedef unsigned char byte;
- byte send[20]; //用于存放发送的数据,最大ModBus帧是256字节
- byte receive[20]; //用于存放接收的数据
- byte rec_ptr; //用于给接收到的数据编号
- byte rec_flag; //rec_flag=1时表示已接收到一帧数据,对数据帧解析完rec_flag被置为0
- byte rec_bytes; //接收的字节数
- main(void)
- {
- byte i;
- byte *ssd;
- rec_ptr = 0;
- rec_flag= 0;
- PCA0MD &= ~0x40; // WDTE = 0 关闭看门狗,上电默认打开
- Init();
-
- EA=1; //允许所有中断
-
- while(1)
- {
- while (rec_flag==1)
- {
- send[0]= rec_bytes;
- send[1]= 0x00;
- ssd = send;
- if(receive[0] == 0x34)
- {
- for(i=0;i<2;++i)
- {
- ACC = *ssd;
- TB80 = ~P;
- SBUF0=*ssd++;
- while(TI0==0);
- TI0=0;
- }
- }
- /* else
- {
- ACC = *xFF;
- TB80 = ~P;
- SBUF0=0xFF;
- while(TI0==0);
- TI0=0;
- } */
- rec_flag=0;
- }
- }
- }
- void uart0(void) interrupt 4
- {
- if(RI0)
- {
- RI0=0;
- receive[rec_ptr++] = SBUF0; // rec_ptr初始值为0,每接受一个数据便自增1
-
- if (rec_ptr==3 )
- {
- rec_bytes = rec_ptr;
- rec_ptr = 0;
- rec_flag = 1;
- }
- }
- }
你每次读入3个数据到数组里是不对的
应该判断是34才开始往数组里放
而且收到的数据应该拷贝的另外一个地方
否则后来的数据就把你之前收到的数据给覆盖掉了
我是把一次读入的3个字节都存到数组receive[]里,然后再根据receive[0]做不同响应,这样不对吗?每次接收到3个字节后rec_ptr清零,等主程序处理好数据后再通过串口助手输入新的数据,本来就是要覆盖receive[]的阿
求详细说明
最怕中间丢了一个数,那你就找不到34开头的数了
换了个串口助手软件就可以了..坑