내장형 하드웨어/RFID

RFID - 기판 수령, 분석

동화다아아 2011. 11. 1. 11:02


→ 5개의 선이 stream 안테나에서 본체(회로)에 연결
→ CPU내에 여러 회로가 내장되어있다. 여러 칩들이 큰 플라스틱에 쌓여있다.
→ 스피커는 PWM으로 연주 가능
→ 케페시터 - SMD(Surface Mount Device) type
  ※ SMD
  → 기본적으로 고주파에 강하며, 잡음을 적게 탄다.
  → 반대로 SMD type이 아닌 저항등은 잡음을 흡수한다.
→ 잡음을 타면 안되기 때문에 SMD type을 사용한다.(가격이 10배 높다.)
→ LED 두개, 스피커 한개의 제어가 가능하다.(시리얼 통신으로, 펌웨어가 제공하는 한도내에서)

→ 우리가 사용하는 카드를 확인하면 3A Logics(RFID 칩 만드는 회사)
  ※ 시리얼 통신 선에서 3개는 데이터 송수신(Tx, Rx, GND), 나머지는 전원 공급이 가능하도록 되어있다. 우리가 사용하는 RFID 회로에는 전원공급을 할 수 있는 장치가 없기 때문에 이를 이용해서 전원을 공급하여야 한다.


→ 위의 사진은 스트리밍 안테나이다. 간단하며 기능이 떨어지나 가격이 저렴하다.
→ 아래의 카드는 RFID가 정보를 읽을 카드이다.
→ 전체 사진

 





- 이제 이 기기를 linux의 시리얼 통신 소스를 수정하여 실행시켜 본다.
#include<stdio.h>
#include<fcntl.h>

#include<sys/types.h>
#include<sys/stat.h>
#include<termios.h>
#include<sys/signal.h>
#include<unistd.h>

#define CRC_POLYNOM  0X8408
#define CRC_PRESET  0xFFFF
//#define SPEED B19200
#define SPEED B38400
#define COMPORT1 "/dev/ttyS0" //

void Input_Incomming(int);
void Output_Incomming(int);
void my_signal(int arg); // 시그널 처리 함수

char cBuff[255]; // 수신용 버퍼
volatile int iBreak = 0;
int iRet;
int iCom1 = 0;
struct termios stOldSt1; // 기존 Serial Port1 상태 정보
unsigned char cArr[13]={0x0d,0x00,0x71,0x00
            ,0x3f,0x00,0x00,0x00
            ,0xa0,0x00,0x00,};
unsigned int cnt = 11;
unsigned short CRC16(void * DATA, unsigned int cnt);
int main()
{
  int iMaxFD = 0;
  unsigned short crc;
  unsigned int iCnt;

  struct termios stNewSt1; // 새로운 Serial Port1 상태 정보
  struct sigaction act; // sigaction 구조체 변수 선언
  fd_set stRFd; // file descriptor set
  crc = CRC16(cArr, sizeof(cArr)-2);
  printf("%02X\n", crc);
  *((unsigned short*)(cArr+11)) = crc;


  // 읽기,쓰기 모드로 모뎀장치를 연다.(O_RDWR)
  // 데이터 전송시에 CTRL+C 문자가 오면 프로그램이 종료되지 않도록
  // 하기 위해 controlling tty가 안되도록 한다.(O_NOCTTY)
  iCom1 = open(COMPORT1, O_RDWR|O_NOCTTY); // 시리얼 포트 오픈
  if(0 > iCom1) // 시리얼 포트1 오픈 에러
  {
    perror(COMPORT1);
    exit(-1);
  }
    
  bzero(&act, sizeof(act));
  act.sa_handler = my_signal; // 시그널 처리 함수
  act.sa_flags = 0;
  sigaction(SIGINT, &act, 0); // 
  // save current serial port setting
  tcgetattr(iCom1, &stOldSt1);
  // clear struct for new port setting
  bzero(&stNewSt1, sizeof(stNewSt1));
  // CS8-8N1(8bit, no parity, 1 stop bit), CLOCAL-local connection,
  // CREAD - 문자수신을 가능하게 한다.
  // PARENB - 짝수 페리티
  stNewSt1.c_cflag = SPEED|CS8|CLOCAL|CREAD|PARENB;
  // IGㄲNL - Parity 에러가 있는 문자 바이트를 무시.
  stNewSt1.c_iflag = IGNPAR;
  stNewSt1.c_cc[VMIN] = 1// read시 리턴되기 위한 최소 문자 개수 지정
  // 시리얼 포트 라인을 초기화 하고 포트 세팅을 마친다.  
  tcflush(iCom1, TCIFLUSH); // 시리얼 포트 수신 큐 초기화
  tcsetattr(iCom1, TCSANOW, &stNewSt1); // 시리얼 포트에 새 속성 적용

  iMaxFD = iCom1 + 1;
  
  while(1)
  {
    // Set Descriptor
    FD_ZERO(&stRFd);
    FD_SET(iCom1, &stRFd);
    FD_SET(0&stRFd);
    // block until input
    select(iMaxFD, &stRFd, NULL, NULL, NULL);

    if(iBreak == 1)
    {
      break;
    }
    // 입력을 받는다.
    if(FD_ISSET(iCom1, &stRFd))
    {
      Input_Incomming(iCom1);
    }
    // 키보드 입력을 보낸다.
    if(FD_ISSET(0&stRFd))
    {
    //  memset(cBuff, 0, 255);
    //  iRet = read(0, cBuff, sizeof(cBuff));
    //  cBuff[iRet] = 0;
      write(iCom1, cArr, *cArr);
    }
  }
  tcsetattr(iCom1, TCSANOW, &stOldSt1); // 시리얼 포트의 원래 속성 복귀
  close(iCom1); // 시리얼 포트 닫음
  printf("End program\n");      // End main()
  return 0;
}
void Input_Incomming(int iCom1)
{
  int iCnt=0;
  iRet = read(iCom1, cBuff, 255); // 시리얼 포트로 부터 데이터 수신
  while(iRet>iCnt)
  {
    printf(" %02X ", *(cBuff+iCnt)); // hex 값을 표시하겠다. 
    ++iCnt;
    if(0 == (iCnt%16)) // 16개마다 개행하겠다.
    {
      putchar('\n');    
    }
  }
  putchar('\n');    
  putchar('\n');    
  return ;
}
void Output_Incomming(int iCom1)
{
  return ;
}
void my_signal(int arg)
{
  iBreak = 1;
  printf("\nCtrl-C pressed\n");
  tcsetattr(iCom1,TCSANOW,&stOldSt1);
  close(iCom1);
  return ;
}
unsigned short CRC16(void *P, unsigned int cnt)
{
  unsigned char *DATA = P;
  unsigned int i;
  unsigned int j;
  unsigned short crc = CRC_PRESET;

  // cnt = number of protocol bytes withdout CRC
  for(i=0;i<cnt;++i)
  {
    crc = crc^DATA[i];
    for(j=0;j<8;++j)
    {
      if(crc&0x0001)
      {
        crc = (crc>>1)^CRC_POLYNOM;
      }
      else
      {
        crc = (crc>>1);
      }
    }
  }
  return crc;
}

- 동작 동영상