打印

RC500·续!关于函数调用后成员显示异常的问题!结构体被子

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

RT,之前发了个帖子,无人问津。所以无人问津这段时间里鄙人继续潜心研究,终于又遇到了一个蛋疼的问题。

关于结构体在子函数间的调用导致成员的值显示异常的问题。如下:

这是一个RC500的函数库里的一个子函数:
/////////////////////////////////////////////////////////////////////
//功    能:寻卡
//参数说明: req_code[IN]:寻卡方式
//                0x52 = 寻感应区内所有符合14443A标准的卡
//                0x26 = 寻未进入休眠状态的卡
//         pTagType[OUT]:卡片类型代码
//                0x0A= Mifare_UltraLight
//                0x04 = Mifare_One(S50)
//                0x02 = Mifare_One(S70)
//                0x08 = Mifare_Pro
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRequest(unsigned char req_code,unsigned char *pTagType)
{
   char status;   
   struct TranSciveBuffer MfComData;
   struct TranSciveBuffer *pi;
   pi = &MfComData;


   WriteRawRC(RegChannelRedundancy,0x03);
//无CRC,单独产生或者出现奇数的奇偶校验,

   //奇偶校验位在每个字节后插入发送数据流中并会出现在接收数据流的每个字节后
   ClearBitMask(RegControl,0x08);
//该位指示Crypto1 单元关闭因此与卡的所有数据通信都不被加密

   WriteRawRC(RegBitFraming,0x07);
//TxLastBits 用于位方式帧的发送TxLastBits

   //定义要发送的最后一个字节的位数目000指示最后字节的所有位都要发送在发送之后TxLastBits 自动清零
   SetBitMask(RegTxControl,0x03);
//关闭天线

   PcdSetTmo(4);
   MfComData.MfCommand = PCD_TRANSCEIVE;
   MfComData.MfLength=1;
   MfComData.MfData[0] = req_code;

   status = PcdComTransceive(pi);                    //①
   
   if (!status)
   {   
        if (MfComData.MfLength != 0x10)
        {   status = MI_BITCOUNTERR;   }
   }
   *pTagType     = MfComData.MfData[0];
   return status;


其中结构体struct TranSciveBuffer MfComData;在之前就声明了:
extern struct TranSciveBuffer{unsigned char MfCommand;
                              unsigned int  MfLength;
                              unsigned char MfData[64];
                             };



然后在处调用子程序PcdComTransceive,然后,问题来了。


PcdComTransceive源程序如下:
/////////////////////////////////////////////////////////////////////
//通过RC500和ISO14443卡通讯
//input: pi->MfCommand = RC500命令字
//       pi->MfLength  = 发送的数据长度
//       pi->MfData[]  = 发送数据
//output:status        = 错误字
//       pi->MfLength  = 接收的数据BIT长度
//       pi->MfData[]  = 接收数据
/////////////////////////////////////////////////////////////////////
char PcdComTransceive(struct TranSciveBuffer *pi)
{  
   bit recebyte = 0;
   char status;
   unsigned char irqEn   = 0x00;
   unsigned char waitFor = 0x00;
   unsigned char lastBits;
   unsigned char n;
   unsigned int i;
                              AAA=pi->MfLength;  //②这一句不是源程序,是我用一个全局变量AAA取之前的结构体的成员MfLength的值,然后放到12864上显示。AAA在12864上显示没问题,这是提出问题的基础。
   switch (pi->MfCommand)
   {
      case PCD_IDLE:
         irqEn   = 0x00;
         waitFor = 0x00;
         break;
      case PCD_WRITEE2:
         irqEn   = 0x11;
         waitFor = 0x10;
         break;
      case PCD_READE2:
         irqEn   = 0x07;
         waitFor = 0x04;
         recebyte=1;
         break;
      case PCD_LOADCONFIG:
      case PCD_LOADKEYE2:
      case PCD_AUTHENT1:
         irqEn   = 0x05;
         waitFor = 0x04;
         break;
      case PCD_CALCCRC:
         irqEn   = 0x11;
         waitFor = 0x10;
         break;
      case PCD_AUTHENT2:
         irqEn   = 0x04;
         waitFor = 0x04;
         break;
      case PCD_RECEIVE:
         irqEn   = 0x06;
         waitFor = 0x04;
         recebyte=1;
         break;
      case PCD_LOADKEY:
         irqEn   = 0x05;
         waitFor = 0x04;
         break;
      case PCD_TRANSMIT:
         irqEn   = 0x05;
         waitFor = 0x04;
         break;
      case PCD_TRANSCEIVE:
         irqEn   = 0x3D;
         waitFor = 0x04;
         recebyte=1;
         break;
      default:
         pi->MfCommand = MI_UNKNOWN_COMMAND;
         break;
   }
  

   
   if (pi->MfCommand != MI_UNKNOWN_COMMAND)
   {
      WriteRawRC(RegPage,0x00);
      WriteRawRC(RegInterruptEn,0x7F);
//清除中断使能

      WriteRawRC(RegInterruptRq,0x7F);
//清除中断标志

      WriteRawRC(RegCommand,PCD_IDLE);
//清除Command寄存器   

      SetBitMask(RegControl,0x01);
//清除FIFO指针


// WriteRawRC(RegControl,0x03);

      WriteRawRC(RegInterruptEn,irqEn|0x80);   
      for (i=0; i<1; i++)
      {
         WriteRawRC(RegFIFOData, pi->MfData);//将数据写入FIFO
      }
// AAA=pi->MfData[0];

      WriteRawRC(RegCommand, 0x52);//将指令写入Command寄存器
      i = 0x4500; //
AAA=ReadRawRC(RegCommand);

      do
      {

         n = ReadRawRC(RegInterruptRq);//当定时器TimerValue 寄存器值减为0 时置位
         i--;  
      }
      while ((i!=0) && !(n&irqEn&0x20) && !(n&waitFor));
//等待数据发送完 n&waitFor表示命令自动结束

//
  AAA=ReadRawRC(RegCommand);

    //  AAA=ReadRawRC(RegFIFOData);

// AAA=pi->MfData[0];

//
AAA=pi->MfCommand;

      status = MI_COM_ERR;

      if ((i!=0) && !(n&irqEn&0x20))
  //FIFO数据超限或i=0

      {
   

         if (!(ReadRawRC(RegErrorFlag)&0x17))
   //没出错

         {
            status = MI_OK;
            if (recebyte) //从PICC读数据
表示有返回数据

            {

              
n = ReadRawRC(RegFIFOLength);//指示保存在FIFO 缓冲区的字节数


//写入FIFOData寄存器增加,读减少FIFOLength

              
lastBits = ReadRawRC(RegSecondaryStatus) & 0x07;

                if (lastBits)//显示最后接收字节的有效位个数如果为0 整个字节有效
                {
                   pi->MfLength = (n-1)*8 + lastBits;
                }
                else
                {
                   pi->MfLength = n*8;//计算比特数长度
                }
                if (n == 0)
                {
                   n = 1;
                }
                for (i=0; i<n; i++)
                {
                    pi->MfData = ReadRawRC(RegFIFOData);//读出FIFO的数据
                }
            }
         }

else if (ReadRawRC(RegErrorFlag)&0x01)//如果检测到一个位冲突该位置位该位在PrepareRx



   //状态中接收器的启动阶段自动清零

         {

    status = MI_COLLERR;

            if (recebyte)
            {
              
n = ReadRawRC(RegFIFOLength);

              
lastBits = ReadRawRC(RegSecondaryStatus) & 0x07;

                if (lastBits)
                {
                   pi->MfLength = (n-1)*8 + lastBits;
                }
                else
                {
                   pi->MfLength = n*8;
                }
                if (n == 0)
                {
                   n = 1;
                }
                for (i=0; i<n; i++)
                {
                    pi->MfData[i+1] = ReadRawRC(RegFIFOData);
                }
            }

pi->MfData[0]=ReadRawRC(0x0B);

         }

      }
      else if (n & irqEn & 0x20)
      {   status = MI_NOTAGERR;  sond=0; }
      else if (!(ReadRawRC(RegErrorFlag)&0x17))
      {   status = MI_ACCESSTIMEOUT;   }
      else
      {   status = MI_COM_ERR;    }

      WriteRawRC(RegInterruptEn,0x7F);
      WriteRawRC(RegInterruptRq,0x7F);
      SetBitMask(RegControl,0x04);           // stop timer now
      WriteRawRC(RegCommand,PCD_IDLE);
   }
   return status;
}




}





我在处插入一个全局变量AAA(自己定义,调试用的)观察pi->MfLength的时候,pi->MfLength的值就从1变成2了,而且无论在第一个子函数PcdRequest里怎么改变MfComData.MfLength的值,到了第二个子函数PcdComTransceive以后pi->MfLength都会变成2,貌似是固定了的。。。


同样的方法,我用AAA在第一个子函数里观察就正常,到了第二个子函数就不正常,这非常诡异。


但是,用同样的方法观察,pi->MfCommand(这是结构体的第一个成员就是正常的,第一个子函数负什么值,它在第二个子函数里都能正常显示。
今天一天,问了3个老师,C语言的老师说从C的角度,应该是没问题,叫我换一个角度考虑。其他两个老师找不出原因,鼓励我继续看程序找原因。。。。
RC500的确是一个很难搞懂的芯片,一路上遇见很多奇怪的问题。所以特地来二姨家诚心发问,希望谁做过的能帮帮我,这几天真是被这个搞得郁闷透了。。。









相关帖子

沙发
er357951|  楼主 | 2012-5-18 18:30 | 只看该作者
补充说明一下,整个程序除了调用子程序后结构体成员的值出错外,其他的都正常,毕竟是一个库函数,网上DOWN的。

而且是第一个结构体的第一个成员不出错,第二第三个就出错。

他们一出错,就影响后面程序的运行,就一直错下去进不了正确流程了。

曾经怀疑是不是第二个子函数在定义临时变量的时候把结构体的地址给覆盖了,但是老师说应该不可能,我感觉也是。

很诡异,希望懂的好心人帮忙解惑一下,不胜感激、、。。

使用特权

评论回复
板凳
er357951|  楼主 | 2012-5-18 18:44 | 只看该作者
继续补充说明,鄙人用的的是RC500  单片机用的是STC的89C58硬件连接之前检查3天了,应该没问题。
那个程序现在上传,方便交流。

如果有什么说的不清楚或着什么地方没提到的,欢迎指正,我会马上修改的。
多谢大家了。
RC500Driver.rar (123.13 KB)

使用特权

评论回复
地板
er357951|  楼主 | 2012-5-18 20:34 | 只看该作者
刚刚查到是  关于 结构指针 的问题

使用特权

评论回复
5
foreruny| | 2014-10-10 11:23 | 只看该作者
er357951 发表于 2012-5-18 18:44
继续补充说明,鄙人用的的是RC500  单片机用的是STC的89C58硬件连接之前检查3天了,应该没问题。
那个程序 ...

有上位机通信协议吗?谢谢!

使用特权

评论回复
6
林子旅| | 2016-7-22 18:07 | 只看该作者
请问楼主是怎么解决的?我现在也遇到这个问题了

使用特权

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

本版积分规则

1

主题

57

帖子

1

粉丝