[STM32]

STM32+RC522读写M1卡遇到的定时器超时问题

[复制链接]
5405|17
手机看帖
扫描二维码
随时随地手机跟帖
布丁奶茶|  楼主 | 2017-9-25 15:07 | 显示全部楼层 |阅读模式
最近在弄STM32F1读写M1卡,遇到的问题是:1.密码验证完成后往M1的某一块写16字节的数据,总是定时器超时。(我读ReadRawRC ( ComIrqReg )的值为0x45,说明定时器的值减到0产生了定时超时,但我不知道为什么会超时?)2.往M1卡写数据后再去读接收缓冲区的字节,发现没有任何数据。(ucN = ReadRawRC ( FIFOLevelReg );//读FIFO中保存的字节数,发现ucN等于0,说明卡片没有回数据,这又是为什么?)
程序是我在网上移植别人的,我看了一下,通信函数基本差不多。弄好好久还是不知道怎么解决。求弄过的大神指点指点,非常感谢!
以下是两个关键的函数:
/*
* 函数名:PcdComMF522
* 描述  :通过RC522和ISO14443卡通讯
* 输入  :ucCommand,RC522命令字
*         pInData,通过RC522发送到卡片的数据
*         ucInLenByte,发送数据的字节长度
*         pOutData,接收到的卡片返回数据
*         pOutLenBit,返回数据的位长度
* 返回  : 状态值
*         = MI_OK,成功
* 调用  :内部调用
*/
char PcdComMF522 ( u8 ucCommand, u8 * pInData, u8 ucInLenByte, u8 * pOutData, u32 * pOutLenBit )

相关帖子

布丁奶茶|  楼主 | 2017-9-25 15:19 | 显示全部楼层
/*
* 函数名:PcdComMF522
* 描述  :通过RC522和ISO14443卡通讯
* 输入  :ucCommand,RC522命令字
*         pInData,通过RC522发送到卡片的数据
*         ucInLenByte,发送数据的字节长度
*         pOutData,接收到的卡片返回数据
*         pOutLenBit,返回数据的位长度
* 返回  : 状态值
*         = MI_OK,成功
* 调用  :内部调用
*/
char PcdComMF522 ( u8 ucCommand, u8 * pInData, u8 ucInLenByte, u8 * pOutData, u32 * pOutLenBit )               
{
    char cStatus = MI_ERR;
    u8 ucIrqEn   = 0x00;
    u8 ucWaitFor = 0x00;
    u8 ucLastBits;
    u8 ucN;
    u32 ul;
       
       
    switch ( ucCommand )
    {
       case PCD_AUTHENT:                //Mifare认证
          ucIrqEn   = 0x12;                //允许错误中断请求ErrIEn  允许空闲中断IdleIEn
          ucWaitFor = 0x10;                //认证寻卡等待时候 查询空闲中断标志位
          break;
                         
       case PCD_TRANSCEIVE:                //接收发送 发送接收
          ucIrqEn   = 0x77;                //允许TxIEn RxIEn IdleIEn LoAlertIEn ErrIEn TimerIEn
          ucWaitFor = 0x30;                //寻卡等待时候 查询接收中断标志位与 空闲中断标志位
          break;
                         
       default:
         break;
                         
    }
   
    WriteRawRC ( ComIEnReg, ucIrqEn | 0x80 );                //IRqInv置位管脚IRQ与Status1Reg的IRq位的值相反
    ClearBitMask ( ComIrqReg, 0x80 );                        //Set1该位清零时,CommIRqReg的屏蔽位清零
    WriteRawRC ( CommandReg, PCD_IDLE );                //写空闲命令
    SetBitMask ( FIFOLevelReg, 0x80 );                        //置位FlushBuffer清除内部FIFO的读和写指针以及ErrReg的BufferOvfl标志位被清除
   
    for ( ul = 0; ul < ucInLenByte; ul ++ )
                  WriteRawRC ( FIFODataReg, pInData [ ul ] );                    //写数据进FIFOdata
                       
    WriteRawRC ( CommandReg, ucCommand );                                        //写命令
   
   
    if ( ucCommand == PCD_TRANSCEIVE )
                        SetBitMask(BitFramingReg,0x80);                                  //StartSend置位启动数据发送 该位与收发命令使用时才有效
   
    ul = 1000;//根据时钟频率调整,操作M1卡最大等待时间25ms
               
    do                                                                                                                 //认证 与寻卡等待时间       
    {
         ucN = ReadRawRC ( ComIrqReg );                                                        //查询事件中断
         ul --;
    } while ( ( ul != 0 ) && ( ! ( ucN & 0x01 ) ) && ( ! ( ucN & ucWaitFor ) ) );                //退出条件i=0,定时器中断,与写空闲命令
               
    ClearBitMask ( BitFramingReg, 0x80 );                                        //清理允许StartSend位
               
    if ( ul != 0 )
    {
                        if ( ! ( ReadRawRC ( ErrorReg ) & 0x1B ) )                        //读错误标志寄存器BufferOfI CollErr ParityErr ProtocolErr
                        {
                                cStatus = MI_OK;
                               
                                if ( ucN & ucIrqEn & 0x01 )                                        //是否发生定时器中断
                                  cStatus = MI_NOTAGERR;   
                                       
                                if ( ucCommand == PCD_TRANSCEIVE )
                                {
                                        ucN = ReadRawRC ( FIFOLevelReg );                        //读FIFO中保存的字节数
                                       
                                        ucLastBits = ReadRawRC ( ControlReg ) & 0x07;        //最后接收到得字节的有效位数
                                       
                                        if ( ucLastBits )
                                                * pOutLenBit = ( ucN - 1 ) * 8 + ucLastBits;           //N个字节数减去1(最后一个字节)+最后一位的位数 读取到的数据总位数
                                        else
                                                * pOutLenBit = ucN * 8;                                           //最后接收到的字节整个字节有效
                                       
                                        if ( ucN == 0 )               
            ucN = 1;   
                                       
                                        if ( ucN > MAXRLEN )
                                                ucN = MAXRLEN;   
                                       
                                        for ( ul = 0; ul < ucN; ul ++ )
                                          pOutData [ ul ] = ReadRawRC ( FIFODataReg );   
                                       
                                        }
                                       
      }
                       
                        else
                                cStatus = MI_ERR;   
                       
    }
   
   SetBitMask ( ControlReg, 0x80 );           // stop timer now
   WriteRawRC ( CommandReg, PCD_IDLE );
       
   return cStatus;
}



/*
* 函数名:PcdWrite
* 描述  :写数据到M1卡一块
* 输入  :u8 ucAddr,块地址
*         pData,写入的数据,16字节
* 返回  : 状态值
*         = MI_OK,成功
* 调用  :外部调用
*/
char PcdWrite ( u8 ucAddr, u8 * pData )
{
    char cStatus;
          u8 uc, ucComMF522Buf [ MAXRLEN ];
    u32 ulLen;
     
   
    ucComMF522Buf [ 0 ] = PICC_WRITE;
    ucComMF522Buf [ 1 ] = ucAddr;
       
    CalulateCRC ( ucComMF522Buf, 2, & ucComMF522Buf [ 2 ] );

    cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, & ulLen );

    if ( ( cStatus != MI_OK ) || ( ulLen != 4 ) || ( ( ucComMF522Buf [ 0 ] & 0x0F ) != 0x0A ) )
      cStatus = MI_ERR;   
        
    if ( cStatus == MI_OK )
    {
                        //memcpy(ucComMF522Buf, pData, 16);
      for ( uc = 0; uc < 16; uc ++ )
                          ucComMF522Buf [ uc ] = * ( pData + uc );  
                       
      CalulateCRC ( ucComMF522Buf, 16, & ucComMF522Buf [ 16 ] );

      cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 18, ucComMF522Buf, & ulLen );
                       
                        if ( ( cStatus != MI_OK ) || ( ulLen != 4 ) || ( ( ucComMF522Buf [ 0 ] & 0x0F ) != 0x0A ) )
        cStatus = MI_ERR;   
                       
    }
               
               
    return cStatus;
}

使用特权

评论回复
布丁奶茶|  楼主 | 2017-9-26 17:42 | 显示全部楼层
搞定了,原来是我初始化的问题

使用特权

评论回复
布丁奶茶 发表于 2017-9-26 17:42
搞定了,原来是我初始化的问题

谢谢你

使用特权

评论回复
穷开心| | 2018-4-29 00:55 | 显示全部楼层
我也遇到了同样的问题请问你怎么解决的?

使用特权

评论回复
布丁奶茶|  楼主 | 2018-5-18 16:58 | 显示全部楼层
穷开心 发表于 2018-4-29 00:55
我也遇到了同样的问题请问你怎么解决的?

我的当时是我自己初始化没弄好,你现在卡在哪一步了?

使用特权

评论回复
svenyang| | 2018-5-25 17:05 | 显示全部楼层
布丁奶茶 发表于 2018-5-18 16:58
我的当时是我自己初始化没弄好,你现在卡在哪一步了?

楼主我也遇到这个问题了,不知道你说的初始化要注意什么
能发一下你的程序给我吗,我邮箱513658269@qq.com

使用特权

评论回复
jackyle6| | 2018-5-29 21:10 | 显示全部楼层
我也出现了同样的问题,我现在是在寻卡的时候读取不到卡,&unLen=0,

使用特权

评论回复
jackyle6| | 2018-5-30 15:03 | 显示全部楼层
您好,我也出现同样错误了,   if ( ucN & ucIrqEn & 0x01 )   //是否发生定时器中断  在这儿出现错误了,您具体说一下初始化哪块出现了问题。谢谢
1060316027@qq.com

使用特权

评论回复
布丁奶茶|  楼主 | 2018-6-13 16:28 | 显示全部楼层
svenyang 发表于 2018-5-25 17:05
楼主我也遇到这个问题了,不知道你说的初始化要注意什么
能发一下你的程序给我吗,我邮箱
...

好久没来21了,我的程序不方便发你,因为涉及到公司的产品,而且我的初始化是针对我自己的产品的,你只要选卡没问题,一般都是能读卡的

使用特权

评论回复
布丁奶茶|  楼主 | 2018-6-13 16:30 | 显示全部楼层
本帖最后由 布丁奶茶 于 2019-1-9 16:36 编辑
jackyle6 发表于 2018-5-30 15:03
您好,我也出现同样错误了,   if ( ucN & ucIrqEn & 0x01 )   //是否发生定时器中断  在这儿出现错误了, ...

抱歉,最近忙项目去了。问题不是出在这,这么说吧,一般网上的参考例程的初始化都是ok的,你要看你具体在哪个步骤有问题。

使用特权

评论回复
jackyle6| | 2018-6-14 15:10 | 显示全部楼层
布丁奶茶 发表于 2018-6-13 16:30
抱歉,最近忙项目去了。问题不是出在这,这么说吧,一般网上的参考例程的初始化都是ok的,你要看你具体在 ...

嗯,前两天找到问题的原因了,是因为自己做的天线电容焊接处没焊上,我重新焊好后就可以自动寻卡,读卡了,也谢谢你的帮助。

使用特权

评论回复
阿泉爱学习| | 2018-10-25 14:45 | 显示全部楼层
布丁奶茶 发表于 2017-9-25 15:19
/*
* 函数名:PcdComMF522
* 描述  :通过RC522和ISO14443卡通讯

不知道楼主还来不来21,我最近也在做RC522,我一直是没有寻到卡,也是卡在了定时器超时的阶段,测得ComIrqReg寄存器值同样为0x45,我也一直是怀疑初始化有问题,不知道楼主当时是初始化那一部分做了修改,方便指导一下吗

使用特权

评论回复
欲言还修| | 2019-2-28 09:24 | 显示全部楼层
你以前做的RS522项目还在不,我现在也是寻卡不成功,再判断中断后就结束了。

使用特权

评论回复
欲言还修| | 2019-2-28 09:25 | 显示全部楼层
jackyle6 发表于 2018-6-14 15:10
嗯,前两天找到问题的原因了,是因为自己做的天线电容焊接处没焊上,我重新焊好后就可以自动寻卡,读卡了 ...

以前做的RS522项目还在不,现在也是寻卡不成功,再判断中断后就结束了。

使用特权

评论回复
布丁奶茶|  楼主 | 2019-3-11 17:04 | 显示全部楼层
欲言还修 发表于 2019-2-28 09:25
以前做的RS522项目还在不,现在也是寻卡不成功,再判断中断后就结束了。  ...

寻卡不成功首次查查通信,通信没问题的话再查查天线,最后再查驱动

使用特权

评论回复
370978973| | 2023-3-30 14:17 | 显示全部楼层
一摸一样的问题,定时器超时,FIFO中受到的字节是0

使用特权

评论回复
zwsam| | 2024-1-10 10:14 | 显示全部楼层

使用特权

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

本版积分规则

44

主题

180

帖子

1

粉丝