打印

串口通信有问题

[复制链接]
1820|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
victor3l|  楼主 | 2012-8-6 17:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 victor3l 于 2012-8-6 21:09 编辑

我的报文组织函数

xdata uchar datTab[16] = {0};//组织报文的


/*************************************************
函数名         :void DealDat(float num)
入口参数       :float
返回值         :无
全局变量       :uchar datTab[16]
功能           :组织报文
**************************************************/
void DealDat(float num)
{
uchar totalInt = 0;                           //总重的整数部分
uchar totalDec = 0;                           //总重的小数部分
uchar check = 0;                              //校验信息
uchar x1 = 0;                                 //中间变量的处理
uchar x2 = 0;
uchar x3 = 0;
uchar x4 = 0;
uchar x5 = 0;
uchar x6 = 0;
datTab[0] = 0x24;                             //一下5位都是固定的
datTab[1] = 0x6a;
datTab[2] = 0x45;
datTab[3] = 0x30;
datTab[4] = 0x30;                             //上面两个30好像没有实际意义
datTab[5] = 0x30;                             //下面2位数据是固定的数据长度
datTab[6] = 0x33;
if(num > 0)                                  //数据是正的,要用0x20表示
{
  datTab[7] = 0x32;
  datTab[8] = 0x30;
}
else                                     //数据是负数要用0x2D表示。注意要用大写的字符
{
  datTab[7] = 0x32;
  datTab[8] = 0x44;
}

if(num > 0)
  totalInt = (uint)(num);                 //我的总重整数部分由问题   2012年6月11日17:06:54
else
  totalInt = (uint)(-num);
x1 = (totalInt >> 4);                      //把整数部分的高位(4位)他的范围是0----F
if( (x1 >= 0) && (x1 < 10) )                //0,1,2,3,4,5,6,7,8,9数据的ascii
  datTab[9] = x1 + 0x30;
else if( (x1 > 9) && (x1 < 16))            //ABCDEF数据的ascii
  datTab[9] = x1 + 0x37;

x2 = (totalInt & 0x0f);                   //取出整数部分的低位(4位)他的范围是0----F
if((x2 >= 0) && (x2 < 10))
  datTab[10] = x1 + 0x30;
else if((x2 > 9) && (x2 < 16))            //ABCDEF数据的ascii
  datTab[10] = x2 + 0x37;
/*********************小数部分******************************/
if(num > 0)   
  totalDec = ((uint)(num * 100)) % 100;  //取出小数部分,这里也变成了整数了
else
  totalDec = ((uint)((-num) * 100)) % 100;  //取出小数部分,这里也变成了整数了
x3 = totalDec >> 4;                        //小数部分的高位 (4位)
if((x3 >= 0) && (x3 < 10))
  datTab[11] = x3 + 0x30;
else if((x3 > 9) && (x3 < 16))
  datTab[11] = x3 + 0x37;
x4 = (totalDec & 0x0f);
if((x4 >= 0) && (x4 < 10))
  datTab[12] = x4 + 0x30;
else if((x4 > 9) && ( x4 < 16))
  datTab[12] = x4 + 0x37;
if(num > 0)
  check = 0^0x03^0x20^totalInt^totalDec;
else
  check = 0^0x03^0x2D^totalInt^totalDec;

  
x5 = (check >> 4);                       //取出校验的高四位的
if((x5 >= 0) && (x5 < 10))
  datTab[13] = x5 + 0x30;  
else if((x5 > 9) && (x5 < 16))
  datTab[13] = x5 + 0x37;
x6 = check & 0x0f ;                       //取出校验的低四位
if((x6 >= 0) && (x6 < 10))
  datTab[14] = x6 + 0x30;
else if((x6 > 9) && (x6 < 16))
  datTab[14] = x6 + 0x37;
  
datTab[15] = 0x0d;                        //数据的结束标志。
    SendStr(datTab,16);
  
}

当上位机发送24 6a 45 0d这4个字节时,并且单片机收到后把标志位置位,在主循环中根据标志位把总重发送给串口,单片机在中断中接收串口发来的数据。
程序如下:
void Comser()interrupt 4
{
uchar count;
uchar i;
static uchar ComBuf[4] = {0};
ES = 0;
if(RI)
{
  RI = 0;
  ComBuf[0] = SBUF;                    //进了串口中断,就是接收数据的开始,而且此时第一个字节已经接收成功了.所以要及时将其保存.
  for(i = 1;i < 4; i++)
  {
   while((!TI) && (++count < 250));
   count = 0;                       //count可有可无,如果要那也是在限制时间到时,这时应该将接收缓存清空
   RI = 0;
   
   ComBuf = SBUF;
   ComDelay(1);                    //延时时间不能长,否则前一数据会被后一数据覆盖,那数据就不齐了.
  }
  if((0x24 == ComBuf[0]) && (0x6a == ComBuf[1]) && (0x45 == ComBuf[2]) && (0x0d == ComBuf[3]))
   flag = 1;
}
ES = 1;
}

我现在的问题是:串口发送的数据单片机已经接收到了,也返回数据了,但是为什么返回的数据,总是跟实际的总重想差一点点,并且假如发上来的数据就是总重但是他的校验位还是错的,但是前一段时间就是这个程序,发送返回的都是正确的,这个是什么原因,请大家帮看看,上面的代码有什么问题,谢谢,也请做过的朋友提供点思路,谢谢



1通讯方式
标准RS232通讯;波特率:9600;通讯格式:8N18位数据,无奇偶校验位,有1位停止位。
2基本格式
a、称重传感器回复重量数据给GPS监控主机格式。
名称
长度

说明
起始标志
1
0x24
GPS接口共用
外设设备类型
1
0x6A
0x24 0x6A共同组成数据包头
命令字
1
0x45
指令类型
数据长度
2
0x00 0x03
固定的长度,3个十六进制数
符号
1
0x20/0x2D
0x20 0x2D
吨位小数点前两位
1
0x--

吨位小数点后两位
1
0x--

校验和
1
0x--
数据长度、符号、吨位共5个字节异或和
结束标志符
1
0x0D
回车符
发送时 黑色部分按十六进制发送,红色加下划线部分(数据长度,数据包,校验和)将一个十六进制数据拆分成两个十六进制数据发送,如0x3C,应该分别发送3CASCII0x330x43。数据中字母均用大写字母ASCII码。
例:重量为29.72吨,传输数据为:
0x24 0x6A 0x45 0x30 0x33 0x32 0x30 0x31 0x44 0x34 0x38 0x37 0x36 0x0D
上面这个是通信协议,我发现我的数据分离上出错了,但是有找不出来,当整数部分小于10的时候按照我的这个程序竟然传回的都是0了,但是就出现而言,我有找不出错误,请大家帮帮忙,完成这个协议,怎么写代码较好。

相关帖子

沙发
NE5532| | 2012-8-6 20:06 | 只看该作者
如果能确认程序没改过,就检查232芯片,市场上MAX开头的歪货很多,可能造成莫名其妙的数据错误。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

308

帖子

5

粉丝