STM32+RC522读写M1卡遇到的定时器超时问题
最近在弄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 ) /*
* 函数名: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
搞定了,原来是我初始化的问题
谢谢你 我也遇到了同样的问题请问你怎么解决的? 穷开心 发表于 2018-4-29 00:55
我也遇到了同样的问题请问你怎么解决的?
我的当时是我自己初始化没弄好,你现在卡在哪一步了? 布丁奶茶 发表于 2018-5-18 16:58
我的当时是我自己初始化没弄好,你现在卡在哪一步了?
楼主我也遇到这个问题了,不知道你说的初始化要注意什么
能发一下你的程序给我吗,我邮箱513658269@qq.com
我也出现了同样的问题,我现在是在寻卡的时候读取不到卡,&unLen=0, 您好,我也出现同样错误了, if ( ucN & ucIrqEn & 0x01 ) //是否发生定时器中断在这儿出现错误了,您具体说一下初始化哪块出现了问题。谢谢
1060316027@qq.com svenyang 发表于 2018-5-25 17:05
楼主我也遇到这个问题了,不知道你说的初始化要注意什么
能发一下你的程序给我吗,我邮箱
...
好久没来21了,我的程序不方便发你,因为涉及到公司的产品,而且我的初始化是针对我自己的产品的,你只要选卡没问题,一般都是能读卡的 本帖最后由 布丁奶茶 于 2019-1-9 16:36 编辑
jackyle6 发表于 2018-5-30 15:03
您好,我也出现同样错误了, if ( ucN & ucIrqEn & 0x01 ) //是否发生定时器中断在这儿出现错误了, ...
抱歉,最近忙项目去了。问题不是出在这,这么说吧,一般网上的参考例程的初始化都是ok的,你要看你具体在哪个步骤有问题。
布丁奶茶 发表于 2018-6-13 16:30
抱歉,最近忙项目去了。问题不是出在这,这么说吧,一般网上的参考例程的初始化都是ok的,你要看你具体在 ...
嗯,前两天找到问题的原因了,是因为自己做的天线电容焊接处没焊上,我重新焊好后就可以自动寻卡,读卡了,也谢谢你的帮助。 布丁奶茶 发表于 2017-9-25 15:19
/*
* 函数名:PcdComMF522
* 描述:通过RC522和ISO14443卡通讯
不知道楼主还来不来21,我最近也在做RC522,我一直是没有寻到卡,也是卡在了定时器超时的阶段,测得ComIrqReg寄存器值同样为0x45,我也一直是怀疑初始化有问题,不知道楼主当时是初始化那一部分做了修改,方便指导一下吗 你以前做的RS522项目还在不,我现在也是寻卡不成功,再判断中断后就结束了。 jackyle6 发表于 2018-6-14 15:10
嗯,前两天找到问题的原因了,是因为自己做的天线电容焊接处没焊上,我重新焊好后就可以自动寻卡,读卡了 ...
以前做的RS522项目还在不,现在也是寻卡不成功,再判断中断后就结束了。 欲言还修 发表于 2019-2-28 09:25
以前做的RS522项目还在不,现在也是寻卡不成功,再判断中断后就结束了。...
寻卡不成功首次查查通信,通信没问题的话再查查天线,最后再查驱动 一摸一样的问题,定时器超时,FIFO中受到的字节是0
页:
[1]