该程序连基本的读取IC卡的卡号也读不出来,staus总是返回MI_ERR。输出一直是There is no card!
以下是main.c的程序:
#include "stm32f10x.h"
#include "delay.h"
#include "stdio.h"
#include "string.h"
#include "ic.h"
//*连线说明:
//*1--SS <----->PA4
//*2--SCK <----->PA5
//*3--MOSI<----->PA6
//*4--MISO<----->PA7
//*5--悬空
//*6--GND <----->GND
//*7--RST <----->PE15
//*8--VCC <----->VCC
/*全局变量*/
unsigned char CT[2];//卡类型
unsigned char SN[4]; //卡号
unsigned char RFID[16];unsigned char lxl_bit=0;
unsigned char card1_bit=0;
unsigned char card2_bit=0;
unsigned char card3_bit=0;
unsigned char card4_bit=0;
unsigned char total=0;
unsigned char lxl[4]={6,109,250,186};
unsigned char card_1[4]={66,193,88,0};
unsigned char card_2[4]={66,191,104,0};
unsigned char card_3[4]={62,84,28,11};
unsigned char card_4[4]={126,252,248,12};
u8 KEY[6]={0xff,0xff,0xff,0xff,0xff,0xff};//卡的缺省密码
unsigned char RFID1[16]={0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x07,0x80,0x29,0xff,0xff,0xff,0xff,0xff,0xff};
/*函数声明*/
//void ShowID(u8 *p); //显示卡的卡号,以十六进制显示
void Store(u8 *p,u8 store,u8 cash);//最重要的一个函数
//u8 ReadData(u8 addr,u8 *pKey,u8 *pSnr,u8 *dataout);
//u8 WriteData(u8 addr,u8 *pKey,u8 *pSnr,u8 *datain);
/****** GPIO引脚配置函数 *********/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO的结构体
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//RX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//RES
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_ResetBits(GPIOE,GPIO_Pin_15);//PE15输出低
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//NSS
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//SCK
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//MISO
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //此处设置为GPIO_Mode_IPU时,输出速度变快
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//MOSI
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //PA5/6/7上拉
}
void RCC_Configuration()
{
SystemInit();
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );//SPI1时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
//波特率,字长,停止位,奇偶校验位,硬件流控制位,模式
USART_InitStructure.USART_BaudRate=9600;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //如果没有使能中断以及清除中断标志位,printf会先输出乱码
USART_Cmd(USART1,ENABLE);
USART_ClearFlag(USART1,USART_FLAG_TC);
}
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8)ch;
return ch;
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
}
int main()
{
unsigned char status;
//unsigned char s=0x08;
u8 j;
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART_Configuration();
InitRc522();
while(1)
{
status = PcdRequest(PICC_REQALL,CT);/*尋卡*/
if(status==MI_OK)//尋卡成功
{
printf("PcdRequest_MI_OK\r\n");
status=MI_ERR;
status = PcdAnticoll(SN);/*防冲撞*/
}
if (status==MI_OK)//防衝撞成功
{
printf("PcdAnticoll_MI_OK\r\n");
status=MI_ERR;
//printf("ID:%02x %02x %02x %02x\n",SN[0],SN[1],SN[2],SN[3]);//发送卡号
printf("The Card ID is:");
for(j=0;j<4;j++)
{
printf("%02x ",SN[j]);
}
if((SN[0]==lxl[0])&&(SN[1]==lxl[1])&&(SN[2]==lxl[2])&&(SN[3]==lxl[3]))
{
lxl_bit=1;
printf("The User is:lxl");
}
if((CT[0]==card_1[0])&&(CT[1]==card_1[1])&&(SN[2]==card_1[2])&&(SN[3]==card_1[3]))
{
card1_bit=1;
printf("The User is:card_1");
}
if((SN[0]==card_2[0])&&(SN[1]==card_2[1])&&(SN[2]==card_2[2])&&(SN[3]==card_2[3]))
{
card2_bit=1;
printf("The User is:card_2");
}
if((SN[0]==card_3[0])&&(SN[1]==card_3[1])&&(SN[2]==card_3[2])&&(SN[3]==card_3[3]))
{
card3_bit=1;
printf("The User is:card_3");
}
if((SN[0]==card_4[0])&&(SN[1]==card_4[1])&&(SN[2]==card_4[2])&&(SN[3]==card_4[3]))
{
card4_bit=1;
printf("The User is:card_4");
}
total=card1_bit+card2_bit+card3_bit+card4_bit+lxl_bit;
printf("total:");
printf("%d",total);
status =PcdSelect(SN);
//Reset_RC522();
}
else
{
printf("There is no card!\r\n");
}
}}
以下是RC522.c的程序:
#include "delay.h"
#include "stm32f10x.h"
#include "spi.h"
#include "ic.h"
#include "string.h"
void delay_ns(u32 ns)
{
u32 i;
for(i=0;i<ns;i++)
{
__nop();
__nop();
__nop();
}
}
void InitRc522(void)
{
SPI_Configuration();
PcdReset();//复位后,RST=1
PcdAntennaOff();
delay_ms(2);
PcdAntennaOn();
M500PcdConfigISOType('A');
}
void Reset_RC522(void)
{
PcdReset();
PcdAntennaOff();
delay_ms(2);
PcdAntennaOn();
}
/////////////////////////////////////////////////////////////////////
//功 能:寻卡
//参数说明: req_code[IN]:寻卡方式
// 0x52 = 寻感应区内所有符合14443A标准的卡
// 0x26 = 寻未进入休眠状态的卡
// pTagType[OUT]:卡片类型代码
// 0x4400 = Mifare_UltraLight
// 0x0400 = Mifare_One(S50)
// 0x0200 = Mifare_One(S70)
// 0x0800 = Mifare_Pro(X)
// 0x4403 = Mifare_DESFire
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRequest(u8 req_code,u8 *pTagType)
{
char status;
u8 unLen;
u8 ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08);//清除MRCrypto1on,要用软件清零
WriteRawRC(BitFramingReg,0x07);//startsend=0,rxalign=0,在FIFO中存放的位置,TXlastbit=7
SetBitMask(TxControlReg,0x03);//TX2rfen=1,TX1RFen=1,传递调制的13.56MHZ的载波信号
ucComMF522Buf[0] = req_code;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);
if ((status == MI_OK) && (unLen == 0x10))
{
*pTagType = ucComMF522Buf[0];
*(pTagType+1) = ucComMF522Buf[1];
}
else
{
status = MI_ERR;
}
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdAnticoll(u8 *pSnr)
{
char status;
u8 i,snr_check=0;
u8 unLen;
u8 ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08);
WriteRawRC(BitFramingReg,0x00);//表示最后一个字节所有位都发送
ClearBitMask(CollReg,0x80);//CollRegCollReg0冲突结束后冲突位被置零
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x20;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);
if (status == MI_OK)
{
for (i=0; i<4; i++)
{
*(pSnr+i) = ucComMF522Buf[i];
snr_check ^= ucComMF522Buf[i];
}
if (snr_check != ucComMF522Buf[i])
{
status = MI_ERR;
}
}
SetBitMask(CollReg,0x80); //CollRegCollReg在106kbps良好的防冲突情况下该位置1
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:选定卡片
//参数说明: pSnr[IN]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdSelect(u8 *pSnr)
{
char status;
u8 i;
u8 unLen;
u8 ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x70;
ucComMF522Buf[6] = 0;
for (i=0; i<4; i++)
{
ucComMF522Buf[i+2] = *(pSnr+i);
ucComMF522Buf[6] ^= *(pSnr+i);
}
CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);
ClearBitMask(Status2Reg,0x08);//清零MFcryon statue
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
if ((status == MI_OK) && (unLen == 0x18))
{
status = MI_OK;
}
else
{
status = MI_ERR;
}
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:验证卡片密码
//参数说明: auth_mode[IN]: 密码验证模式
// 0x60 = 验证A密钥
// 0x61 = 验证B密钥
// addr[IN]:块地址
// pKey[IN]:密码
// pSnr[IN]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdAuthState(u8 auth_mode,u8 addr,u8 *pKey,u8 *pSnr)
{
char status;
u8 unLen;
u8 ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = auth_mode;//验证A密钥
ucComMF522Buf[1] = addr; //addr[IN]:块地址
// for (i=0; i<6; i++)
// {
// ucComMF522Buf[i+2] = *(pKey+i);
// }
// for (i=0; i<6; i++)
// {
// ucComMF522Buf[i+8] = *(pSnr+i);
// }
memcpy(&ucComMF522Buf[2], pKey, 6);
memcpy(&ucComMF522Buf[8], pSnr, 4);
status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
{
status = MI_ERR;
}
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:读取M1卡一块数据
//参数说明: addr[IN]:块地址
// p [OUT]:读出的数据,16字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRead(u8 addr,u8 *p )
{
char status;
u8 unLen;
u8 i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_READ;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
if ((status == MI_OK) && (unLen == 0x90))
// { memcpy(p , ucComMF522Buf, 16); }
{
for (i=0; i<16; i++)
{
*(p +i) = ucComMF522Buf[i];
}
}
else
{
status = MI_ERR;
}
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:写数据到M1卡一块
//参数说明: addr[IN]:块地址
// p [IN]:写入的数据,16字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdWrite(u8 addr,u8 *p )
{
char status;
u8 unLen;
u8 i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_WRITE;//1字节
ucComMF522Buf[1] = addr;//1字节
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);//用上面2字节数据计算CRC(2字节)
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);//发送以上4字节
if((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
if (status == MI_OK)
{
//memcpy(ucComMF522Buf, p , 16);
for (i=0; i<16; i++)
{
ucComMF522Buf[i] = *(p +i);
}
CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);//用16字节的数据计算CRC(2字节)
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);//16字节数据+2字节CRC
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
}
return status;
}
/////////////////////////////////////////////////////////////////////
//功 能:命令卡片进入休眠状态
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdHalt(void)
{
volatile u8 status;//这里status需要定义为volatile类型,不然会出现没有使用的警告
u8 unLen;
u8 ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_HALT;
ucComMF522Buf[1] = 0;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);//用上面2字节数据计算CRC(2字节)
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
return MI_OK;
}
|
|