Кодовый замок
Anonymous write:
"Думаю актуальным будет направление про охранные устройства:
- кодовый замок с клавиатурой 4х4, с lcd(и без), с возможностью смены кода с клавиатуры.
в качестве исполнительного устройства использовать соленоид или движок от центрального замка автомобиля"
vakula по этой теме когда-то писал здесь: https://avrlab.com/node/85
Повторюсь:
"Давай условимся, что код у нас только цифровой, т.е. состоит из цифр от 0 до 9. В примере сделана клавиатура с кнопками "Backspace" и "Сброс", что облегчает задачу. Теперь нужно добавить функционал: "при нажатии клавиши "С" кодовый замок сверяет введенный код с кодом, разрешающим доступ, и если они совпадают - отпирает какое-то там реле и т.д.". Отобразим наши рассуждения в коде:
#include <avr/io.h> #include <avr/interrupt.h> #define NUMBER_SIZE 6 //Максимальная разрядность числа #define RS 2 //RS=PD2 #define E 3 //E=PD3 #define TIME 10 //временная константа для ЖКИ //Тактовая частота 4Mhz #define CODE 123456 //Код нашего кодового замка unsigned char key_code[4][4]={{'C','D','E','F'}, {'B','3','6','9'}, {'A','2','5','8'}, {'0','1','4','7'}}; //Коды клавиш unsigned char row[NUMBER_SIZE]={}; //массив, который содержит нажатые клавиши unsigned char row_counter=0; //количество нажатых клавиш unsigned long int number=0; //Число морганий курсора void pause (unsigned int a) { unsigned int i; for (i=a;i>0;i--) ; } //Передача команды ЖКИ void lcd_com (unsigned char lcd) { unsigned char temp; temp=(lcd&~(1<<RS))|(1<<E); //RS=0 – это команда PORTD=temp; //Выводим на portD старшую тетраду команды, сигналы RS, E asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации PORTD=temp&~(1<<E); //Сигнал записи команды temp=((lcd*16)&~(1<<RS))|(1<<E); //RS=0 – это команда PORTD=temp; //Выводим на portD младшую тетраду команды, сигналы RS, Е asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации PORTD=temp&~(1<<E); //Сигнал записи команды pause (10*TIME); //Пауза для выполнения команды } //Запись данных в ЖКИ void lcd_dat (unsigned char lcd) { unsigned char temp; temp=(lcd|(1<<RS))|(1<<E); //RS=1 – это данные PORTD=temp; //Выводим на portD старшую тетраду данных, сигналы RS, E asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации PORTD=temp&~(1<<E); //Сигнал записи данных temp=((lcd*16)|(1<<RS))|(1<<E); //RS=1 – это данные PORTD=temp; //Выводим на portD младшую тетраду данных, сигналы RS, E asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации PORTD=temp&~(1<<E); //Сигнал записи данных pause(TIME); //Пауза для вывода данных } //Иниализация ЖКИ void lcd_init (void) { lcd_com(0x2c); //4-проводный интерфейс, 5x8 размер символа pause(100*TIME); lcd_com(0x0c); //Показать изображение, курсор не показывать pause(100*TIME); lcd_com(0x01); //Очистить DDRAM и установить курсор на 0x00 pause (100*TIME); } void init_timer (void) { TIMSK=(1<<TOIE0); //Разрешить прерывания по переполнению таймера0 TCCR0=(1<<CS00)|(1<<CS01)|(0<<CS02); //Делитель =/64 } //Проверка, является ли х цифрой, если да результат =1, иначе результат =0 unsigned char is_digit (unsigned char x) { if ((x>='0')&&(x<='9')) return 1; else return 0; } //Конвертирует "row" в int значение number void get_number(void) { unsigned char i; number=0; for (i=0;i<row_counter;i++) { number=number*10; number=number+row[i]-0x30; } } //Пишем row на ЖКИ void write_row (void) { unsigned char i; lcd_com(0x86); //Перейдем в начало for (i=0;i<row_counter;i++) //Пишем row lcd_dat(row[i]); for(i=row_counter;i<NUMBER_SIZE;i++) //Очистим незаполненные ячейки lcd_dat(' '); } ISR (TIMER0_OVF_vect) { unsigned char i,j; DDRC=0x00; //PortC как вход PORTC=0x0f; DDRB=0x0f; //PortB как выход PORTB=0x00; pause(10); //Задержка для устренения всяких переходных процессов, важно ее не забыть! i=4; if ((PINC&0x01)==0x00) i=0; //Если нажата клавиша в 0й колонке, i=0 if ((PINC&0x02)==0x00) i=1; //... if ((PINC&0x04)==0x00) i=2; if ((PINC&0x08)==0x00) i=3; DDRC=0x0f; //PortC как выход PORTC=0x00; DDRB=0x00; //PortB как вход PORTB=0x0f; pause(10); //Задержка для устренения всяких переходных процессов, важно ее не забыть! j=4; if ((PINB&0x01)==0x00) j=0; //Если нажата клавиша в 0й строке, j=0 if ((PINB&0x02)==0x00) j=1; //... if ((PINB&0x04)==0x00) j=2; if ((PINB&0x08)==0x00) j=3; if ((i!=4)&&(j!=4)) { //Если была нажата клавиша while ((PINB&_BV(j))==0x00) //Ждем отжатия ; if ((is_digit(key_code[i][j])==1)&& //Нажата цифра и не достигнут лимит в NUMBER_SIZE (row_counter<NUMBER_SIZE)) { //Добавить в row и увеличить row_counter row[row_counter]=key_code[i][j]; row_counter++; } if (key_code[i][j]=='F') row_counter=0x00; //Если нажата 'F' очищаем row if ((key_code[i][j]=='E')&& (row_counter>0x00)) row_counter--; //Если нажата 'E' //и есть введенные цифры – удалить последнюю if (key_code[i][j]=='C') { //Если нажата 'C' тогда сверяем number и код доступа замка get_number(); if (number==CODE) { //отпираем замок } } } write_row(); //Пишем row на ЖКИ } TCNT0=0x00; //Очищаем таймер и флаг переполнения TIFR=0x00; return; } int main(void) { DDRD=0xfc; //Инициализация PortD PORTD=0x00; pause(1000); //Задержка для включения ЖКИ lcd_init(); //Инициализация ЖКИ init_timer(); //Инициализация нулевого таймера lcd_dat('D'); //Напишем на ЖКИ "Data= " lcd_dat('a'); lcd_dat('t'); lcd_dat('a'); lcd_dat('='); lcd_dat(' '); sei(); //Разрешения прерываний while(1) //Вечный цикл ; return 1; }
Как видно, от последнего макета прошивка отличается строками 152-168. Также был добавлен #define в строку 12.
ИМХО: изменения кода доступа с клавиатуры как-то неправильно. Код доступа должен зашиваться, или выставляться какими-то джамперами, минипереключателями, чтобы у злоумышленника не было возможности открыть замок, кроме как ввести правильный код."
hex
Афтор добавь пожалуйсто файл прошивки.
Афтар пишет, что какбэ в
Афтар пишет, что какбэ в сроке 156 надо дописать код, который будет отпирать замок. Какое силовое устройство для отпирания замка - я не знаю, потому придется дописать код под себя и скомпилировать как было сказано ниже.
Почитай как сделать hex
Почитай как сделать hex прошивку, автор вряд ли найдет время. Верней если все-таки автор не отпишется, попробуй сам сделай файл прошивки.
спасибо собрал все как
спасибо собрал все как написано в статье, работает