完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
该程序连基本的读取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_OKrn"); status=MI_ERR; status = PcdAnticoll(SN);/*防冲撞*/ } if (status==MI_OK)//防衝撞成功 { printf("PcdAnticoll_MI_OKrn"); status=MI_ERR; //printf("ID:%02x %02x %02x %02xn",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!rn"); } }} 以下是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 __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; } ///////////////////////////////////////////////////////////////////// //用MF522计算CRC16函数 ///////////////////////////////////////////////////////////////////// void CalulateCRC(u8 *pIn ,u8 len,u8 *pOut ) { u8 i,n; ClearBitMask(DivIrqReg,0x04); WriteRawRC(CommandReg,PCD_IDLE); //取消当前命令 SetBitMask(FIFOLevelReg,0x80); //FlushBuffer?清除ErrReg?的标志位 for(i=0; i WriteRawRC(FIFODataReg, *(pIn +i)); } WriteRawRC(CommandReg, PCD_CALCCRC); i = 0xFF; do { n = ReadRawRC(DivIrqReg); i--; }while ((i!=0) && !(n&0x04));//当CRCIRq所有数据被处理完毕该位置位 pOut [0] = ReadRawRC(CRCResultRegL); pOut [1] = ReadRawRC(CRCResultRegM); } ///////////////////////////////////////////////////////////////////// //功 能:复位RC522 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// char PcdReset(void) { //PORTD|=(1< delay_ns(10); //PORTD&=~(1< delay_ns(10); //PORTD|=(1< delay_ns(10); WriteRawRC(CommandReg,PCD_RESETPHASE); //WriteRawRC(CommandReg,PCD_RESETPHASE); delay_ns(10); WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30); //定时器的低8位数据 WriteRawRC(TReloadRegH,0); //定时器的高8位数据 WriteRawRC(TModeReg,0x8D); //定时器模式寄存器,定时器减值计数 WriteRawRC(TPrescalerReg,0x3E); //实际值是OXD3E,这部分主要是设置定时器寄存器 WriteRawRC(TxAutoReg,0x40);//必须要,设置逻辑1,强制100%ASK调制 return MI_OK; } ////////////////////////////////////////////////////////////////////// //设置RC522的工作方式 ////////////////////////////////////////////////////////////////////// char M500PcdConfigISOType(u8 type) { if (type == 'A') //ISO14443_A { ClearBitMask(Status2Reg,0x08);//状态2寄存器 WriteRawRC(ModeReg,0x3D);//3F 和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(RxSelReg,0x86);//84 选择内部接收器设置,内部模拟部分调制信号,发送数据后,延迟6个位时钟,接收 WriteRawRC(RFCfgReg,0x7F); //4F 配置接收器48dB最大增益 WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) WriteRawRC(TReloadRegH,0); //实际值是OXD3E,这部分主要是设置定时器寄存器 WriteRawRC(TModeReg,0x8D); WriteRawRC(TPrescalerReg,0x3E); delay_ns(1000); PcdAntennaOn(); } else { return 1; } return MI_OK; } ///////////////////////////////////////////////////////////////////// //功 能:读RC522寄存器 //参数说明:Address[IN]:寄存器地址 //返 回:读出的值 ///////////////////////////////////////////////////////////////////// u8 ReadRawRC(u8 Address) { u8 ucAddr; u8 ucResult=0; CLR_SPI_CS; ucAddr = ((Address<<1)&0x7E)|0x80;//变化成有效的地址形式,最低位为0,最高位为1时候是,从MFRC522读出数据 SPIWriteByte(ucAddr); ucResult=SPIReadByte(); SET_SPI_CS; return ucResult; } ///////////////////////////////////////////////////////////////////// //功 能:写RC522寄存器 //参数说明:Address[IN]:寄存器地址 // value[IN]:写入的值 ///////////////////////////////////////////////////////////////////// void WriteRawRC(u8 Address, u8 value) { u8 ucAddr; // u8 tmp; CLR_SPI_CS; ucAddr = ((Address<<1)&0x7E);//变化成有效的地址形式,最低为为0,最高位为1时候是,写入MFRC522数据 SPIWriteByte(ucAddr); SPIWriteByte(value); SET_SPI_CS; // tmp=ReadRawRC(Address); // // if(value!=tmp) // printf("wrongn"); } ///////////////////////////////////////////////////////////////////// //功 能:置RC522寄存器位 //参数说明:reg[IN]:寄存器地址 // mask[IN]:置位值 ///////////////////////////////////////////////////////////////////// void SetBitMask(u8 reg,u8 mask) { char tmp = 0x0; tmp = ReadRawRC(reg); WriteRawRC(reg,tmp | mask); // set bit mask } ///////////////////////////////////////////////////////////////////// //功 能:清RC522寄存器位 //参数说明:reg[IN]:寄存器地址 // mask[IN]:清位值 ///////////////////////////////////////////////////////////////////// void ClearBitMask(u8 reg,u8 mask) { char tmp = 0x0; tmp = ReadRawRC(reg); WriteRawRC(reg, tmp&~mask); // clear bit mask } ///////////////////////////////////////////////////////////////////// //功 能:通过RC522和ISO14443卡通讯 //参数说明:Command[IN]:RC522命令字 // pIn [IN]:通过RC522发送到卡片的数据 // InLenByte[IN]:发送数据的字节长度 // pOut [OUT]:接收到的卡片返回数据 // *pOutLenBit[OUT]:返回数据的位长度 ///////////////////////////////////////////////////////////////////// char PcdComMF522(u8 Command,u8 *pIn,u8 InLenByte,u8 *pOut,u8 *pOutLenBit) { char status = MI_ERR; u8 irqEn = 0x00; u8 waitFor = 0x00; u8 lastBits; u8 n; u16 i; switch (Command) { case PCD_AUTHENT: irqEn = 0x12; waitFor = 0x10; break; case PCD_TRANSCEIVE: //send data in the FIFO irqEn = 0x77; waitFor = 0x30; break; default: break; } WriteRawRC(ComIEnReg,irqEn|0x80);//容许除定时器中断请求以及所有中断请求 ClearBitMask(ComIrqReg,0x80); //清所有中断位 WriteRawRC(CommandReg,PCD_IDLE);//取消当前命令 SetBitMask(FIFOLevelReg,0x80); //清FIFO缓存 for (i=0; i WriteRawRC(FIFODataReg, pIn [i]);//写寻卡命令 } WriteRawRC(CommandReg, Command);//发送并接收数据 // n = ReadRawRC(CommandReg); if (Command == PCD_TRANSCEIVE) { SetBitMask(BitFramingReg,0x80);//相当于启动发送STARTSENG //StartSend=1,transmission of data starts } //开始传送 //i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms i = 10000; do { n = ReadRawRC(ComIrqReg);//n为返回数据的字节数 i--; }while ((i!=0) && !(n&0x01) && !(n&waitFor)); ClearBitMask(BitFramingReg,0x80);//相当于清除发送STARTSENG//StartSend=0 if (i!=0)//定时时间到,i没有递减到0 { if(!(ReadRawRC(ErrorReg)&0x1B))//BufferOvfl Collerr CRCErr ProtecolErr { status = MI_OK; if (n & irqEn & 0x01) { status = MI_NOTAGERR; } if (Command == PCD_TRANSCEIVE) { n = ReadRawRC(FIFOLevelReg); lastBits = ReadRawRC(ControlReg) & 0x07; //得出接受字节中的有效位,如果为0,全部位都有效 if (lastBits) { *pOutLenBit = (n-1)*8 + lastBits;//返回数据的位长度 } else { *pOutLenBit = n*8;//返回数据的位长度 } if (n == 0) { n = 1; } if (n > MAXRLEN) { n = MAXRLEN; } for (i=0; i pOut [i] = ReadRawRC(FIFODataReg);//接收卡片返回的数据 } } } else { status = MI_ERR; } } SetBitMask(ControlReg,0x80); // stop timer now WriteRawRC(CommandReg,PCD_IDLE); return status; } ///////////////////////////////////////////////////////////////////// //打开天线 ///////////////////////////////////////////////////////////////////// void PcdAntennaOn(void) { u8 i; i = ReadRawRC(TxControlReg); if (!(i & 0x03)) { SetBitMask(TxControlReg, 0x03); } } ///////////////////////////////////////////////////////////////////// //关闭天线 ///////////////////////////////////////////////////////////////////// void PcdAntennaOff(void) { ClearBitMask(TxControlReg, 0x03);//tx12RFEN==00,禁止发射管脚 } 以下是spi的相关设置: #include "stm32f10x.h" #include "spi.h" //SPI 速度设置函数 //SpeedSet: //SPI_BaudRatePrescaler_2 2分频 //SPI_BaudRatePrescaler_8 8分频 //SPI_BaudRatePrescaler_16 16分频 //SPI_BaudRatePrescaler_256 256分频 void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler) { assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); SPI1->CR1&=0XFFC7; SPI1->CR1|=SPI_BaudRatePrescaler; //设置SPI1速度 SPI_Cmd(SPI1,ENABLE); } void SPI_Configuration(void) { SPI_InitTypeDef SPI_InitStructure; SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为低电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第一个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPI1, ENABLE); //使能SPI外设 SPI1_ReadWriteByte(0xff);//启动传输 } u8 SPIWriteByte(u8 Byte) { while((SPI1->SR&0X02)==0); //等待发送区空 SPI1->DR=Byte; //发送一个byte while((SPI1->SR&0X01)==0); //等待接收完一个byte return SPI1->DR; //返回收到的数据 } //SPIx 读写一个字节 //TxData:要写入的字节 //返回值:读取到的字节 u8 SPI1_ReadWriteByte(u8 TxData) { u8 retry=0; while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位 { retry++; if(retry>200) return 0; } SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据 retry=0; while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位 { retry++; if(retry>200) return 0; } return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据 } |
|
相关推荐
|
|
有没有初始化RC522?RC522是工作在SPI模式下吗?
|
|
|
|
|
|
有的,InitRc522()就是对RC522进行初始化的,它跟STM32用SPI1进行通信 |
|
|
|
|
|
if (status==MI_OK)//防衝撞成功
这几段程序放到第一个if语句里面
status=MI_ERR; 这句话注释掉 |
|
|
|
|
|
http://blog.csdn.net/wangfei447976098/article/details/17348969
![]() |
|
|
|
|
|
参考一下
找到一个代码 void RcSetReg(unsigned char Address, unsigned char value) { unsigned char i, ucAddr; MF522_SCK = 0; MF522_NSS = 0; ucAddr = ((Address<<1)&0x7E); for(i=8;i>0;i--) { MF522_SI = ((ucAddr&0x80)==0x80); MF522_SCK = 1; ucAddr <<= 1; MF522_SCK = 0; } for(i=8;i>0;i--) { MF522_SI = ((value&0x80)==0x80); MF522_SCK = 1; value <<= 1; MF522_SCK = 0; } MF522_NSS = 1; MF522_SCK = 1; } /************************************************* Function: RcSetReg Description: Write data to register of RC522 Parameter: RegAddr The address of the regitster RegVal The value to be writen Return: None **************************************************/ /* void RcSetReg(unsigned char RegAddr, unsigned char RegVal) { unsigned char EchoByte; short status; RegAddr &= 0x3f; //code the first byte putchar(RegAddr); putchar(RegVal); status = getchar(&EchoByte, 10000); } */ ///////////////////////////////////////////////////////////////////// //¹¦ ÄÜ£º¶ÁRC632¼Ä´æÆ÷ //²ÎÊý˵Ã÷£ºAddress[IN]:¼Ä´æÆ÷µØÖ· //·µ »Ø£º¶Á³öµÄÖµ ///////////////////////////////////////////////////////////////////// unsigned char RcGetReg(unsigned char Address) { unsigned char i, ucAddr; unsigned char ucResult=0; MF522_SCK = 0; MF522_NSS = 0; ucAddr = ((Address<<1)&0x7E)|0x80; for(i=8;i>0;i--) { MF522_SI = ((ucAddr&0x80)==0x80); MF522_SCK = 1; ucAddr <<= 1; MF522_SCK = 0; } for(i=8;i>0;i--) { MF522_SCK = 1; ucResult <<= 1; ucResult|=(bit)MF522_SO; MF522_SCK = 0; } MF522_NSS = 1; MF522_SCK = 1; return ucResult; } 不知道为什么要左移 |
|
|
|
|
|
你好遇到同样问题,找卡这个步骤不成功,我是移植到msp430上的,端口设置确认没有问题,电压也在正常范围,示波器测好像波形也有的,不知道啥问题了,lz能分享下调试经验么,非常感谢
|
|
|
|
|
|
我也遇到这个问题了,lz解决了没
|
|
|
|
|
|
使用stm32l451片子,对ad7606进行3通道100k采样值跳动问题?
135 浏览 0 评论
STM32进行DMA数据转运,为什么只有A组最后一位数据被转运到B组去?
1337 浏览 2 评论
1650 浏览 3 评论
1258 浏览 0 评论
嵌入式开发 Win11安装ST-Link 提示 设备描述符请求失败 怎么处理?
1391 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-19 17:21 , Processed in 1.035027 second(s), Total 120, Slave 96 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191