单片机
返回首页

51单片机与RC500射频

2015-10-16 来源:eefocus

#include

#include
#include
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define GetRegPage(addr)    (0x80 | (addr>>3))
idata struct TranSciveBuffer{uchar MfCommand;
                             uchar MfLength;
                             uchar MfData[19];
                            };

void delay(uchar t)
{
 uchar i,j;
 for(i=0;i   for(j=0;j<110;j++);
}
void WriteRawIO(unsigned char Address,unsigned char value)
{
 XBYTE[Address]=value;
}
unsigned char ReadRawIO(unsigned char Address)
{
 return XBYTE[Address];
}
void WriteRC(unsigned char Address, unsigned char value)
{
    WriteRawIO(0x00,GetRegPage(Address)); 
    WriteRawIO(Address,value);             
}
unsigned char ReadRC(unsigned char Address)
{
   WriteRawIO(0x00,GetRegPage(Address));
   return ReadRawIO(Address);                 
   }
void ClearBitMask(uchar reg,uchar mask)
{
   char tmp=0x0;
   tmp = ReadRC(reg);
   WriteRC(reg,tmp & ~mask);
}
void SetBitMask(uchar reg,uchar mask)
{
   char tmp=0x0;
   tmp=ReadRC(reg);
   WriteRC(reg,tmp|mask);
}
void FlushFIFO(void)

    SetBitMask(RegControl,0x01);
}
void PcdAntennaOff()
{
    ClearBitMask(RegTxControl,0x03);
}
 void PcdAntennaOn()
{
    SetBitMask(RegTxControl,0x03);
}

void PcdSetTmo(unsigned char tmoLength)
{
    switch(tmoLength)
    { 
        case 1:                      
            WriteRC(RegTimerClock,0x07); 
            WriteRC(RegTimerReload,0x6a);
            break;
        case 2:                      
            WriteRC(RegTimerClock,0x07); 
            WriteRC(RegTimerReload,0xa0);
            break;
        case 3: 
            WriteRC(RegTimerClock,0x09);
            WriteRC(RegTimerReload,0xa0);
            break;
        case 4:
            WriteRC(RegTimerClock,0x09);
            WriteRC(RegTimerReload,0xff);
            break;
        case 5: 
            WriteRC(RegTimerClock,0x0b);
            WriteRC(RegTimerReload,0xff);
            break;
        case 6:                      
            WriteRC(RegTimerClock,0x0d);
            WriteRC(RegTimerReload,0xff);
            break;
        case 7:                     
            WriteRC(RegTimerClock,0x0f);
            WriteRC(RegTimerReload,0xff);
            break;
        default:                      
            WriteRC(RegTimerClock,0x07);
            WriteRC(RegTimerReload,tmoLength);
            break;
    }    
}

char PcdComTransceive(struct TranSciveBuffer *pi) 
{
   bit recebyte=0;
   char status;
   uchar irqEn=0x00;
   uchar waitFor=0x00;
   uchar lastBits;
   uchar n;
   uint i;
   FlushFIFO();
   switch(pi->MfCommand)
   {
      case PCD_IDLE:
         irqEn = 0x00;
         waitFor = 0x00;
         break;
      case PCD_WRITEE2:
         irqEn = 0x11;
         waitFor = 0x10;
         break;
      case PCD_READE2:
         irqEn = 0x07;
         waitFor = 0x04;
         recebyte=1;
         break;
      case PCD_LOADCONFIG:
      case PCD_LOADKEYE2:
      case PCD_AUTHENT1:
         irqEn = 0x05;
         waitFor = 0x04;
         break;
      case PCD_CALCCRC:
         irqEn = 0x11;
         waitFor = 0x10;
         break;
      case PCD_AUTHENT2:
         irqEn = 0x04;
         waitFor = 0x04;
         break;
      case PCD_RECEIVE:
         irqEn = 0x06;
         waitFor = 0x04;
         recebyte=1;
         break;
      case PCD_LOADKEY:
         irqEn = 0x05;
         waitFor = 0x04;
         break;
      case PCD_TRANSMIT:
         irqEn = 0x05;
         waitFor = 0x04;
         break;
      case PCD_TRANSCEIVE:
         irqEn = 0x3D;
         waitFor = 0x04;
         recebyte=1;
         break;
      default:
         pi->MfCommand=MI_UNKNOWN_COMMAND;
         break;
   }
   if(pi->MfCommand!=MI_UNKNOWN_COMMAND)
   {
     WriteRC(RegPage,0x00);
  WriteRC(RegInterruptEn,0x7F);//使能所有的中断
     WriteRC(RegInterruptRq,0x7F);//
     WriteRC(RegCommand,PCD_IDLE);//闲置状态
      SetBitMask(RegControl,0x01);//清除FIFO
     WriteRC(RegInterruptEn,irqEn|0x80); //允许对应的专断
     for(i=0;iMfLength;i++)
       {
         WriteRC(RegFIFOData,pi->MfData[i]);//写数据至FIFO
       }
        WriteRC(RegCommand,pi->MfCommand);//执行命令
     i=0x2000;
        do
        {
       n=ReadRC(RegInterruptRq);
    i--;
        }
        while((i!=0)&&!(n&irqEn&0x20)&&!(n&waitFor));//等待数据发送完 n&waitFor表示命令自动结束
        status=MI_COM_ERR;
        if((i!=0)&&!(n&irqEn&0x20))//FIFO数据超限或i=0
        {
         if(!(ReadRC(RegErrorFlag)&0x17))//没出错
          {
            status=MI_OK;
   if(recebyte)//表示有返回数据
            {
               n=ReadRC(RegFIFOLength);//读出返回的数据长度
    lastBits=ReadRC(RegSecondaryStatus)&0x07;
                if(lastBits)
                {  
                   pi->MfLength=(n-1)*8+lastBits;
                }
                else
                {  
                   pi->MfLength=n*8;
                }
                if(n==0)
                {
                   n=1;
                }
                for(i=0;i                 {
                 pi->MfData[i]=ReadRC(RegFIFOData);
                }
            }
         }
      }
      else if(n&irqEn&0x20)//FIFO数据超限
      {
          status=MI_NOTAGERR;
      }
      else
      {
          status=MI_COM_ERR;
      }
      WriteRC(RegInterruptEn,0x7F);
   delay(10);
      WriteRC(RegInterruptRq,0x7F);
   }
   return status;
}

char PcdRequest(uchar req_code)
{
    char status;
 idata struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
    pi=&MfComData;
    PcdSetTmo(106);
    PcdAntennaOn();
    WriteRC(RegChannelRedundancy,0x03);
    ClearBitMask(RegControl,0x08);//Crypto1on=0
    WriteRC(RegBitFraming,0x07);
    MfComData.MfCommand=PCD_TRANSCEIVE;
    MfComData.MfLength=1;
 MfComData.MfData[0]=req_code;
    status=PcdComTransceive(pi);
  if(!status)
    {   
  if(MfComData.MfLength!=0x10)
        {
         status=MI_BITCOUNTERR;
        }
    }
    return status;
}

uchar PiccCascAnticoll(uchar *snr)  //这个指针变量没有用,但少了就会报错

    uchar i;
    uchar snr_check=0;
    char status=MI_OK;
    idata struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
 pi=&MfComData; 
 PcdAntennaOn();
 PcdSetTmo(106);//设置定时器
    WriteRC(RegDecoderControl,0x28);//设置碰撞后接收的所有位都用0表示
    ClearBitMask(RegControl,0x08);//Crypto1=0
    WriteRC(RegChannelRedundancy,0x03);//使能奇校验
 MfComData.MfCommand=PCD_TRANSCEIVE;//发送接收命令
    MfComData.MfLength=2;//发送两个字节
    MfComData.MfData[0]=PICC_ANTICOLL1;//PICC_ANTICOLL1=93H,PiCC反碰撞指令
    MfComData.MfData[1]=0x20;//反碰撞还需要在发送一个20H,即想picc发送两个字节
    status=PcdComTransceive(pi);//PcdComTransceive函数将Mfdate中的数据发送给Picc
    if(!status)//表示执行命令没出错
    {
     
   for(i=0;i<4;i++)//执行命令后返回的前4个字节
         {
          snr_check^=MfComData.MfData[i];//接收到的前四个字节按位异或存入snr_check中
         }
         if(snr_check!=MfComData.MfData[i])//判断所接收序列号是否正确
         {
          status=MI_SERNRERR;//接收到的5个字节出错
   }
   else
   {
    for(i=0;i<5;i++)
   {
    *(snr+i)=MfComData.MfData[i];
    }
   }
  
 }
    ClearBitMask(RegDecoderControl,0x20);
 return status;
}

char PcdSelect(uchar *snr,uchar *sar)
{
    uchar i;
    char status;
    uchar snr_check=0;
    idata struct TranSciveBuffer{uchar MfCommand;
                                 uchar MfLength;
                                 uchar MfData[7];
                                }MfComData;
    struct TranSciveBuffer *pi;

    pi=&MfComData;
    PcdSetTmo(106);
    WriteRC(RegChannelRedundancy,0x0F);
    ClearBitMask(RegControl,0x08);

    MfComData.MfCommand=PCD_TRANSCEIVE;
    MfComData.MfLength=7;
    MfComData.MfData[0]=PICC_ANTICOLL1;
    MfComData.MfData[1]=0x70;
    for(i=0;i<4;i++)
    {
     snr_check^=*(snr+i);
     MfComData.MfData[i+2]=*(snr+i);
    }
    MfComData.MfData[6]=snr_check;//select要传7个字节
    status=PcdComTransceive(pi);
    if(status==MI_OK)
    {    if(MfComData.MfLength!=0x8)
        {
         status = MI_BITCOUNTERR;
        }
  *sar=MfComData.MfData[0];
   }
   return status;
}


void init()

 delay(500);
 RC500CS=1;//这个位定义在rc500文件里
 RC500RST=1;
 delay(100);
 RC500RST=0;
 TMOD=0x20;//串口通讯的设置,采用9600波特率
 TH1=0xfd;
 TL1=0xfd;
 TR1=1;
 SCON=0x52;   
 PCON&=0x7f;
 TI=0;
 delay(10);//这个延时很重要,否则会写不进数据到RC500
}
void main()

    uchar i,a[5],b[5],status,*snr,c;//传递数组的首地址可以,传递指针必须初始化,且每个指针都要知道指向的地址,所以传递数组比较好
 snr=&c;
 init();
 PcdRequest(PICC_REQALL);
 PiccCascAnticoll(a);
 for(i=0;i<5;i++)    
 
  b[i]=a[i];
  SBUF=b[i];
  while(!TI);
  TI=0;
 }
 status=PcdSelect(b,snr);
 SBUF=status;
 while(!TI);
 TI=0;
 SBUF=*snr;
 while(!TI);
 TI=0;
 while(1); 
}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 光控电路设计与分析

  • 永不缺相启动运行的电动机控制电路

  • CCFL的工作原理及电子驱动电路解析

  • 比较常见的功率整流器和滤波电路

  • 基于M66T旋律发​​生器的电路图解析

  • 基于CA3193的热电偶放大器电路

    相关电子头条文章