우리는 사무실, 쇼핑몰 및 기타 많은 장소에서 승인 카드를 소지 한 사람 만 방에 들어갈 수 있다는 것을 알고 있습니다. 이러한 시스템은 RFID 통신 시스템을 사용합니다. 쇼핑몰에서 RFID는 제품에 RFID 칩이 부착되어있어 도난을 막기 위해 사용되며, 사람이 RFID 칩을 가지고 건물을 나가면 자동으로 알람이 울립니다. RFID 태그는 모래의 일부만큼 작게 설계되었습니다. RFID 인증 시스템은 설계가 쉽고 비용이 저렴합니다. 오늘날 일부 학교와 대학은 RFID 기반 출석 시스템을 사용 합니다.
이 프로젝트에서 우리는 인증 된 투표 만 계산하는 투표 기계를 설계 할 것입니다. 이것은 RFID (Radio Frequency Identification) 태그를 사용하여 수행됩니다. 여기에서는 승인 된 RFID 태그 보유자 만 투표 할 수 있도록 ATMEGA 용 프로그램을 작성합니다. (또한이 간단한 투표 기계 프로젝트를 확인하십시오)
필요한 구성 요소
하드웨어: ATMEGA32, 전원 공급 장치 (5v), AVR-ISP PROGRAMMER, JHD_162ALCD (16x2LCD), 100uF 커패시터 (전원 공급 장치에 연결됨), 버튼 (5 개), 10KΩ 저항 (5 개), 100nF 커패시터 (5 개), LED (2 개), EM-18 (RFID 리더 모듈).
소프트웨어: Atmel studio 6.1, progisp 또는 flash magic.
회로도 및 설명
회로에서 ATMEGA32의 PORTA는 LCD의 데이터 포트에 연결됩니다. 여기서는 PORTC를 일반 통신 포트로 사용하려는 경우 퓨즈 바이트를 변경하여 PORTC에서 ATMEGA 로의 JTAG 통신을 비활성화하는 것을 기억해야합니다. 16x2 LCD에는 검은 색 빛이 있으면 전체적으로 16 개의 핀이 있고, 백라이트가 없으면 14 개의 핀이 있습니다. 백라이트 핀에 전원을 공급하거나 남겨 둘 수 있습니다. 이제 14 핀에는 8 개의 데이터 핀 (7-14 또는 D0-D7), 2 개의 전원 공급 장치 핀 (1 & 2 또는 VSS & VDD 또는 gnd & + 5v), 대비 제어를위한 3 번째 핀 (VEE- 문자의 두께 제어)이 있습니다. 그림), 3 개의 제어 핀 (RS & RW & E)
회로에서 제어 핀이 두 개뿐이라는 것을 알 수 있습니다. 이것은 더 나은 이해의 유연성을 제공하며 대비 비트 및 READ / WRITE는 자주 사용되지 않으므로 접지로 단락 될 수 있습니다. 이렇게하면 LCD가 가장 높은 명암비 및 읽기 모드가됩니다. ENABLE 및 RS 핀을 제어하여 문자와 데이터를 적절하게 전송하면됩니다.
LCD에 대해 수행되는 연결은 다음과 같습니다.
접지에 대한 PIN1 또는 VSS
PIN2 또는 VDD 또는 VCC ~ + 5v 전원
PIN3 또는 VEE to ground (초보자에게 최상의 대비를 제공)
uC의 PD6에 PIN4 또는 RS (등록 선택)
PIN5 또는 RW (읽기 / 쓰기)를 접지 (LCD를 읽기 모드로 설정하여 사용자의 통신을 용이하게 함)
PIN6 또는 E (활성화)-uC의 PD5
uC의 PIN7 또는 D0 ~ PA0
PIN8 또는 D1-uC의 PA1
PIN9 또는 D2-uC의 PA2
uC의 PIN10 또는 D3 ~ PA3
uC의 PIN11 또는 D4 ~ PA4
uC의 PIN12 또는 D5 ~ PA5
uC의 PIN13 또는 D6 ~ PA6
uC의 PIN14 또는 D7 ~ PA7
회로에서 8 비트 통신 (D0-D7)을 사용했음을 알 수 있습니다. 그러나 이것은 필수는 아니고 4bit 통신 (D4-D7)을 사용할 수 있지만 4bit 통신 프로그램은 약간 복잡 해져서 8bit 통신을 선호했습니다.
따라서 위의 표만 살펴보면 LCD의 10 핀을 컨트롤러에 연결하는 것으로 8 핀은 데이터 핀이고 2 핀은 제어용입니다.
계속 진행하기 전에 직렬 통신에 대해 이해해야합니다. 여기서 RFID 모듈은 데이터를 컨트롤러에 직렬로 보냅니다. 다른 통신 모드가 있지만 쉬운 통신을 위해 RS232를 선택합니다. 모듈의 RS232 핀은 ATMEGA의 RXD 핀에 연결됩니다.
RFID 모듈에서 보낸 데이터는 다음과 같습니다.
이제 RFID 모듈 인터페이스의 경우 다음 기능이 필요합니다.
1. 컨트롤러의 RXD 핀 (데이터 수신 기능)이 활성화되어 있어야합니다.
2. 통신은 직렬이기 때문에 데이터 바이가 수신 될 때마다 알 필요가 있으므로 완전한 바이트가 수신 될 때까지 프로그램을 중지 할 수 있습니다. 이것은 데이터 수신 완료 인터럽트를 활성화하여 수행됩니다.
3. RFID는 8 비트 모드에서 컨트롤러로 데이터를 전송합니다. 따라서 한 번에 두 개의 문자가 컨트롤러로 전송됩니다. 이것은 그림 3의 블록에 표시됩니다.
4. 그림 3에서 패리티 비트가없고 모듈이 보낸 데이터에 정지 비트 하나가 있습니다.
위의 기능은 컨트롤러 레지스터에서 설정됩니다. 간단히 논의 할 것입니다.
RED (RXEN):이 비트는 데이터 수신 기능을 나타냅니다.이 비트는 컨트롤러가 모듈에서 데이터를 수신하도록 설정해야하며 컨트롤러의 RXD 핀도 활성화합니다.
BROWN (RXCIE):이 비트는 성공적인 데이터 수신 후 인터럽트를 받기 위해 설정되어야합니다. 이 비트를 활성화하면 8 비트 데이터 수신 직후 알게됩니다.
PINK (URSEL):이 비트는 UCSRC에서 다른 필요한 비트를 설정 한 후 UCSRC에서 다른 비트를 활성화하기 전에 설정해야합니다. URSEL을 비활성화하거나 0으로 설정해야합니다.
YELLOW (UCSZ0, UCSZ1, UCSZ2):이 세 비트는 우리가 한 번에 받거나 보내는 데이터 비트 수를 선택하는 데 사용됩니다.
RFID 모듈이 보낸 데이터는 8bit 데이터 타입 (그림 3)이므로 UCSZ0, UCSZ1을 1로, UCSZ2를 0으로 설정해야합니다.
ORANGE (UMSEL):이 비트는 시스템이 비동기 적으로 (둘 다 다른 클럭 사용) 통신하는지 또는 동 기적으로 (둘 다 동일한 클럭 사용) 통신하는지에 따라 설정됩니다.
모듈과 컨트롤러는 서로 다른 클럭을 사용하므로이 비트는 기본적으로 모두 0으로 설정되어 있으므로 0으로 설정하거나 그대로 두어야합니다.
녹색 (UPM1, UPM0):이 두 비트는 통신에서 사용하는 비트 패리티를 기반으로 조정됩니다.
RFID 모듈은 패리티없이 데이터를 전송하기 때문에 (그림 3) UPM1, UPM0을 모두 0으로 설정하거나 모든 레지스터의 모든 비트가 기본적으로 0으로 설정되어 있으므로 그대로 둘 수 있습니다.
파란색 (USBS):이 비트는 통신 중에 사용하는 정지 비트 수를 선택하는 데 사용됩니다.
RFID 모듈은 하나의 정지 비트 (그림 3)로 데이터를 전송하므로 USBS 비트를 그대로두면됩니다.
이제 마지막으로 전송 속도를 설정해야합니다. 그림 3에서 RFID 모듈이 9600bps (초당 비트 수)의 전송 속도로 컨트롤러에 데이터를 전송하는 것이 분명합니다.
전송 속도는 적절한 UBRRH를 선택하여 컨트롤러에서 설정합니다.
UBRRH 값은 전송 속도와 CPU 크리스탈 주파수를 교차 참조하여 선택됩니다.
따라서 상호 참조에 의해 UBRR 값은 '6'으로 표시되므로 전송 속도가 설정됩니다.
여기에 다섯 개의 버튼이 있습니다. 네 개는 후보자의 투표를 늘리기위한 것이고 다섯 번째는 후보자의 투표를 0으로 재설정하기위한 것입니다. 여기에있는 커패시터는 버튼의 바운싱 효과를 무효화하기위한 것입니다. 제거되면 버튼을 누를 때마다 컨트롤러가 둘 이상을 계산할 수 있습니다.
핀에 연결된 저항은 버튼을 눌러 핀을 접지로 끌어 당길 때 전류를 제한하기위한 것입니다. 버튼을 누를 때마다 컨트롤러의 해당 핀이지면으로 당겨져 컨트롤러가 특정 버튼을 눌렀다는 것과 해당 조치를 취해야 함을 인식하고 버튼을 눌렀을 때 후보 투표를 늘리거나 투표를 재설정 할 수 있습니다.
해당 인물을 나타내는 버튼을 누르면 컨트롤러가 해당 인물을 선택하고 증분 후 메모리 내 해당 인물 번호를 증분하며 16x2 LCD 디스플레이에 해당 인물 점수를 표시합니다.
투표 기계의 작동은 아래에 주어진 C 코드의 단계별로 가장 잘 설명됩니다.
코드 설명
핀에 대한 데이터 흐름 제어를 활성화하는 #include // header
#define F_CPU 1000000 // 텔링 컨트롤러 크리스탈 주파수 부착
#포함
#define E 5 // LCD Enable 핀에 연결되어 있으므로 PORTD의 5 번째 핀에 "enable"이라는 이름을 부여합니다.
#define RS 6 // LCD RS 핀에 연결되어 있으므로 PORTD의 6 번째 핀에 "registerselection"이라는 이름을 부여합니다.
void send_a_command (unsigned char 명령);
void send_a_character (unsigned char character);
void send_a_string (char * string_of_characters);
int main (void)
{
DDRA = 0xFF; // porta를 출력 핀으로 설정
DDRD = 0b11111110;
_delay_ms (50); // 50ms 지연 제공
DDRB = 0b11110000; // 일부 portB 핀을 입력으로 사용합니다.
UCSRB-= (1 <
// 데이터 수신 완료 인터럽트 활성화, 데이터 수신 핀 활성화
UCSRC-= (1 <
// 먼저 URSEL 설정으로 다른 비트 변경, 8 비트 통신 설정
UCSRC & = ~ (1 <
UBRRH & = ~ (1 <
UBRRL = 6; // 전송 속도 설정
int16_t VOTEA = 0; // person1 투표 메모리 저장
char A; // person1 투표 LCD에 문자 표시
int16_t VOTEB = 0;; // person2 투표 저장 메모리
char B; // person2 LCD에 문자 표시 투표
int16_t VOTEC = 0;; // person3 투표 저장 메모리
char C; // person3 LCD에 문자 표시
int16_t VOTED = 0;; // person4 투표 저장 메모리
char D; / / person4 투표 LCD에 문자 표시
// 다음은 태그의 ID를 포함합니다. 다른 태그에 대해 변경해야합니다. 프로젝트가 작동하려면 업데이트해야합니다.
// 컨트롤러에 프로그램을 덤핑 한 후 인증을 받아야하는 카드를 가져 와서 태그 ID를 가져와야합니다. 태그를 RFID 모듈 근처에 배치하여 획득하고 ID가 화면에 표시됩니다. ID를받은 후 아래의 ID 번호를 새 ID 번호로 교체하여 프로그램을 업데이트해야합니다.
char ADMIT = {{(0x97), (0xa1), (0x90), (0x92)}, {(0x97), (0xa1), (0x90), (0x93)}, {(0x97), (0xa1), (0x90), (0x94)}, {(0x97), (0xa1), (0x90), (0x95)}, {(0x97), (0xa1), (0x90), (0x96)}}; |
이제 위에서 우리는 5 개의 카드 만 승인합니다.이 카드는 임의의 숫자로 변경할 수 있습니다.
예를 들어, 기본 프로그램이 컨트롤러에 덤프되어 있다고 가정하고, 인증되어야하는 카드를 모듈 근처에서 차례로 가져 오면 각각의 ID를 xxxxxxxx (907a4F87)로 얻게됩니다.
7 개의 태그가 있으면 7 개의 8 비트 ID를 갖게됩니다.
// 이제 7 장의 카드에 대해 // char ADMIT = {{(0x90), (0x7a), (0x4F), (0x87)},; // 모듈에서 보낸 ID를 표시하기위한 메모리 할당 int i = 0; int vote = 0; int k = 0; send_a_command (0x01); // 화면 지우기 0x01 = 00000001 _delay_ms (50); send_a_command (0x38); // telling lcd 우리는 8bit 명령을 사용하고 있습니다 / data 모드 _delay_ms (50); send_a_command (0b00001111); // LCD SCREEN ON 및 Courser 깜박임 char MEM; // 태그의 완전한 ID를 저장하기위한 메모리 할당 send_a_string ("RFID NUMBER"); // 전송 문자열 send_a_command (0x80 + 0x40 + 0); // 강좌를 두 번째 줄로 이동 동안 (1) { while (! (UCSRA & (1 <
{ } COUNTA = UDR; // UDR은 수신 된 8 비트 데이터를 저장하고 정수로 가져옵니다. MEM = COUNTA; // 처음 두 문자가 메모리로 업데이트됩니다. itoa (COUNTA, SHOWA, 16); // LCD에 변수 번호를 넣는 명령 (바꿀 문자, 밑 수가 변수 인 변수 번호 (여기서는 base10에서 숫자를 세는 것처럼 10)) send_a_string (SHOWA); // LCD에 코스터를 위치시킨 후 2 인칭 캐릭터 (가변 숫자로 대체)를 디스플레이에 표시 while (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = COUNTA; // 세 번째 및 네 번째 문자가 메모리로 업데이트됩니다. while (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = COUNTA; // 다섯 번째 및 여섯 번째 문자가 메모리에 업데이트됩니다. while (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = COUNTA; // 일곱 번째 및 여덟 문자가 메모리에 업데이트됩니다. send_a_string (""); send_a_command (0x80 + 0x40 + 0); UCSRB & = ~ (1 <
(i = 0; i <5; i ++) { if ((MEM == ADMIT) & (MEM == ADMIT) & (MEM == ADMIT) & (MEM == ADMIT)) {// 한 번에 두 문자를 메모리의 문자와 비교하여 인증 구매 확인 PORTB-= (1 <
vote = 1; // 승인 된 세트 VOTE } } if (vote == 0) // 투표가 설정되지 않은 경우 인증 실패 { UCSRB-= (1 <
} while (vote == 1) // 승인 된 경우 투표 할 때까지이 루프를 수행합니다. { send_a_command (0x80 + 0); // 라인 1의 위치 0으로 이동 send_a_string ("VOTE NOW"); // 문자열 표시 if (bit_is_clear (PINB, 0)) // 버튼 1을 눌렀을 때 { VOTEA ++; // 첫 번째 사람의 투표 메모리를 하나씩 늘립니다. vote = 0; // 투표 후 루프 이동 } if (bit_is_clear (PINB, 1)) // 버튼 2를 눌렀을 때 { VOTEB ++; // 두 번째 사람 의 투표 메모리 1 씩 증가 vote = 0; } if (bit_is_clear (PINB, 2)) // 버튼 3을 눌렀을 때 { VOTEC ++; // 세 번째 사람 의 투표 메모리 1 씩 증가 vote = 0; } if (bit_is_clear (PINB, 3)) // 버튼 4를 눌렀을 때 { VOTED ++; // 4 번째 사람 의 투표 메모리 1 씩 증가 vote = 0; } (투표 == 0) // 투표 후 취소 된 경우 { send_a_command (0x80 + 0); // 라인 1의 위치 0으로 이동 send_a_string ("감사합니다 투표"); // 표시 문자열 for (k = 0; k <10; k ++) { _delay_ms (220); } 포트 B & = ~ (1 <
send_a_command (0x01); send_a_command (0x80 + 0); // 네 명 모두의 투표 표시 send_a_string ("A ="); send_a_command (0x80 + 2); itoa (VOTEA, A, 10); send_a_string (A); send_a_command (0x80 + 8); send_a_string ("B ="); send_a_command (0x80 + 10); itoa (VOTEB, B, 10); send_a_string (B); send_a_command (0x80 + 0x40 + 0); send_a_string ("C ="); send_a_command (0x80 + 0x40 + 2); itoa (VOTEC, C, 10); send_a_string (C); send_a_command (0x80 + 0x40 + 8); send_a_string ("D ="); send_a_command (0x80 + 0x40 + 10); itoa (VOTED, D, 10); send_a_string (D); send_a_command (0x80 + 0x40 + 16); for (k = 0; k <25; k ++) { _delay_ms (220); } UCSRB-= (1 <
send_a_command (0x01); send_a_command (0x80 + 0); // 제로 위치로 이동 send_a_string ("RFID NUMBER"); // 문자열 보내기 send_a_command (0x80 + 0x40 + 0); } } void send_a_command (unsigned char 명령) { PORTA = 명령; 포트 & = ~ (1 <
포트-= 1 <
_delay_ms (50); 포트 & = ~ 1 <
PORTA = 0; } void send_a_character (unsigned char character) { PORTA = 캐릭터; 포트-= 1 <
포트-= 1 <
_delay_ms (50); 포트 & = ~ 1 <
PORTA = 0; } void send_a_string (char * string_of_characters) { while (* 문자열 _ 문자> 0) { send_a_character (* 문자열 _ 문자 ++); } } |