Microprocessor/Module RFID(UID/Write Multiple Blocks/Read Multiple Blocks)[20121016]
  • 728x90
    반응형

    RFID(UID/Write Multiple Blocks/Read Multiple Blocks)




    NFC



    패시브 태그(수동적 태그) : 리더기가 전기를 보내지 않으면 죽어있는 일반카드


    액티브 태그 : 밧데리가 들어 있고 전류가 흐르는 태그



    NFC(근거리 무선 통신)란?

    • NFC는 일반적으로 13.56M이다.
    • NFC는 리더기 간의 통신이 가능하다.



    UID



    같은 모양의 카드일지라도 고유 카드넘버가 존재한다.

    두가지 카드를 이용하여 카드넘버를 출력하는 프로그램을 제작해 보자.

    UID는 스펙에서 다음과 같이 설명되어 있다.




    UID는 8 ~ 15번 bit로 8개의 bit가 존재한다.


    UID

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    #include <windows.h>
    #include <stdio.h>
     
    #define    Philips_I_Code_1                 0x00 
    #define    Texas_Instruments_Tag_it_HF      0x01
    #define    ISO15693_Tags                    0x03
    #define    Philips_I_Code_EPC               0x06
    #define    Philips_I_Code_UID               0x07
     
    unsigned short Emb_Crc(void *);
     
     
    int main()
    {
      unsigned char msg[128= { 0x07,
                                 0x00,
                                 0xB0,
                                 0x01,
                                 0x00,};
       HANDLE hComm;
       DWORD DW_write;
       DWORD DW_read;
       DCB sPS;      // 씨리얼 포트 상태 저장
       COMMTIMEOUTS cTime;
       unsigned int icnt;
      
     
       // CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다.
       hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        
       if(INVALID_HANDLE_VALUE == hComm)
       {
        printf("Com port open Error !\n");
        return 0;
       }
     
        
        // 버퍼 설정
       if== SetupComm(hComm, 40964096))
       {
        printf("Buffer setting Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
      
       if== PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
       {
        printf("Buffer initialization Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
       sPS.DCBlength = sizeof(sPS);
     
       if== GetCommState(hComm, &sPS))
       {
        printf("Port status read Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
       sPS.BaudRate = CBR_38400;    // 비트,초
       sPS.ByteSize = 8;        // 데이터 비트 전송
       sPS.Parity   = EVENPARITY;   // 짝수
       sPS.StopBits = ONESTOPBIT;   // 정지 비트
        
     
        // 위 세팅값을 핸들에 넣어준다.
       if== SetCommState(hComm, &sPS))
       {
        printf("Port status write Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
     
      *((unsigned short *)(msg + msg[0- 2)) = Emb_Crc(msg);
     
      
      WriteFile(hComm, msg, msg[0], &DW_write, 0);
      ReadFile(hComm, msg, 1&DW_read, 0);
      ReadFile(hComm, msg + 1, msg[0- 1&DW_read, 0);
     
      printf("tag data : ");
      switch(msg[0])
      {
        case 17 :
          printf("[standard]\n");
          break;
     
        case 16 :
          printf("[I-Code EPC]\n");
          break;
     
        case 20 :
          printf("[ I-Code EPC]\n");
          break;
     
        case 27 :
          printf("[I-Code UID]\n");
          break;
     
        default :
          printf("[No such card ! ]\n");
          CloseHandle(hComm);
          break;
     
      }
      
      printf("RF  TYPE : [%s]\n", (msg[5& 0xC0) ? "UHF Transponder" : 
           "13.56 MHz Transponder");
      
      
      printf("VENDOR : ");
      switch(msg[5]&0x0F)
      {
        case Philips_I_Code_1 :
          printf("[Philips I-Code 1]\n");
          break;
     
        case Texas_Instruments_Tag_it_HF :
          printf("[Texas Instruments Tag-it HF]\n");
          break;
     
        case ISO15693_Tags :
          printf("[ISO15693 Tags]\n");
          break;
     
        case Philips_I_Code_EPC :
          printf("[Philips I-Code EPC]\n");
          break;
        
        case Philips_I_Code_UID :
          printf("[Philips I-Code UID]\n");
          break;
     
        default :
          printf("[No such card ! ]\n");
          CloseHandle(hComm);
          break;
      }
      
      printf("%02x\n",msg[5]);
     
      //< UID >============================================
      printf("UID : ");
      for(icnt = ; icnt < ; icnt++)
      {
        printf("%02X ", msg[7+icnt]);
      }
      putchar('\n');  
      
     
      printf("Com port open Success !\n");
      CloseHandle(hComm);      // 터미널은 닫아주어야한다.
     
      return 0;
    }
     
     
    unsigned short Emb_Crc(void *arg)
    {
        unsigned short i;
        unsigned short j;
        unsigned short cnt;
        unsigned short crc=0xFFFF;
        unsigned short temp;
        unsigned char *buf = arg;
     
        cnt = (*buf) - 2;
     
        for(i=; i < cnt ; ++i)
        {
          crc^= *(buf + i);
          for(j=; j < ++j) 
          {
            if(!= (crc&0x0001))
            {
              crc=(crc>>1)^0x8408;
            }
            else
            {
              crc=(crc>>1);
            }
          }
          
        }
     
        return crc;
    }
    cs


    위 코드에서 UID를 출력하는 코드이다.


    1
    2
    3
    4
    5
    6
    7
    8
    //< UID >============================================
      printf("UID : ");
      for(icnt = ; icnt < ; icnt++)
      {
        printf("%02X ", msg[7+icnt]);
      }
      putchar('\n');  
     
    cs


    카드가 없을때의 UID 값


    1번 카드의 UID 값


    2번 카드의 UID 값



    [0x24] Write Multiple Blocks




    DB-SIZE는 다음과 같이 스펙에서 4byte로 고정되어 있음을 알 수 있다.



    [0x24] Write Multiple Blocks

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    #include <windows.h>
    #include <stdio.h>
     
     
     
    unsigned short Emb_Crc(void *);
     
     
    int main()
    {
      unsigned char msg[128= { 0x16,
                     0x00,
                     0xB0,
                     0x24,
                     0x01,  // MODE (addressed mode)
                     0xE0,  // UID (6)
                     0x04,
                     0x01,
                     0x00,
                     0x2E,
                     0xB3,
                     0x88,
                     0x51,   
                     0x0A,  // DB-ADR (14)
                     0x01,  // DB-N
                     0x04,  // DB-SIZE
                     0x12,  // DB
                     0x34,
                     0x56,
                     0x78,
                    };
     
       HANDLE hComm;
       DWORD DW_write;
       DWORD DW_read;
       DCB sPS;      
       COMMTIMEOUTS cTime;
       unsigned int icnt;
      
     
       // CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다.
       hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        
       if(INVALID_HANDLE_VALUE == hComm)
       {
        printf("Com port open Error !\n");
        return 0;
       }
     
        
        // 버퍼 설정
       if== SetupComm(hComm, 40964096))
       {
        printf("Buffer setting Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
      
       if== PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
       {
        printf("Buffer initialization Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
       sPS.DCBlength = sizeof(sPS);
     
       if== GetCommState(hComm, &sPS))
       {
        printf("Port status read Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
       sPS.BaudRate = CBR_38400;    // 비트,초
       sPS.ByteSize = 8;        // 데이터 비트 전송
       sPS.Parity   = EVENPARITY;   // 짝수
       sPS.StopBits = ONESTOPBIT;   // 정지 비트
        
     
        // 위 세팅값을 핸들에 넣어준다.
       if== SetCommState(hComm, &sPS))
       {
        printf("Port status write Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
     
      *((unsigned short *)(msg + msg[0- 2)) = Emb_Crc(msg);
     
     
      //< RFID 로 전송 및 수신>==========================
      WriteFile(hComm, msg, msg[0], &DW_write, 0);
      ReadFile(hComm, msg, 1&DW_read, 0);
      ReadFile(hComm, msg + 1, msg[0- 1&DW_read, 0);
      //=================================================
     
      
     
      //< UID >============================================
      printf("UID    : ");
      for(icnt = 0; icnt < 8; icnt++)
      {
        printf("%02X ", msg[+ icnt]);
      }
      putchar('\n');
      printf("DB-ADR : %02X \n", msg[13]);
      printf("DB-N   : %02X \n", msg[14]);
      printf("DB-SIZE: %02X \n", msg[15]);
      printf("DB     : %02X \n",   msg[16]);
     
      printf("DB-ADR-E : %02X, %02X\n", msg[4], msg[5]);
     
      printf("STATUS : %02X \n",   msg[3]);
      
      printf("Com port open Success !\n");
      CloseHandle(hComm);      // 터미널은 닫아주어야한다.
     
      return 0;
    }
     
     
    unsigned short Emb_Crc(void *arg)
    {
        unsigned short i;
        unsigned short j;
        unsigned short cnt;
        unsigned short crc=0xFFFF;
        unsigned short temp;
        unsigned char *buf = arg;
     
        cnt = (*buf) - 2;
     
        for(i=; i < cnt ; ++i)
        {
          crc^= *(buf + i);
          for(j=; j < ++j) 
          {
            if(!= (crc&0x0001))
            {
              crc=(crc>>1)^0x8408;
            }
            else
            {
              crc=(crc>>1);
            }
          }
          
        }
     
        return crc;
    }
    cs


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    unsigned char msg[128= { 0x16,
                     0x00,
                     0xB0,
                     0x24,
                     0x01,  // MODE (addressed mode)
                     0xE0,  // UID (6)
                     0x04,
                     0x01,
                     0x00,
                     0x2E,
                     0xB3,
                     0x88,
                     0x51,   
                     0x0A,  // DB-ADR (14)
                     0x01,  // DB-N
                     0x04,  // DB-SIZE
                     0x12,  // DB
                     0x34,
                     0x56,
                     0x78,
                    };
     
     
    cs


    결과는 4번 STATUS를 확인하고 0이 나오면 정상 작동이다.


    실행 결과



    [0x23] Read Multiple Blocks



    [0x23] Read Multiple Blocks

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    #include <windows.h>
    #include <stdio.h>
     
     
    unsigned short Emb_Crc(void *);
     
     
    int main()
    {
      unsigned char msg[128= { 0x11,  // n
                      0x00,
                      0xB0,
                      0x23,
                      0x01,  // MODE (addressed mode)
                      0xE0,  // UID (6)
                      0x04,
                      0x01,
                      0x00,
                      0x2E,
                      0xB3,
                      0x88,
                      0x51,   
                      0x0A,  // DB-ADR (14)
                      0x01,  // DB-N
                    };
     
       HANDLE hComm;
       DWORD DW_write;
       DWORD DW_read;
       DCB sPS;      
       COMMTIMEOUTS cTime;
       unsigned int icnt;
      
     
       // CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다.
       hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        
       if(INVALID_HANDLE_VALUE == hComm)
       {
        printf("Com port open Error !\n");
        return 0;
       }
     
        
        // 버퍼 설정
       if== SetupComm(hComm, 40964096))
       {
        printf("Buffer setting Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
      
       if== PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
       {
        printf("Buffer initialization Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
       sPS.DCBlength = sizeof(sPS);
     
       if== GetCommState(hComm, &sPS))
       {
        printf("Port status read Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
       sPS.BaudRate = CBR_38400;    // 비트,초
       sPS.ByteSize = 8;        // 데이터 비트 전송
       sPS.Parity   = EVENPARITY;   // 짝수
       sPS.StopBits = ONESTOPBIT;   // 정지 비트
        
     
        // 위 세팅값을 핸들에 넣어준다.
       if== SetCommState(hComm, &sPS))
       {
        printf("Port status write Error !\n");
        CloseHandle(hComm);  
        return 0;
       }
     
     
      *((unsigned short *)(msg + msg[0- 2)) = Emb_Crc(msg);
     
     
      //< RFID 로 전송 및 수신>==========================
      WriteFile(hComm, msg, msg[0], &DW_write, 0);
      ReadFile(hComm, msg, 1&DW_read, 0);
      ReadFile(hComm, msg + 1, msg[0- 1&DW_read, 0);
      //=================================================
     
      
     
      //< UID >============================================
      printf("UID    : ");
      for(icnt = 0; icnt < 8; icnt++)
      {
        printf("%02X ", msg[+ icnt]);
      }
      putchar('\n');
      printf("DB-ADR : %02X \n", msg[13]);
     
     
      printf("DB-N : %02X\n", msg[4]);
      printf("DB-Size :%02X\n", msg[5]);
     
      printf("STATUS : %02X \n",   msg[3]);
      
      printf("Com port open Success !\n");
      CloseHandle(hComm);      // 터미널은 닫아주어야한다.
     
      return 0;
    }
     
     
    unsigned short Emb_Crc(void *arg)
    {
        unsigned short i;
        unsigned short j;
        unsigned short cnt;
        unsigned short crc=0xFFFF;
        unsigned short temp;
        unsigned char *buf = arg;
     
        cnt = (*buf) - 2;
     
        for(i=; i < cnt ; ++i)
        {
          crc^= *(buf + i);
          for(j=; j < ++j) 
          {
            if(!= (crc&0x0001))
            {
              crc=(crc>>1)^0x8408;
            }
            else
            {
              crc=(crc>>1);
            }
          }
          
        }
     
        return crc;
    }
    cs


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    unsigned char msg[128= {  0x11,  // n
                      0x00,
                      0xB0,
                      0x23,
                      0x01,  // MODE (addressed mode)
                      0xE0,  // UID (6)
                      0x04,
                      0x01,
                      0x00,
                      0x2E,
                      0xB3,
                      0x88,
                      0x51,   
                      0x0A,  // DB-ADR (14)
                      0x01,  // DB-N
                    };
    cs


    실행 결과

    앞의 예제에서 카드에 써놓은 123456을 0A 번지에서 읽어 왔다.




    728x90
    반응형
상단으로