STM32 - Wiegand card reader
Здравствуйте.
Библиотека для работы с Wiegand на stm32.
Попалась мне в руки панель доступа она же Card Reader (на картинке) с названием DAHUA DHI-ASR1101A-D. Ещё бывают такие же, но без кнопок, только Card Reader (DHI-ASR1100A-D), и ещё всякие бывают, различных производителей.
Эти штуки общаются с микроконтроллером по протоколу Wiegand (там ещё есть RS485, но речь не о нём).
Распиновка у прибора такая…
Взято здесь.
Питается она от 12 вольт, а выходы данных 5-ти вольтовые. Я подключал к stm32 к пинам толлерантным к пяти вольтам.
CASE — служит для сигнализации о несанкционированном вскрытии устройства. То есть если кто-то попытается открутить панель от стены, тогда это проводок выдаст сигнал («плюс»).
LED — после того как код карточки прилетит в МК, и эта карточка окажется валидна, тогда если этот пин кратковременно прижать к «земле», то рисунок на панели подсветится зелёным.
Нам же сейчас интересны контакты D0 и D1, это и есть Wiegand.
Сам по себе этот протокол предельно прост. Обе линии D0 и D1 постоянно находятся в высоком состоянии, а данные передаются импульсами (короткими прижатиями
Выглядит это так…
После завершения передачи пакета, делается пауза от 250 до 500 мс. В прерываниях мы обрабатываем эти импульсы, а по длинной паузе отсутствия импульсов определяем что пакет получен.
Подробности тут.
В названии протокола обычно присутствуют цифры, типа — Wiegand-26, Wiegand-34, и т.д. Эти цифры означают количество бит в пакете. Например в описываемом устройстве используется Wiegand-4 и Wiegand-34, в первом случае передаётся код кнопки, а во втором 32-х битный ID карты. То есть, Wiegand-34 означает что он несёт в себе 32-х битное значение, а оставшиеся два бита это то ли стартовый и стоповый биты, то ли биты чётности, не знаю. Представленная ниже библиотека умеет работать с различными протоколами.
Вот так выглядит нажатие кнопки 1, и считывание карты…
Значение DEC совпадает с тем что написано на карте.
В Кубе нужно настроить два пина на внешнее прерывание, у меня это будут PB12 и PB13…
Даём пинам названия D0 и D1 соответственно, и настраиваем их оба на режим
Включаем прерывания…
Ну и настраиваем USART для вывода инфы.
Подключаем проводки D0 и D1 к PB12 и PB13, соединяем «земли», и запитываем устройство.
За основу была взята ардуиновская библиотека Wiegand-Protocol-Library-for-Arduino и адаптирована под stm32.
В проект нужно добавить файлы
/* USER CODE BEGIN Includes */
#include "wiegand.h"
/* USER CODE END Includes */
Прописываем дефайны пинов…
/* 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).
Объявляем глобальную переменную…
/* USER CODE BEGIN PV */
volatile uint8_t wig_flag_inrt = 1;
/* USER CODE END PV */
Позже скажу зачем.
Добавляем колбек для прерываний…
/* 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 */
При срабатывании прерывания будут вызываться функции обработки сигналов.
А в бесконечном цикле проверяем есть ли новые данные, и если есть, то считываем их…
/* 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);
}
}
Вот собственно и весь код. В оригинальной библиотеке сделано отключение прерываний в момент проверки и получения новых данных, видимо чтоб предотвратить искажение результата
И ещё, функцию
Результат…
Символ 0x1B (звёздочка) можно использовать как команду сброса набранных ранее цифр (если вы их складываете в какой-то массив), а символ 0xD (решётка) можно использовать как конец приёма цифр (типа Enter). При нажатии на эту кнопку устройство издаёт дополнительный сигнал.
В библиотеке (в main.c) есть закомментированный код для складывания цифр в массив и вывода его на печать при нажатии «решётки».
Размер буфера для цифр равен 12 — если он переполнится то обнулится. Если набрать несколько цифр и нажать «звёздочку», то массив с цифрами обнулится. Если набрать несколько цифр, а потом провести картой, то массив с цифрами опять таки обнулится и на печать будет выведена ID карты.
И в довершение ещё один пример, в котором сделано так, чтоб можно было не нажимать кнопку «решётка» (Enter) после ввода цифрового кода. То есть, вы набрали нужный код, и если в течении нескольких секунд новых цифр не вводится, то это расценивается системой как конец ввода. При этом нажатие на «решётку» работает в обычном режиме, ну и сброс само собой тоже.
Это может пригодится когда пульт находится в одном месте, а ворота в другом. Тогда можно просто набрать код, и идти к воротам. Пока дойдёшь — они откроются.
В примере всё то же самое, только добавлен таймер и несколько условий. Таймер настроен на паузу 4 секунды и работает в одноимпульсном режиме. Менять длину паузы нужно с помощью переполнения и сравнения. Сейчас переполнение равно 40000, а сравнение 39999. Если нужно сделать паузу 3 секунды, тогда делаем переполнение 30000, а сравнение 29999. Это справедливо если тактовая частота 72МГц.
Это всё, всем спасибо
Телеграм-чат istarik
Телеграм-чат STM32
- 0
- stD
13159
Поддержать автора
Комментарии (0)