RC522读卡器 M1卡学习总结(二)

RC522读卡器 M1卡学习总结(二)二、说说RC522读卡器       我从淘宝里买来的读卡器模块如下:M1卡 学习总结(二)”title=”RC522读卡器 M1卡 学习总结(二)”style=”margin:0px;padding:0px;border:0px;list-style:none”>它带有一组接口:SDA  SCK  MOSI  MISO  IRQ(NG)  GND  RST  3

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

二、说说RC522读卡器

       我从淘宝里买来的读卡器模块如下:

                                            —-》防冲突检查(Anticollision Loop)选择一张卡片,返回该卡序列号;

                                           —–》选择卡片(Select Tag),选择被选中的卡的序列号,返回卡的容量代码;

                                           —–》三次互相确认(3 Pass Authentication)通过密码校验之后,三次互相认                                             证                                                   之后可以通讯。

 

M1卡指令:

                 读(Read):读一个块;

                 写(Write):写一个块;

                 加值(Increment):对数值块进行加值;

                 减值(Decrement):对数值块进行减值;

                 存储(Restore):将块中数据保存到数据寄存器中;

                 传输(Transfer):将数据寄存器中内容写入到块中;

                 终止(Halt):将卡置于暂停工作状体。


三、RC522读卡器的使用–硬件部分

       我使用了stm8s103来驱动RC522读卡器,硬件连接如下:

      stm8s103引脚                      RC522接口

      3.3v                    ———-   3.3v

      GND                   ———    GND

      PC4                    ———     SDA(NSS)

      PC5(SPI_SCK)    ———     SCK

      PC6(SPI_MISO) ———     MISO

      PC7(SPI_MOSI) ———     MOSI

      至少接这6针。

 

     使用stm8s芯片的spi接口来和rc522通讯,通过相应的寄存器可控制SPI接口的数据传输率、数据时钟相位等通信参数。

     这里使用spi通讯,1/4分频,空闲低电平,第一个时钟周期开始采样,第一个时钟边缘开始数据采样。

注意:片选信号必须保证在写入数据流期间为低电平,而在无数据流写入时为高电平,不得为了省事而一直将NSS置为低电平。


四、单片机stm8s与读卡器RC522通讯—-软件部分

      单片机与读卡器的接口

      RC522读卡器提供三种接口,分别是UART,I2C,SPI这三种接口。我们这里选择了spi接口。关于stm8s为主机,rc522读卡器为从机。spi使用4个管脚与从设备相连,MISO,MOSI,SCK,NSS.

       这里有一点需要注意:MOSI管脚相互连接,MISO脚相互连接。这样,数据在主和从之间串行地传输(MSB位在前)。通信总是由主设备发起。主设备通过MOSI脚把数据发送给从设备,从设备通过MISO引脚回传数据。这意味全双工通信的数据输出和数据输入是用同一个时钟信号同步的:时钟信号由主设备通过SCK脚提供。

(1)SPI初始化如下:

void init_SPI_Master(void)
       
        SPI_CR1 = 0x04;          //fMaster/2, 配置为主设备,空闲低电平,第一个时钟周期开始采样
        SPI_CR2 = 0x03;           //内部指定主模式,NSS上电平决定该位值
        SPI_CRCPR = 0x07;
        SPI_ICR = 0x00;            //中断禁止
        SPI_CR1 |= 0x40;          //开启SPI

}

(2)UART初始化,这里为了调试方便,我们使用uart接口来观察执行情况。

void init_UART(void)
{

       UART1_CR2=0x00;//使发送禁用TEN=0;
       UART1_CR1=0x00;//设置M字长,8位数据位
       UART1_CR3=0x00;//1位停止位
 
       UART1_BRR2=0X00;      //波特率9600,分频系数=2000000/9600=208
       UART1_BRR1=0X0D;       //208=0X0D;
       UART1_CR2=0X2C;       //b3=1,允许发送  b2=1,允许接收  b5=1,允许产生接收中断
}

 (3)UART发送数据函数

void UARTSend(uchar aa)
{

  UART1_CR2=0x00;
  UART1_DR=aa;                   

  UART1_CR2=0x08;
  while((UART1_SR & 0x40) ==0);
  UART1_CR2=0x2c;//0x2c;//0x08; 2位 rev使能 3位 发送使能 5–rien 
}

(4)UART接收中断处理函数

@far @interrupt void UART1_RX_IRQHandler(void)  //UART1_Receiver(void)
{

     unsigned char i;
     _asm(“sim”);    //关总中断
      a=UART1_DR;      //将接收的字符放到a中
     _asm(“rim”);    //开总中断
    return;
}

(5)SPI接收发送字节

//spi接口在写的时候要先发送,发送不一定要传送内容,只是为了
//给从机提供时钟,因为sck是主机来发出的,所以写函数里面要有发送指令,目的是提供从机写时钟
uchar SPIWriteByte(uchar spiData)
{

   uchar retry=0;
  while((SPI_SR & 0X02)==0)  //等待发送区空
  {

   retry++;
   if(retry>200) return 0;  //防止死机
  }
 
  SPI_DR=spiData;             //发送一个byte
  retry=0;
  while((SPI_SR|0X80)==0X80);  //等待通信结束
 
  while((SPI_SR & 0X01)==0);  //等待接收缓冲区空
  {

     retry++;
    if(retry>200) return 0;
  }
  return SPI_DR;    //返回受到的数
 

}

(6)main.c主程序函数

void main()
{

 uchar i;
 uchar Card_Type1[2];
 uchar Card_ID[4];
 uchar Card_KEY[6] = {0xff,0xff,0xff,0xff,0xff,0xff};  
 uchar Card_Data[16];
 uchar status;
  //fmaster=fcpu=2MHz
 CLK_ECKR=0x00;
 CLK_ICKR=0x01;
 CLK_CMSR=0xe1;
 
 CLK_SWR=0xe1;
 CLK_CKDIVR=0x18;

 init_IO();
 init_UART();
 init_SPI_Master();
 
 _asm(“rim”);    //开总中断,便于产生串口接收中断

 status=PcdReset();
 PcdAntennaOff();
 delay(20);
 PcdAntennaOn();
 M500PcdConfigISOType( ‘A’ );
 a=0x63;
 nblock=4;//kuan 0
 t=0;
 while(1)
 {

  

        //    PcdAntennaOff();
        //测试一下接口是否正确
        status = CheckMCURC522interface();
        if(status != MI_OK)
        {

             UARTSend(0x04);
             continue;
        }
    
         status = PcdRequest(PICC_REQALL, g_ucTempbuf);
           if (status != MI_OK)
          {    
              continue;
           }
         //  UARTSend(a);//0x11);
         //  for(i=0;i<8;i++)
         //  UARTSend(g_ucTempbuf[i]);//0400 e52b 0000000000
       

         delay(20);//

         status = PcdAnticoll(g_ucTempbuf);
         if (status != MI_OK)
         {    continue;    }
         //   UARTSend(0x12);
         delay(20);//delay_ms(2);
         status = PcdSelect(g_ucTempbuf);
         if (status != MI_OK)
         {    continue;    }
        //   UARTSend(0x13);
         delay(20);//

       //   UARTSend(nblock);
       //认证卡
         status = PcdAuthState(PICC_AUTHENT1A, nblock, DefaultKey, g_ucTempbuf);
         if (status != MI_OK)
         {    continue;    }
        //   UARTSend(0x14);
        delay(20);//

       if(a==b) continue;
       else b=a;
       UARTSend(a);  //发送执行的命令代码
     switch(a)
     {

     case 0x91://写电子钱包数据到块nblock
       status = PcdWrite(nblock, data1);
         if(status==MI_OK)
       {

        UARTSend(0x88);
        
       }
       else UARTSend(0x44);
       break;
     case 0x92://写普通数据到块nblock
       status = PcdWrite(nblock, data3);
         if(status==MI_OK)
       {

        UARTSend(0x88);
        
       }
       else UARTSend(0x44);
         break;
     case 0x93://从块n中读取数据
       status = PcdRead(nblock, g_ucTempbuf);//PcdRead(2, g_ucTempbuf);
        if (status == MI_OK)
        {   
        UARTSend(0x88);
        for(i=0;i<16;i++)
         UARTSend(g_ucTempbuf[i]);//把写进去的数
        }
        else  UARTSend(0x44);
        break;
     case 0x94://从块n中读取数据
       status = PcdRead(nblock, g_ucTempbuf);//PcdRead(2, g_ucTempbuf);
        if (status == MI_OK)
        {   
        UARTSend(0x88);
        for(i=0;i<16;i++)
         UARTSend(g_ucTempbuf[i]);//把写进去的数
        }
        else  UARTSend(0x44);
        break;
     case 0x95://操作电子钱包
       status = PcdValue(PICC_DECREMENT,nblock,data2);
       if (status == MI_OK)
        
         UARTSend(0x88);
         for(i=0;i<4;i++)
           UARTSend(data2[i]);//
       }
        else  UARTSend(0x44);
       break;
     case 0x96: //备份电子钱包
       status = PcdBakValue(nblock, nblock+1);
        if (status == MI_OK)
        
         UARTSend(0x88);
        
       }
        else  UARTSend(0x44);
        break;
     default:break;
     
     }
    
       
  //    PcdHalt();
  //    PcdAntennaOff();
 }
}

(7)RC522的库函数和网上都基本一样,就不写了。

以上程序本人已经测试过了。

 

(8)本人在学习rc522的过程中参考了很多文章,在此表示感谢!

M1卡介绍  http://wenku.baidu.com/view/62cccb122e3f5727a4e9625c.html

M1卡激活成功教程密码控制位及控制规则http://www.docin.com/p-624326551.html

Mifare1技术说明(M1卡说明文档) http://www.docin.com/p-379085837.html

基于非接触式ic卡的读卡器的设计与开发http://www.docin.com/p-906980594.html

      13.56M读卡器开发详解二http://blog.sina.com.cn/s/blog_6754612e0101c0pe.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/193779.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • arraylist和linkedlist的区别_arraylist 和linkedlist

    arraylist和linkedlist的区别_arraylist 和linkedlist&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这段时间把疯狂JAVA再看了一遍,发现Stack,ArrayDeque,LinkedList都可以作为栈使用,所以就稍微从性能以及实现的细节对比这三者的区别。类继承树&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由继承树看出,三者都是Collection的间接实现类。&

    2022年9月20日
    2
  • JavaCodeTra 猴子选猴王 约瑟夫循环

    JavaCodeTra 猴子选猴王 约瑟夫循环

    2022年2月2日
    58
  • calico文件_ico文件怎么打开

    calico文件_ico文件怎么打开k8s的网络插件,可以使用下面的,镜像可以自己修改。

    2025年7月2日
    2
  • java如何输入字符串_JAVA中怎样输入字符串「建议收藏」

    java如何输入字符串_JAVA中怎样输入字符串「建议收藏」https://zhidao.baidu.com/question/344967589.htmljava.lang.String.charAt()方法返回指定索引处的char值。http://www.yiibai.com/javalang/string_charat.html(toLowerCase)toUpperCase的意思是将所有的英文字符转换为大写字母,如:Stringcc=“a…

    2022年7月16日
    15
  • js的常见的三种密码加密方式-MD5加密、Base64加密和解密和sha1加密详解总结

    js的常见的三种密码加密方式-MD5加密、Base64加密和解密和sha1加密详解总结写在前面写前端的时候,很多的时候是避免不了注册这一关的,但是一般的注册是没有任何的难度的,无非就是一些简单的获取用户输入的数据,然后进行简单的校验以后调用接口,将数据发送到后端,完成一个简单的注册的流程,那么一般来说,密码是不做加密的。但是也有一些数据库里面存放的是加密后的密码,这样有一个比较安全的地方在于,即使黑客将用户输入的文本密码得到了,也不知道具体是什么,因为密码是经过加密的。今天就简单的…

    2022年7月11日
    33
  • android高德地图获取海拔_高德导航地图能显示海拔高度吗

    android高德地图获取海拔_高德导航地图能显示海拔高度吗现在人们生活水平普遍提高,私家车成为老百姓的常态,选择周末或者节假日来一场自驾游还是非常给力的,很多年轻人都喜欢挑战自己,去西部自驾游,这个就需要知道海拔信息了,那么高德地图能导航出海拔数据吗?高德地图测海拔的具体方法如下:1、第一步打开高德地图的网页,找到并点击下方那行小字。2、点中间的(开放平台)四个字。3、打开高德开发平台界面然后依次点击(开发支持)-(地图工具)-(坐标拾取器)。4、打开界…

    2022年5月21日
    434

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号