https://istarik.ru/blog/stm32/144.html
stm32에서 Wiegand와 함께 작업하기 위한 라이브러리. 나는 액세스 패널에 손을 댔고, DAHUA DHI-ASR1101A-D라는 이름의 카드 리더기 (그림)
이기도 합니다 . 같은 것도 있지만 버튼이 없고 카드리더기(DHI-ASR1100A-D)만 있고 그외 제조사도 별거 다 있습니다. 이러한 것들은 Wiegand 프로토콜을 사용하여 마이크로 컨트롤러와 통신합니다 (RS485도 있지만 이것에 관한 것은 아닙니다) . 장치의 핀아웃은 다음과 같습니다. 여기에서 가져왔습니다 . 전원은 12볼트이며 데이터 출력은 5볼트입니다. 5볼트를 허용하는 stm32 핀에 연결했습니다.
CASE – 장치의 무단 열림을 알리는 역할을 합니다. 즉, 누군가가 패널을 벽에서 풀려고 하면 이 배선이 신호 (“플러스”) 를 제공합니다 .
LED-카드 코드가 MK에 도착하고이 카드가 유효한 것으로 판명 된 후이 핀을 “접지”에 짧게 누르면 패널의 그림이 녹색으로 강조 표시됩니다. 우리는 이제 연락처 D0 및 D1
에 관심이 있습니다 . 이것은 Wiegand입니다. 그 자체로 이 프로토콜은 매우 간단합니다. 라인 D0과 D1은 모두 지속적으로 높으며 데이터는 펄스로 전송됩니다 (짧은 누름
(20-200µs)이 줄이나 저 줄을 “접지”로) . D0 라인 의 펄스는 0이 전송되었음을 의미하고 D1 의 펄스는 단위가 전송되었음을 의미합니다. 펄스 사이의 일시 중지는 약 2ms입니다.
이렇게 생겼습니다.
패킷 전송이 완료된 후 250에서 500ms 사이에 일시 중지됩니다. 인터럽트에서 우리는 이러한 펄스를 처리하고 펄스가 없는 긴 일시 중지로 패킷이 수신되었음을 확인합니다.
자세한 내용은 여기 .
프로토콜의 이름에는 일반적으로 Wiegand-26, Wiegand-34 등과 같은 숫자가 포함됩니다. 이 숫자는 패킷의 비트 수를 나타냅니다. 예를 들어, 설명된 장치는 Wiegand-4 및 Wiegand-34를 사용하며, 첫 번째 경우에는 버튼 코드가 전송되고 두 번째 경우에는 32비트 카드 ID가 전송됩니다. 즉, Wiegand-34는 32비트 값을 전달한다는 의미이며 나머지 2비트는 시작 및 중지 비트 또는 패리티 비트입니다. 아래에 제시된 라이브러리는 다양한 프로토콜과 함께 작동할 수 있습니다.
버튼 1을 누르고 카드를 읽는 모습입니다…
설정으로 이동합니다.
쿠바에서는 외부 인터럽트를 위해 두 개의 핀을 구성해야 합니다. 저에게는 PB12 및 PB13이 될 것입니다 … 우리는 핀에 각각 D0 및 D1
이라는 이름을 지정 하고 둘 다 모드로 설정합니다.떨어지는.
우리는 인터럽트를 켭니다 …
음, 정보를 출력하도록 USART를 설정했습니다.
전선 D0 및 D1을 PB12 및 PB13 에 연결 하고 “접지”를 연결하고 장치에 전원을 공급합니다.
이제 프로그램에 대해:
Arduino 라이브러리 Wiegand-Protocol-Library-for-Arduino를 기반으로 stm32에 적용했습니다.README의 링크에는 여전히 일부 다중 비트 프로토콜이 있다고 나와 있으며 내가 다시 만들지 않은 올바른 프로토콜에 대한 링크가 제공됩니다.
프로젝트에 추가할 파일wiegand.c그리고wiegand.h. 안에main.c헤더 포함…
1 2 3 4 5 |
/* USER CODE BEGIN Includes */ #include "wiegand.h" /* USER CODE END Includes */ |
우리는 핀 정의를 규정합니다 …
1 2 3 4 5 6 |
/* USER CODE BEGIN PD */ #define D0 D0_Pin #define D1 D1_Pin /* USER CODE END PD */ |
핀에 이름을 할당하지 않은 경우 D0_Pin 및 D1_Pin 대신 기본 이름(GPIO_PIN_12 및 GPIO_PIN_13)을 적어 둡니다.
전역 변수 선언 중…
1 2 3 4 5 |
/* USER CODE BEGIN PV */ volatile uint8_t wig_flag_inrt = 1; /* USER CODE END PV */ |
이유는 나중에 말씀드리겠습니다.
인터럽트 콜백 추가 중…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* USER CODE BEGIN 0 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(wig_flag_inrt && GPIO_Pin == D0) { ReadD0(); } else if(wig_flag_inrt && GPIO_Pin == D1) { ReadD1(); } } /* USER CODE END 0 */ |
인터럽트가 트리거되면 신호 처리 기능이 호출됩니다.
그리고 무한 루프에서 새로운 데이터가 있는지 확인하고 있으면 읽습니다 …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* USER CODE BEGIN WHILE */ while (1) { if(wig_available()) { wig_flag_inrt = 0; uint32_t wcode = getCode(); int16_t wtype = getWiegandType(); wig_flag_inrt = 1; char str[64] = {0,}; snprintf(str, 64, "HEX=0x%lX DEC=%lu, Protokol Wiegand-%d\n", wcode, wcode, wtype); HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), 1000); } } |
이것이 실제로 전체 코드입니다. 원래 라이브러리는 결과의 왜곡을 방지하기 위해 새로운 데이터를 확인하고 수신할 때 인터럽트를 비활성화합니다.(이것은 나에게 모호한 행동으로 보이지만 각 검사에서 인터럽트가 비활성화되어 신호 누락으로 이어질 수 있음이 밝혀졌습니다). 나는 그것을 끄지 않고 단순히 플래그 (wig_flag_inrt) 를 추가하여 결과를 읽을 때 신호 처리 기능을 입력하지 못하게합니다.(이 옵션에도 결함이 있지만).
그러나 기능wig_available()지속적으로 호출하지 않는 것이 더 나을 수 있지만 예를 들어 20-30ms마다 한 번씩이면 충분합니다. 타이머와 플래그를 통해 이를 수행하거나 다음과 같이 할 수 있습니다 .
문자 0x1B (별표) 는 이전에 전화를 건 숫자를 재설정하는 명령으로 사용할 수 있으며 (일종의 배열에 추가하는 경우) 문자 0xD (파운드 기호)는 수신의 끝으로 사용할 수 있습니다. 숫자 (Enter 입력) . 이 버튼을 누르면 장치에서 추가 신호를 내보냅니다.
라이브러리 (main.c)에는 배열에 숫자를 추가하고 “파운드” 버튼을 누를 때 인쇄하는 주석 코드가 있습니다.
숫자 버퍼의 크기는 12입니다. 넘치면 0으로 재설정됩니다. 여러 자리를 입력하고 “별표”를 누르면 숫자가 있는 배열이 0으로 재설정됩니다. 몇 개의 숫자를 입력한 다음 카드를 스 와이프하면 숫자 배열이 다시 0으로 재설정되고 카드 ID가 인쇄됩니다.
그리고 마지막으로 디지털 코드를 입력 한 후 “파운드” (Enter) 버튼 을 누르지 않는 방식으로 수행되는 또 다른 예입니다 . 즉, 원하는 코드를 입력했으며 몇 초 내에 새 숫자를 입력하지 않으면 시스템에서 입력이 끝난 것으로 간주합니다. 동시에 “격자”를 클릭하면 일반 모드에서 작동하며 자체 재설정도 수행됩니다.
이는 리모컨이 한 곳에 있고 게이트가 다른 곳에 있을 때 유용할 수 있습니다. 그런 다음 코드를 누르고 게이트로 이동할 수 있습니다. 거기에 도착하면 열릴 것입니다.
예제에서는 모든 것이 동일하며 타이머와 여러 조건만 추가됩니다. 타이머는 4초 동안 일시정지하도록 설정되어 있으며 단일 펄스 모드로 작동합니다. 오버플로 및 비교를 사용하여 일시 중지 길이를 변경해야 합니다 . 이제 오버플로는 40000이고 비교는 39999입니다. 3초 동안 일시 중지해야 하는 경우 30000을 오버플로하고 비교는 29999입니다. 이는 클록 주파수가 72MHz인 경우에 해당합니다.
그게 다야, 모두 에게 감사합니다