搜索
bottom↓
回复: 8

上位机发送字符串,单片机接收无法识别,新手入门求助...

[复制链接]

出0入0汤圆

发表于 2012-12-29 17:49:45 | 显示全部楼层 |阅读模式
  1. #include <at89x51.h>
  2. #define kai 0;
  3. #define guan 1;
  4. unsigned char table[2];
  5. unsigned char flag;
  6. unsigned char a;//a用来存放串口接收到的数据
  7. unsigned char b;//b用来存放串口接收到的数据
  8. sbit a0=P2^0;
  9. sbit a1=P2^1;  


  10. main()
  11. {

  12.         TMOD=0x20;//定时器1使用初值自动重装方式,方式2
  13.         TH1=0xfd;
  14.         TL1=0xfd;//9600波特率初值
  15.         TR1=1;//允许定时器计数
  16.         SM0=0;//方式1设置
  17.         SM1=1;
  18.         REN=1; //允许串口接收
  19.         EA=1;  //开总中断
  20.         ES=1;  //开串口中断

  21.         while(1)
  22.         {
  23. a=table[0];
  24. b=table[1];
  25. if(flag==1){
  26.            if(a==49&&b==49)
  27.            {
  28.                             a0=kai;
  29.                                 SBUF=1;
  30.                                 flag=0;
  31.                                
  32.                                  }
  33.            else if(a==49&&b==48)
  34.            {
  35.                             a1=kai;
  36.                                 SBUF=2;
  37.                                 flag=0;
  38.                                  }
  39.            else ;
  40.   }          
  41. }
  42. }


  43. void serial () interrupt 4
  44. {
  45.    unsigned char i;
  46.    if(RI)
  47.    {
  48.     RI=0;
  49.            for(i=0;i<2;i++)
  50.     {
  51.            while(!RI);
  52.            table[i]=SBUF;
  53.                    flag=1;
  54.             
  55.     }
  56.    }   
  57.            if(TI)
  58.         {
  59.                 TI=0;
  60.         }
  61. }
复制代码
以上就是程序啦。现在遇到这么一个问题。上位机发送字符11。进入if(a==49&&b==49)。发送10 有时候进入这个,有时候进入if(a==49&&b==48)。发送1有时候也会进入if(a==49&&b==49)。反正就是很乱。如果把flag==1去掉。又正常。这个是为什么。我觉得问题应该出在中断上,我刚学中断,一直没搞懂,现在还是没搞懂,求助。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-12-29 18:32:07 | 显示全部楼层
本帖最后由 snic_k 于 2012-12-29 18:33 编辑

接收数据处理有问题,不够严密。

收到第一个数据时,如果有数据丢失,则会造成数据混乱。
例:当你发送11时,第一位丢失,只收到1,因你的程序中断中要死等第二位,所以当你在发送第二次数据11或10时,收到11或10的第一位,刚好与上次收到的1组成了11,第二次发送的11或10的第二位看情况,有可能丢失,也有可能可以被正确收到。总之就是数据结构乱了。

建议:
1、中断中最好收到一个数据就存入相应的table中,不要等待第二个数据。接收完后在主程序中再去判断数据长度等。
2、数据传输有可能因某些因素导致数据丢失,最好加上引导码,如第一个数据发送0XA5,第二个发送0x5A等,单片机收到数据首先判断第一个第二个数据是否是0XA55A,如不是则收到的数据做丢弃处理,这样可以保证所收到的数据不会乱掉。如此可以解决像我刚上面所提到的因丢数据造成的数据结构混乱。

出0入0汤圆

 楼主| 发表于 2012-12-29 20:00:15 | 显示全部楼层
这个,你说的思路我明白,程序上怎么写呢。比如引导码,不太懂。

出0入4汤圆

发表于 2012-12-29 20:01:02 | 显示全部楼层
snic_k 发表于 2012-12-29 18:32
接收数据处理有问题,不够严密。

收到第一个数据时,如果有数据丢失,则会造成数据混乱。

学习了,很详细~

出0入4汤圆

发表于 2012-12-29 20:14:14 | 显示全部楼层
51757517@qq.com 发表于 2012-12-29 20:00
这个,你说的思路我明白,程序上怎么写呢。比如引导码,不太懂。

字头 0XA5   判断一下,是了继续做下一个判断,不是这组全扔掉,做其他事情,过会再回来判断还是不是0XA5,不是再扔掉,到字头是0XA5了,判断下一个字节~~~我是这么干过~~

出0入0汤圆

发表于 2012-12-29 20:41:21 | 显示全部楼层
51757517@qq.com 发表于 2012-12-29 20:00
这个,你说的思路我明白,程序上怎么写呢。比如引导码,不太懂。

引导码不就是相当于多发送了一个或两个字节的数据么。。。。比如你原来是发送11程12两个数据,现在加上两字节的的引导码。那就是一次发送四个数据嘛。。
稍微改了下。。

#include <at89x51.h>
#define kai 0;
#define guan 1;
unsigned char table[4];
unsigned char flag;
unsigned char a;//a用来存放串口接收到的数据
unsigned char b;//b用来存放串口接收到的数据
sbit a0=P2^0;
sbit a1=P2^1;  

//----------------------------------------------
//增加部份
unsigned char DataLen;
//----------------------------------------------


main()
{

        TMOD=0x20;//定时器1使用初值自动重装方式,方式2
        TH1=0xfd;
        TL1=0xfd;//9600波特率初值
        TR1=1;//允许定时器计数
        SM0=0;//方式1设置
        SM1=1;
        REN=1; //允许串口接收
        EA=1;  //开总中断
        ES=1;  //开串口中断

        //----------------------------------------------
        // 增加部份
        DataLen = 0x00;
        //----------------------------------------------

    while(1)
    {
                if(flag==1)
                {
                   if(a==49&&b==49)
                   {
                     a0=kai;
                SBUF=1;
                                
            }
           else if(a==49&&b==48)
           {
               a1=kai;
               SBUF=2;
           }
           else ;

                   flag = 0;
                  }           
        }
}


void serial () interrupt 4
{
        if(RI)
        {
                if(DataLen > 1)
                {
                        table[DataLen] = SBUF;

                        //判断一帧数据是否接收完毕
                        if(++DataLen > 3)
                        {
                                DataLen = 0x00;
                                flag = 1;
                        }
                }
       

                else
                {
                        table[DataLen] = SBUF;

                        if(++DataLen == 0x02)
                        {
                                // 已接收到大于2字节数据,判断引导码是否正确
                                if((table[0] != 0xA5) || (table[1] != 0x5A))
                                {
                                        // 引导码不正确,接收数据长度指针置0
                                        DataLen = 0x00;
                                }
                        }
                }
        }


        TI = 0;
        RI = 0;
}

出0入0汤圆

 楼主| 发表于 2012-12-29 20:54:09 | 显示全部楼层
谢谢~~  我先试一下,吸收一下。

出0入0汤圆

 楼主| 发表于 2012-12-29 21:50:48 | 显示全部楼层
出现个问题。我上位机发送的是字符串ASCII码。怎么让转换成0xA5 16进制。

出0入0汤圆

 楼主| 发表于 2012-12-29 22:45:05 | 显示全部楼层
我用上位机发16进制。A55A0101 进不了循环。 怪事
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 15:53

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表