完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近用51单片机研究射频卡522,事先给空白卡里面写入学号信息,刷卡也能读取了,但是问题来了:“每次刷卡,刷一两次(可以正常读取卡信息哦)后,若显示读卡失败“ERR”时,读卡模块就卡住了,不会读取新过来的卡的数据了” 需要每次单片机重新复位,才能继续读取新卡数据。 以下是部分主程序部分,另外NRF2401和RC522调用函数子程序网上基本一样的,所以这里版面问题没扔出来。 //////////////////////////////////////////////////// //入口主函数 void main( ) { unsigned char status; unsigned char t; CE=0; SCK=0; CSN=1; Uartinital(); InitializeSystem( ); //初始化 while (1) { status=PcdRequest( PICC_REQALL, &RevBuffer[0] ) ; if( status!= MI_OK ) //寻天线区内未进入休眠状态的卡,返回卡片类型 2字节 { status=PcdRequest( PICC_REQIDL, &RevBuffer[0] ) ; if( status != MI_OK ){ //寻天线区内未进入休眠状态的卡,返回卡片类型 2字节 continue; } } status=PcdAnticoll( &RevBuffer[2] ); if( status!= MI_OK ){ //防冲撞,返回卡的序列号 4字节 DisplayListChar(10,1,lyERR); //错误返回 continue; } memcpy(MLastSelectedSnr,&RevBuffer[2],4); status=PcdSelect(MLastSelectedSnr); if(status!= MI_OK ){ //选卡 DisplayListChar(10,1,lyERR); continue; } status=PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, MLastSelectedSnr); if( status!= MI_OK){ // 校验卡密码A DisplayListChar(10,1,lyERR); continue; } status=PcdRead(1,&RevBuffer[2]); if(PcdRead(1,&RevBuffer[2])!= MI_OK) // 读卡了? { status=PcdRead(1,&RevBuffer[2]); if(status!= MI_OK)//再一次读卡确认 { DisplayListChar(10,1,lyERR); continue; } } cdHalt(); //终止卡的操作 就是以下2401部分导致刷卡刷正确一次卡死的问题所在。以下若删了,刷卡没问题(所以证明我的RFID-RC522程序没错的,问题出在下面主程序的小部分)。按说while循环里面怎么可能刷一次就卡住了呢,我猜仅仅发送了一次卡住没继续循环了,仅个人观点,大神来看看DisplayListChar(0,1,&RevBuffer[2]); for( t=0;t<=strlen(&RevBuffer[2]);t++) Tx_Buf[t]=*(&RevBuffer[2]+t); UartSend_string(Tx_Buf); if(nRF24L01_TxPacket(Tx_Buf)==TX_DS)//发送数组中的数据 或者使用这一句 nRF24L01_TxPacket(unsigned char * tx_buf) { } delay(200); //间隔时间 } } 那位大神帮忙看看,刷卡一两次后就要单片机复位,RC522模块才能继续读取新的卡,这是什么情况啊,起码来一个新卡,重新读吧?该怎么改好呢,跪求大神指点一二 以下是NRF2401的部分程序:#ifndef __2401_H__ #define __2401_H__ #define uchar unsigned char #define uint unsigned int //定义的端口为模块上标的端口// ***it MISO=P3^4; ***it MOSI=P3^0; ***it IRQ=P3^3; ***it CE=P3^5; ***it CSN=P3^1; ***it SCK=P3^2; uchar bdata sta; //状态标志bdata就是可位寻址内部数据存储区 ***it RX_DR = sta ^6;//接收数据准备就绪 ***it TX_DS =sta^5;//已发送数据 ***it MAX_RT =sta^4; #define TX_ADR_WIDTH 5 // 5 uints TX address width #define RX_ADR_WIDTH 5 // 5 uints RX address width #define TX_PLOAD_WIDTH 10 // 32 uints TX payload #define RX_PLOAD_WIDTH 10 // 32 uints TX payload uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址 uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址 uchar idata Tx_Buf[TX_PLOAD_WIDTH]={0};//发送数据 #define READ_REG 0x00 // 读寄存器指令 #define WRITE_REG 0x20 // 写寄存器指令 #define RD_RX_PLOAD 0x61 // 读取接收数据指令 #define WR_TX_PLOAD 0xA0 // 写待发数据指令 #define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令 #define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令 #define REUSE_TX_PL 0xE3 // 定义重复装载数据指令 #define NOP 0xFF // 保留 //**********************************SPI(nRF24L01)寄存器地址**/ #define CONFIG 0x00 // 配置收发状态,CRC校验模式 //以及收发状态响应方式 #define EN_AA 0x01 // 自动应答功能设置 #define EN_RXADDR 0x02 // 可用信道设置 #define SETUP_AW 0x03 // 收发地址宽度设置 #define SETUP_RETR 0x04 // 自动重发功能设置 #define RF_CH 0x05 // 工作频率设置 #define RF_SETUP 0x06 // 发射速率、功耗功能设置 #define STATUS 0x07 // 状态寄存器 #define OBSERVE_TX 0x08 // 发送监测功能 #define CD 0x09 // 地址检测 #define RX_ADDR_P0 0x0A // 频道0接收数据地址 #define RX_ADDR_P1 0x0B // 频道1接收数据地址 #define RX_ADDR_P2 0x0C // 频道2接收数据地址 #define RX_ADDR_P3 0x0D // 频道3接收数据地址 #define RX_ADDR_P4 0x0E // 频道4接收数据地址 #define RX_ADDR_P5 0x0F // 频道5接收数据地址 #define TX_ADDR 0x10 // 发送地址寄存器 #define RX_PW_P0 0x11 // 接收频道0接收数据长度 #define RX_PW_P1 0x12 // 接收频道0接收数据长度 #define RX_PW_P2 0x13 // 接收频道0接收数据长度 #define RX_PW_P3 0x14 // 接收频道0接收数据长度 #define RX_PW_P4 0x15 // 接收频道0接收数据长度 #define RX_PW_P5 0x16 // 接收频道0接收数据长度 #define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置 //******************************************延时函数 //长延时 void Deelay(unsigned int s) //延时约1ms,当s=1时; { unsigned int i,j; for(i=0;i<1000;i++)for(j=0;j } //短延时 void deelay_ms(unsigned int x) //延时约0.1ms,当x=1时 { unsigned int i,j; i=0; for(i=0;i { j=108;; while(j--); } } //****IO口模拟SPI总线代码********/ uchar SPI_RW(uchar byte)//这一段程序看懂了,觉得写得挺好 { uchar bit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr++) { MOSI=(byte&0x80); byte=(byte<<1); SCK=1; byte|=MISO; SCK=0; } return(byte); } uchar SPI_RW_Reg (uchar reg,uchar value) // 向寄存器REG写一个字节,同时返回状态字节 { uchar status; CSN=0; status=SPI_RW(reg); SPI_RW(value); CSN=1; return(status); } uchar SPI_Read (uchar reg )//读取寄存器值的函数 { uchar reg_val; CSN=0; SPI_RW(reg); reg_val=SPI_RW(0); CSN=1; return(reg_val); } uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)//发射缓冲区访问函数 { uchar status,byte_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW(reg); // Select register to write to and read status byte for(byte_ctr=0; byte_ctr SPI_RW(*pBuf++); CSN = 1; // Set CSN high again return(status); // return nRF24L01 status byte } //******************发送模式代码*************/ /*void TX_Mode(void) { CE=0; SPI_RW_Reg(FLUSH_TX,0x00); SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ackipe0 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40 //不一样零:: 通道选择0 SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //不一样零:没这一句 设置接收数据长度,本次设置为32字 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); CE=1; delay_ms(100); } void Transmit(unsigned char * tx_buf) { CE=0; //StandBy I模式 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 发射//缓冲区访问函数 装载接收端地址 SPI_RW_Reg(FLUSH_TX,0x00); //不一样二:这一句多了 寄存器访问函数 SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送 CE=1; //置高CE,激发数据发送 delay_ms(150); } */ unsigned char nRF24L01_TxPacket(unsigned char * tx_buf) { CE=0; SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // SPI_RW_Reg(WRITE_REG + RF_CH, 0); // SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // CE=1; // deelay_ms(150); //while(IRQ!=0); sta=SPI_Read(READ_REG + STATUS); // read register STATUS's value SPI_RW_Reg(WRITE_REG+STATUS,sta); // clear interrupt flag(TX_DS) if(sta&MAX_RT) { SPI_RW_Reg(FLUSH_TX,0xff); //Deelay(10); return MAX_RT; } if(sta&TX_DS) return TX_DS; return 0xff; } #endif 那位大神帮忙看看,刷卡一两次后就要单片机复位,RC522模块才能继续读取新的卡,这是什么情况啊,起码来一个新卡,重新读吧?该怎么改好呢,跪求大神指点一二 |
|
相关推荐
4个回答
|
|
哎。。。等了一两天了都没个人答。。。伤心中。。。
|
|
|
|
反复验证,我的刷卡程序是正确的,NRF24L01发送小部分程序----还是这一小部分的问题,单个发送接收,这程序没错,但是把这小部分2401的扔进去,就使得刷卡刷一次就死掉不执行了,需要单片机复位
|
|
|
|
共用1个SPI么?
|
|
|
|
查出来了,是串口通信和2401端口共用时冲突了
|
|
|
|
只有小组成员才能发言,加入小组>>
如何使用STM32+nrf24l01架构把有线USB设备无线化?
2440 浏览 7 评论
请问能利用51单片机和nRF24L01模块实现实时语音无线传输吗?
2215 浏览 5 评论
2969 浏览 3 评论
2666 浏览 8 评论
为什么ucosii上移植lwip后系统进入了HardFault_Handler?
2633 浏览 4 评论
请教各位大咖:有没有接收频率32M左右的芯片推荐的?先感谢啦!
417浏览 1评论
679浏览 0评论
749浏览 0评论
464浏览 0评论
274浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-20 17:44 , Processed in 0.876018 second(s), Total 50, Slave 44 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号