Linux下RFID卡(门禁卡,Mifare卡)的编程


我使用的是串口读卡器,RFID卡是philips的Mifare-M1卡。操作读卡器,就是操作串口设备。串口设备的基础只是,请参考 https://www.ibm.com/developerworks/cn/linux/l-serials/ ,此文讲得很详细。

在嵌入式平台下,串口设置需要做得更全一些,以避免一些特殊字符问题。本文描述了一种用select进行非阻塞方式读取的方法,方便了应用程序进行整合。

1,打开串口

  1. int open_comm (const char* device) {  
  2.     if (device == NULL) return -1;  
  3.     int fd = open (device, O_RDWR|O_NOCTTY|O_NDELAY);  
  4.     return fd;  
  5. }  
2,设置串口
  1. static int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,  
  2.                           B38400, B19200, B9600, B4800, B2400, B1200, B300, };  
  3. static int name_arr[] = { 115200, 38400,  19200,  9600,  4800,  2400,  1200,  300,  
  4.                           38400,  19200,  9600, 4800, 2400, 1200,  300, };  
  5.   
  6. int set_options (int fd, int speed, int databits, int stopbits, int parity) {  
  7.     struct termios options;  
  8.     int status = 0;  
  9.     if ((status = tcgetattr (fd, &options)) != 0) {  
  10.         ERROR ("fail: status=%d, %s", status, strerror (errno));  
  11.         return -1;  
  12.     }  
  13.   
  14.     int bSpeed = -1;  
  15.     for (int i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {  
  16.         if (speed == name_arr[i]) {  
  17.             bSpeed = speed_arr[i];  
  18.             break;  
  19.         }  
  20.     }  
  21.     if (bSpeed == -1) {  
  22.         ERROR ("wrong speed=%d", speed);  
  23.         return -1;  
  24.     }  
  25.     cfsetispeed (&options, bSpeed);  
  26.     cfsetospeed (&options, bSpeed);  
  27.   
  28.     /*允许接收并且设置为本地模式*/  
  29.     options.c_cflag |= (CLOCAL|CREAD);  
  30.   
  31.     /*设置数据位数*/  
  32.     options.c_cflag &= ~CSIZE;  
  33.     switch (databits)  
  34.     {  
  35.     case 7:  
  36.         options.c_cflag |= CS7;  
  37.         break;  
  38.     case 8:  
  39.         options.c_cflag |= CS8;  
  40.         break;  
  41.     default:  
  42.         ERROR ("Unsupported data size");  
  43.         return -1;  
  44.     }  
  45.   
  46.     switch (parity)  
  47.     {  
  48.     case 'n':  
  49.     case 'N':  
  50.         options.c_cflag &= ~PARENB;   /* Clear parity enable */  
  51.         options.c_iflag &= ~INPCK;     /* Enable parity checking */  
  52.         break;  
  53.     case 'o':  
  54.     case 'O':  
  55.         options.c_cflag |= (PARODD | PARENB);  /* 设置为奇效验*/  
  56.         options.c_iflag |= INPCK;             /* Disnable parity checking */  
  57.         break;  
  58.     case 'e':  
  59.     case 'E':  
  60.         options.c_cflag |= PARENB;     /* Enable parity */  
  61.         options.c_cflag &= ~PARODD;   /* 转换为偶效验*/  
  62.         options.c_iflag |= INPCK;       /* Disnable parity checking */  
  63.         break;  
  64.     case 'S':  
  65.     case 's':  /*as no parity*/  
  66.         options.c_cflag &= ~PARENB;  
  67.         options.c_cflag &= ~CSTOPB;  
  68.         break;  
  69.     default:  
  70.         ERROR ("Unsupported parity");  
  71.         return -1;  
  72.     }  
  73.   
  74.     /* 设置停止位*/  
  75.     switch (stopbits)  
  76.     {  
  77.     case 1:  
  78.         options.c_cflag &= ~CSTOPB;  
  79.         break;  
  80.     case 2:  
  81.         options.c_cflag |= CSTOPB;  
  82.         break;  
  83.     default:  
  84.         ERROR ("Unsupported stop bits");  
  85.         return -1;  
  86.     }  
  87.   
  88.     /* Set input parity option */  
  89.     //if (parity != 'n')   
  90.     //  options.c_iflag |= INPCK;   
  91.   
  92.     options.c_cc[VINTR] = 0;  
  93.     options.c_cc[VQUIT] = 0;  
  94.     options.c_cc[VERASE] = 0;  
  95.     options.c_cc[VKILL] = 0;  
  96.     options.c_cc[VEOF] = 0;  
  97.     options.c_cc[VTIME] = 1;  
  98.     options.c_cc[VMIN] = 0;  
  99.     options.c_cc[VSWTC] = 0;  
  100.     options.c_cc[VSTART] = 0;  
  101.     options.c_cc[VSTOP] = 0;  
  102.     options.c_cc[VSUSP] = 0;  
  103.     options.c_cc[VEOL] = 0;  
  104.     options.c_cc[VREPRINT] = 0;  
  105.     options.c_cc[VDISCARD] = 0;  
  106.     options.c_cc[VWERASE] = 0;  
  107.     options.c_cc[VLNEXT] = 0;  
  108.     options.c_cc[VEOL2] = 0;  
  109.     //options.c_cc[VTIME] = 150; // 15 seconds   
  110.     //options.c_cc[VMIN] = 0;   
  111.   
  112.     tcflush (fd,TCIFLUSH); /* Update the options and do it NOW */  
  113.     if ((status = tcsetattr (fd,TCSANOW,&options)) != 0) {  
  114.         ERROR ("fail: status=%d, %s", status, strerror (errno));  
  115.         return -1;  
  116.     }  
  117.     return 0;  
  118. }  
  • 1
  • 2
  • 下一页

相关内容