找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5195|回复: 4
打印 上一主题 下一主题
收起左侧

CCD红外扫描枪 PS/2接口协议的郁闷

[复制链接]
跳转到指定楼层
楼主
ID:68618 发表于 2014-11-22 16:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CCD红外扫描枪,PS/2接口,如果用232接口的价格贵点,MCU那边程序处理好一点,扫描出来的条码扫描枪按照PS/2协议自动发送给上位机,默认形式下有个终止符,就是回车键,键值是0x5a,0xf0,0x5a,现在的情况是扫描EAN-13型的条码,当然对接收的数据可以采用两种办法,判断接收的位数,因为位数是死的,到那个位数值就处理判断,然后送LCD显示看一下,还有一种就是判断有没有碰到终止符,碰到就说明一组数据传输完毕,毕竟条码有长有短,为了灵活运用,偶还是采用了判断终止符的办法。奇怪无比郁闷的是老是成功阅读了若干个条码后会无法判断识别出终止符了。MCU肯定没死机,执行其他程序是OK的,因为没有仿真器,所以设置了几个点亮关闭LED的动作来判断程序到底出错在哪里。折腾了三天了,急死了。唉,附一些程序。

void Receive_Data(void)
    {
          if((Int_counter>0)&&(Int_counter<9))   //第1位起始位低电平抛弃,故从第2次中断开始到第9次中断是8位数据
          {
               Key_buf=Key_buf>>1;
               if((DATA_STATUS))
              Key_buf|=0x80;//如果数据线是高电平,则为1
          }
        Int_counter++;
        while(!(CLK_STATUS));//等待PS/2的CLK拉高
     
        if(Int_counter>10)
         {
              Int_counter=0;
              Receive_status|=BIT(0);//成功接收一个数据后设置一个判断位
         }
   }   
   
/********************************INT1中断**************************************/
#pragma interrupt_handler int1_isr:3
void int1_isr(void)
      {
             if(IsEnd==FALSE)
              {
                    Receive_Data();
                    if(Receive_status&0x01)
                     {
                            Receive_status&=~BIT(0);
                            PS2_Receive.buf[PS2_Receive.cnt]=Key_buf;//第0个即存放第一个数据
                            PS2_Receive.cnt++;
                            LED_GREEN_ON;
                            if(PS2_Receive.buf[PS2_Receive.cnt-1]==0x5a)//碰到"ENTER"终止符,通码+断码为0x5a+0xf0,0x5a
                            {
                                   IsEnd=TRUE;
                                   Endcnt=0;
                                   LED_RED_ON;
                            }
                       if(PS2_Receive.cnt>64)//正常的话,数据接收不可能超过64个,如果成功阅读碰到终止符,程序跳转执行完后会自动清PS2_Receive.cnt;无法阅读,LED_GREEN老是接收了满数据后暗灭交替,IsEnd老是为FALSE,也就是判断不到0x5a啊,就是郁闷在这里。
                        {
                                 LED_GREEN_OFF;
                        }
          }
     }   
    else
     {
           Receive_Data();
           if(Receive_status&0x01)
             {
                   PS2_Receive.buf[PS2_Receive.cnt]=Key_buf;
                   PS2_Receive.cnt++;   
                   Receive_status&=~BIT(0);
                   Endcnt++;
                   if(Endcnt==2)
                   {
                           if((PS2_Receive.buf[PS2_Receive.cnt-1]==0x5a)&&(PS2_Receive.buf[PS2_Receive.cnt-2]==0xf0))     
                             {
                                   if((SendToRBuf(PS2_Receive)==COMM_NO_ERR))
                                    {
                                          Comm_status|=BIT(7);
                                    }
                                  IsEnd=FALSE;
                                  Endcnt=0;
                                  PS2_Receive.cnt=0;
                                  LED_GREEN_OFF;
                           }
                         else
                           {
                                 IsEnd=FALSE;
                                 Endcnt=0;
                                 PS2_Receive.cnt=0;
                                 Scan_error|=BIT(7);   
                          }
                  }
             }
        }
   }                                                                                                  
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:68618 发表于 2014-11-22 16:08 | 只看该作者
奶奶的,老天终于开眼,昨天晚上应该是彻底搞定了。这几天一直感觉还有层纸,一直捅不破,就在成功的边缘。PS/2协议的格式11个CLK信号,第一个DATA线上是START BIT,要为低电平,然后余下8个CLK是数据,再接下来两个CLK是奇偶校验位和STOP BIT,接收端的子程序也是网上看别人写的,他们就很简单的把第一个CLK和最后两个CLK省略掉不判断了,也是可以很好的成功接收判断的,而且偶运用的时候一开始也是能够接收好多是成功的。但是他们那种是对应PS/2接口的键盘做的,毕竟敲一个键下去才有数据传输,而且时间间隔比较久,不象偶这种情况一下子连续几十个数据过来,头脑里想想如果某个数据接收错误,判断不到终止符,会重新读几遍会好的,但实际情况很糟糕,错了一个后连续读若干遍的数据都是错误的,又没有仿真器,只能一步步摸索,后来发现接收过来的数据感觉老是会少右移若干位。想想以前接收无线电信号的码头,UART传输,都要严格判断初始的码头或命令头,于是严格按照PS/2的协议,第一次CLK产生后,下降沿中断进去后,先判断一下,DATA线上的START BIT是不是为0,如果不为0,就舍弃,结果昨晚试了上千下,证实下来有很多时候会判断到START BIT是不为0的,但读出来的数据准确率几乎是99.9%以上了,就发现一次错误,还是第一位数字不正确,余下的都是正确的,而且程序也都能顺利执行,不会中断发生后老是捕捉不到终止符。积聚几天的郁闷情绪一扫而光,现在才完成整个项目的1/6左右工作量,要加快进度了。
以下是接收的代码。
void Receive_Data(void)
    {
if(Int_counter==0)
{
      if((DATA_STATUS)==0)
{
     Enable=1;
     Int_counter++;
}
        else
{
     Enable=0;
     LED_GREEN_ON;
         }
}
else
{
      if(Enable)
      {
                   if((Int_counter>0)&&(Int_counter<9)) //第1位起始位低电平抛弃,故从第2次中断开始到第9次中断是8位数据
                    {
                        Key_buf=Key_buf>>1;
                        if(DATA_STATUS)
                        Key_buf|=0x80;//如果数据线是高电平,则为1
                    }
                   Int_counter++;  
                   while(!(CLK_STATUS));//等待PS/2的CLK拉高  
     
                   if(Int_counter>10)
                    {
                        Int_counter=0;
      Enable=0;
                        Receive_status|=BIT(0);//成功接收一个数据后设置一个判断位
                    }  
      }
        }
   }
LED_GREEN_ON还是会动作的,主程序里再把LED清掉,LED闪烁出现的频率还是蛮多的,大概快速连续扫描几十个条码后会出现闪烁一下。但数据是成功正确的。
回复

使用道具 举报

板凳
ID:68618 发表于 2014-11-22 16:09 | 只看该作者
一个字,晕!
两个字,真晕!
三个字,还是晕!
四个字,彻底的晕!
回复

使用道具 举报

地板
ID:80259 发表于 2015-5-17 15:13 | 只看该作者
楼主,您好。请问您可不可以把您写的关于CCD红外扫描器与单片机的通信整个程序给我?谢谢
邮箱:2274074978@qq.com
回复

使用道具 举报

5#
ID:157626 发表于 2016-12-26 00:04 | 只看该作者
楼主,我们也在做这个东西,可以帮我们做么,有偿。邮箱:cwlong163@163.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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