微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > IC卡读卡

IC卡读卡

时间:10-02 整理:3721RD 点击:

上一篇我们把SPI的驱动搞定了,那么下一步,就是要使用SPI协议对RC522进行读写了。

RC522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是NXP 公司针对“三表”应用推出的一款低电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携 式手持设备研发的较好选择

RC522运行以下三种通讯方式,UART、SPI、I2C。其对应于引脚列表如下图:



SPI的写数据



SPI的读数据



本功能主要是移植STM32方案的IC卡读取程序,打开SPI设备,SPI的配置。


  1.         static uint8_t mode = 0;
  2.         static uint8_t bits = 8;
  3.         static uint32_t speed = 50000;
  4.         static uint16_t delay;
  5.        
  6.         int ret = 0;
  7.         int fd;       
  8.        
  9.         fd = open("/dev/spidev1.0", O_RDWR);

  10.         ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
  11.         ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
  12.         ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
  13.         ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
  14.         ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
  15.         ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
  16.        

复制代码


接收数据程序


  1. uint8_t rx[32];        
  2. int receive_data(unsigned char *rBuf, unsigned int size,int fd) {

  3.     struct spi_ioc_transfer tr = {
  4.             .rx_buf = (unsigned long) rx,
  5.                         .len = size,
  6.                         .delay_usecs = delay,
  7.             .speed_hz = speed,
  8.                         .bits_per_word = bits,
  9.                         };

  10.         return ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
  11. }

复制代码



发送数据程序


  1. uint8_t tx[32];
  2. int send_data(unsigned char *rBuf, unsigned int size,int fd) {

  3.     struct spi_ioc_transfer tr = {           
  4.             .tx_buf = (unsigned long) tx,
  5.                         .len = size,
  6.                         .delay_usecs = delay,
  7.             .speed_hz = speed,
  8.                         .bits_per_word = bits,
  9.                         };

  10.         return ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
  11. }

复制代码


对卡的操作分成四步:寻卡→防冲突→选卡→读/写卡;

寻卡:

  1. char PcdRequest(unsigned char req_code, unsigned char *pTagType,int fd)
  2. {
  3.         char status;
  4.         unsigned int unLen;
  5.         unsigned char ucComMF522Buf[MAXRLEN];
  6.         
  7.         ClearBitMask(Status2Reg, 0x08,int fd);
  8.         WriteRawRC(BitFramingReg, 0x07,int fd);
  9.         SetBitMask(TxControlReg, 0x03,int fd);

  10.         ucComMF522Buf[0] = req_code;

  11.         status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 1, ucComMF522Buf, &unLen,int fd);

  12.         if ((status == MI_OK) && (unLen == 0x10)) {
  13.                 *pTagType = ucComMF522Buf[0];
  14.                 *(pTagType + 1) = ucComMF522Buf[1];
  15.         } else {
  16.                 status = MI_ERR;
  17.         }

  18.         return status;
  19. }

复制代码


防冲突:


  1. char PcdAnticoll(unsigned char *pSnr,int fd)
  2. {
  3.         char status;
  4.         unsigned char i, snr_check = 0;
  5.         unsigned int unLen;
  6.         unsigned char ucComMF522Buf[MAXRLEN];

  7.         ClearBitMask(Status2Reg, 0x08,int fd);
  8.         WriteRawRC(BitFramingReg, 0x00,int fd);
  9.         ClearBitMask(CollReg, 0x80,int fd);

  10.         ucComMF522Buf[0] = PICC_ANTICOLL1;
  11.         ucComMF522Buf[1] = 0x20;

  12.         status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 2, ucComMF522Buf, &unLen,int fd);

  13.         if (status == MI_OK) {
  14.                 for (i = 0; i < 4; i++) {
  15.                         *(pSnr + i) = ucComMF522Buf[i];
  16.                         snr_check ^= ucComMF522Buf[i];
  17.                 }
  18.                 if (snr_check != ucComMF522Buf[i]) {
  19.                         status = MI_ERR;
  20.                 }
  21.         }

  22.         SetBitMask(CollReg, 0x80,int fd);
  23.         return status;
  24. }

复制代码


其他函数,也是类似的,基本与STM32上的函数用法是一样的,只是添加文件描述符。使每个函数都通过文件描述符所打开的设备。不再赘述。

IC卡模块与转接板的连接:



程序在开发板上,程序将在IC卡上写入两个数据,再读取出来,判断两次操作的值是不是一样以判断IC卡驱动程序的正确运行,其运行结果:



可以看到已经可以正确对IC卡进行读写了,但是这样的方式只是对数据的明文传输,在正常的应用过程中,还要对数据进行必要的加密,以及对IC卡中的存储扇区进行功能上的划分,以确保安全。其实际市场应用还要使用到国网的加密模块芯片,由于手头上也没有,就无法测试了。




Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top