IIC和SPI的最大区别在于,SPI不需要写地址和读地址,作为一个四线通信的协议用到w25qxx系列的闪存进行数据通信。初始化中除了MISO输入端需要设置浮空(跟串口的接收一样)外其余引脚均设置为推挽输出。
RC522与NFC卡进行通信需要对其寄存器进行写入,定于发送和接收的模式(和什么卡通信)。在除了读取卡信息外还有消费、加密等不同的设置方式可供使用,目前在本项目里只需进行信息读取即可,故选用模式A的工作方式,只读取Mifare卡信息。初始化程序:
RC522_Init (); printf ( "WF-RC522 InitReady\n" );
PcdReset();
M500PcdConfigISOType('A');//设置工作方式
在M500PcdConfigISOType函数里有PcdAntennaOn()这个函数,用于开启RC522上的天线进入里面有ReadRawRC(),里面拉低片选脚后发送了寄存器地址表示选中,获取完从机信息后重新拉高表示取消选中。由此我们可以通过复制PcdAntennaOn()函数的方式,设置九种PcdAntennaOn1、PcdAntennaOn2......进行九次的片选,在其内部进行引脚替换,分别拉低不同的片选脚。如此设置九个函数后即是SPI多从机读取,我们只需放在系统自检部分,启动时完成九次扫描即可得出目前书包所有位置上分别携带/未携带什么书。
void PcdAntennaOn ( void )//开启天线
{
u8 uc;
uc = ReadRawRC ( TxControlReg );
if ( ! ( uc & 0x03 ) )
SetBitMask(TxControlReg, 0x03);//防冲突
}
u8 ReadRawRC ( u8 ucAddress )
{
u8 ucAddr, ucReturn;
ucAddr = ( ( ucAddress << 1 ) & 0x7E ) | 0x80;
macRC522_CS_Enable();//拉低片选表示选中,复制替换我们自行创建的片选脚
SPI_RC522_SendByte ( ucAddr );//发送寄存器地址
ucReturn = SPI_RC522_ReadByte ();//获取从机发回的信息
macRC522_CS_Disable();//关闭片选脚,方便下一个从机选中
return ucReturn;//返回数据
}
在分别读取每张NFC卡后记录第三位数,分别标记为九种课本,将ID判断与设立好的全局变量进行if关联。IC_test()函数主要负责以上识别卡的功能,函数里只列入六本书的变量是因为我只有六张卡.......
void IC_test ( void )//刷卡
{
char cStr [ 30 ];
u8 ucArray_ID [ 4 ]; //先后存放IC卡的类型和UID(IC卡序列号)
u8 ucStatusReturn; //返回状态
static u8 ucLineCount = 0;
while(1)
{
key = KEY_Scan(0);
if(key == WKUP_PRES)
{
break;
}
printf("开始监测\r\n");
if ( ( ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ) ) != MI_OK ) //寻卡
{
ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ); //若失败再次寻卡
}
if ( ucStatusReturn == MI_OK )
{
if ( PcdAnticoll ( ucArray_ID ) == MI_OK ) //防冲撞(当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作)
{
sprintf ( cStr, "The Card ID is: %02X%02X%02X%02X", ucArray_ID [ 0 ], ucArray_ID [ 1 ], ucArray_ID [ 2 ], ucArray_ID [ 3 ] );
//sprintf类型转换,把ucArray数组中四个元素转换成十六进制后以字符串的形式存在cStr数组里面
printf ( "%s\r\n",cStr );
printf("%d %d %d %d\r\n",ucArray_ID [ 0 ],ucArray_ID [ 1 ],ucArray_ID [ 2 ],ucArray_ID [ 3 ]);//数据经过十六进制转换和补零,这里输出原始数据直接进行比较
//printf ( "%s\r\n",cStr );
//这里是进行识别卡↓
if(ucArray_ID [ 1 ]==182)//class1
{
Mathshu=1;
}
else
{
Mathshu=0;
}
if(ucArray_ID [ 1 ]==51)//class2
{
Chineseshu=1;
}
else
{
Chineseshu=0;
}
if(ucArray_ID [ 1 ]==228)//class3
{
Englishshu=1;
}
else
{
Englishshu=0;
}
if(ucArray_ID [ 1 ]==18)//class4
{
Physicsshu=1;
}
else
{
Physicsshu=0;
}
if(ucArray_ID [ 1 ]==46)//class5
{
Biologyshu=1;
}
else
{
Biologyshu=0;
}
if(ucArray_ID [ 1 ]==188)//class6
{
Chemistryshu=1;
}
else
{
Chemistryshu=0;
}
//这里是进行识别卡↑
if ( ucLineCount == 0 )
ucLineCount ++;
if ( ucLineCount == 17 ) ucLineCount = 0;
}
}
break;
}
}
最后将结果和AT24C02读取当日课程函数后改变的课程全局变量作if判断,结果填入最终结果数组class_total,判断class_total数组里的每一位元素进行LCD显示即可完成书包的系统自检部分功能函数的编写。