Microprocessor/Module

RFID(UID/Write Multiple Blocks/Read Multiple Blocks)[20121016]

Dexter_- 2018. 12. 10. 11:32
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
반응형