我使用的是串口讀卡器,RFID卡是philips的Mifare-M1卡。操作讀卡器,就是操作串口設備。串口設備的基礎只是,請參考 https://www.ibm.com/developerworks/cn/linux/l-serials/ ,此文講得很詳細。
在嵌入式平台下,串口設置需要做得更全一些,以避免一些特殊字符問題。本文描述了一種用select進行非阻塞方式讀取的方法,方便了應用程序進行整合。
1,打開串口
- int open_comm (const char* device) {
- if (device == NULL) return -1;
- int fd = open (device, O_RDWR|O_NOCTTY|O_NDELAY);
- return fd;
- }
2,設置串口
- static int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
- B38400, B19200, B9600, B4800, B2400, B1200, B300, };
- static int name_arr[] = { 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300,
- 38400, 19200, 9600, 4800, 2400, 1200, 300, };
-
- int set_options (int fd, int speed, int databits, int stopbits, int parity) {
- struct termios options;
- int status = 0;
- if ((status = tcgetattr (fd, &options)) != 0) {
- ERROR ("fail: status=%d, %s", status, strerror (errno));
- return -1;
- }
-
- int bSpeed = -1;
- for (int i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {
- if (speed == name_arr[i]) {
- bSpeed = speed_arr[i];
- break;
- }
- }
- if (bSpeed == -1) {
- ERROR ("wrong speed=%d", speed);
- return -1;
- }
- cfsetispeed (&options, bSpeed);
- cfsetospeed (&options, bSpeed);
-
- /*允許接收並且設置為本地模式*/
- options.c_cflag |= (CLOCAL|CREAD);
-
- /*設置數據位數*/
- options.c_cflag &= ~CSIZE;
- switch (databits)
- {
- case 7:
- options.c_cflag |= CS7;
- break;
- case 8:
- options.c_cflag |= CS8;
- break;
- default:
- ERROR ("Unsupported data size");
- return -1;
- }
-
- switch (parity)
- {
- case 'n':
- case 'N':
- options.c_cflag &= ~PARENB; /* Clear parity enable */
- options.c_iflag &= ~INPCK; /* Enable parity checking */
- break;
- case 'o':
- case 'O':
- options.c_cflag |= (PARODD | PARENB); /* 設置為奇效驗*/
- options.c_iflag |= INPCK; /* Disnable parity checking */
- break;
- case 'e':
- case 'E':
- options.c_cflag |= PARENB; /* Enable parity */
- options.c_cflag &= ~PARODD; /* 轉換為偶效驗*/
- options.c_iflag |= INPCK; /* Disnable parity checking */
- break;
- case 'S':
- case 's': /*as no parity*/
- options.c_cflag &= ~PARENB;
- options.c_cflag &= ~CSTOPB;
- break;
- default:
- ERROR ("Unsupported parity");
- return -1;
- }
-
- /* 設置停止位*/
- switch (stopbits)
- {
- case 1:
- options.c_cflag &= ~CSTOPB;
- break;
- case 2:
- options.c_cflag |= CSTOPB;
- break;
- default:
- ERROR ("Unsupported stop bits");
- return -1;
- }
-
- /* Set input parity option */
- //if (parity != 'n')
- // options.c_iflag |= INPCK;
-
- options.c_cc[VINTR] = 0;
- options.c_cc[VQUIT] = 0;
- options.c_cc[VERASE] = 0;
- options.c_cc[VKILL] = 0;
- options.c_cc[VEOF] = 0;
- options.c_cc[VTIME] = 1;
- options.c_cc[VMIN] = 0;
- options.c_cc[VSWTC] = 0;
- options.c_cc[VSTART] = 0;
- options.c_cc[VSTOP] = 0;
- options.c_cc[VSUSP] = 0;
- options.c_cc[VEOL] = 0;
- options.c_cc[VREPRINT] = 0;
- options.c_cc[VDISCARD] = 0;
- options.c_cc[VWERASE] = 0;
- options.c_cc[VLNEXT] = 0;
- options.c_cc[VEOL2] = 0;
- //options.c_cc[VTIME] = 150; // 15 seconds
- //options.c_cc[VMIN] = 0;
-
- tcflush (fd,TCIFLUSH); /* Update the options and do it NOW */
- if ((status = tcsetattr (fd,TCSANOW,&options)) != 0) {
- ERROR ("fail: status=%d, %s", status, strerror (errno));
- return -1;
- }
- return 0;
- }