Кодовый замок с приводом от центрального замка авто

Обсуждаем цифровые устройства...
Ответить
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн янв 26, 2009 17:27:18
Откуда: Odessa, Ukraine

Сообщение taran_ob »

Может кому пригодится.

Код четырехзначный. При неверном коде или паузе более 2с при вводе кода, звучит сигнал и инициируется новый ввод. Для смены кода нужно подать питание с зажатыми кнопками 1234, после сигнала ввести новый код, который хранится в энергонезависимой памяти.

http://www.youtube.com/watch?v=e56xhP-f ... r_embedded


ПС подробнее тут http://krainamaystriv.com/threads/15126/


Изображение
Вложения
GUARD_v1.HEX
Прошивка ATTiny2313A
(3.72 КБ) 326 скачиваний
GUARD_PCB.jpg
Плата
(203.79 КБ) 485 скачиваний
GUARD_SCH.JPG
Схема
(230.17 КБ) 643 скачивания
WP_000594.jpg
Фото
(133.99 КБ) 9381 скачивание
Реклама
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн янв 26, 2009 17:27:18
Откуда: Odessa, Ukraine

Сообщение taran_ob »

Исходник

Код: Выделить всё

/*///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
This program was produced by the
CodeWizardAVR V2.05.3 Standard
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
 
Project : GUARD
Version : 1.0
Date    : 23.01.2013
Author  : TOB
Comments: Кодовый замок c приводом от автомобильного замка.
Для смены кода, подать питание с нажатыми кнопками 1234, после сигнала ввести код.
 
Chip type              : ATtiny2313A
AVR Core Clock frequency: 4,000000 MHz
Memory model            : Tiny
External RAM size      : 0
Data Stack size        : 32
 
*////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
#include <tiny2313A.h>
#include <delay.h>
 
#define DOOR_STATUS (1<<0)          //флаг закрытой двери
#define ACTUATOR_STATUS (1<<1)      //флаг закрытого замка
#define PGM_MODE (1<<2)            //флаг режим программирования
#define OPEN_KEY (1<<3)            //флаг кнопка "ОТКРЫТЬ" нажата
#define CODE_COMPARE (1<<4)        //флаг правильный код
#define NEW_CODE (1<<5)            //флаг введен новый код
#define NEW_PRES (1<<6)            //флаг начало ввода нового кода
 
#define OPEN_PIN PINB.7            //кнопка "ОТКРЫТЬ" (0-нажата)
#define DOOR_PIN PIND.6            //датчик двери (0-закрыта)
#define KEY_PORT PINB              //пины клавиатуры
#define REL_OPEN_PIN PORTD.0        //пин реле открытия замка
#define REL_CLOSE_PIN PORTD.1      //пин реле закрытия замка
#define BUSER_PIN PORTD.5          //пин пищалки
 
#define CLOSE 1                    //для процедуры актюатора
#define OPEN 0                      //для процедуры актюатора
 
#define ACTUATOR_DELAY 1000        //мс, длительность импульса привода
#define AVTO_CLOSE_DELAY 600        //10с, число тактов 0.0163с, задержка автоматического закрытия, если дверь не открыли
#define CLOSE_DELAY 300            //5с, число тактов 0.0163с, задержка перед закрытием  (должно выполняться условие AVTO_CLOSE_DELAY>=CLOSE_DELAY)
#define KEY_DELAY 2                //32мс, число тактов 0.0163с, период сканирования кнопок
#define INPUT_DELAY 60              //2с, максимальная пауза при вводе кода, число сканирований клавиатуры
 
#define CODE_SIZE 4                //число символов кода
#define KEY_SIZE 6                  //число сканируемых кнопок
 
flash char KEY_MASS[12]=            //массив ASCII кодов кнопок
{
0x30,  //0
0x31,  //1
0x32,  //2
0x33,  //3
0x34,  //4
0x35,  //5
0x36,  //6
0x37,  //7
0x38,  //8
0x39,  //9
0x0F,  //*
0x23    //#
};
flash char NOTE_MASS[45][2]=        //массив нот
{
/*         
500кГц      Частота    Нота   
239        2093        C7   
213        2349        D7     
190        2637        E7
179        2794        F7
159        3136        G7
142        3520        A7
127        3951        H7                   
*/
159,700,        //пи 
142,100,        //бриу бриу
159,50,
142,50,
159,100,
0,25,
179,50,
190,100,
213,25,
190,25,   
179,300,        //па па па паам
0,400,
179,300,
0,400,
179,300,
0,200,
255,1000,
213,100,        //брынь
0,50,
190,100,
0,50,
179,100,
0,50,
159,100,
0,50,   
142,50,        //сирена
159,50,   
179,50,   
190,50,               
213,50,   
239,50,
213,50,
190,50,               
179,50,   
159,50,   
142,50
};
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
eeprom unsigned char eep_code[CODE_SIZE];
unsigned char real_code[CODE_SIZE];
unsigned char input_code[CODE_SIZE];
unsigned char new_code[CODE_SIZE];
unsigned char status_flag_reg;
unsigned int tim1_ovf_count0, tim1_ovf_count1;
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
//прерывание по переполнению таймера 1, инкремент счетчиков
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
if (tim1_ovf_count0<2540) tim1_ovf_count0++;      //частота сканирования
if (tim1_ovf_count1<2540) tim1_ovf_count1++;      //задержка перед закрытием
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
//процедура инициализации контроллера
void ini(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
 
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
// State7=P State6=P State5=P State4=P State3=P State2=P State1=P State0=0
PORTB=0xFE;
DDRB=0x01;
 
// Port D initialization
// Func6=In Func5=Out Func4=In Func3=In Func2=In Func1=Out Func0=Out
// State6=P State5=0 State4=P State3=P State2=P State1=0 State0=0
PORTD=0x5C;
DDRD=0x23;
 
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 500,000 kHz
// Mode: CTC top=OCR0A
// OC0A output: Disconnected
// OC0B output: Toggle on compare match
TCCR0A=0x12;
TCCR0B=0x00;
//TCCR0B=0x02;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
 
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 4000,000 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x80;
 
// Global enable interrupts
#asm("sei")
}
 
//процедура управления приводом
void actuator(char action)
{
if (action) {REL_CLOSE_PIN=1; delay_ms(ACTUATOR_DELAY); REL_CLOSE_PIN=0; status_flag_reg|=ACTUATOR_STATUS;}    //закрыть замок
else  {REL_OPEN_PIN=1; delay_ms(ACTUATOR_DELAY); REL_OPEN_PIN=0; status_flag_reg&=~ACTUATOR_STATUS;}          //открыть  замок
}
 
//процедура генерации звуков
void saund(unsigned char first_note, unsigned char last_note)
{
static unsigned char i;               
TCCR0B=0x02;                                                                    //инициализация таймера 500кГц
for (i=first_note; i<last_note; i++)                                            //цикл проигрывания диапазона нот из массива
    {
    OCR0A=NOTE_MASS[i][0];                                                      //нота (чвстота) в регистр сравнения таймера в режиме СТС
    delay_ms(NOTE_MASS[i][1]);                                                  //длительность ноты
    };
TCCR0B=0x00; OCR0A=0x00; BUSER_PIN=0;                                          //остановить таймер
}
 
//процедура сканирования датчиков
void sensor(void)
{
if (DOOR_PIN) status_flag_reg&=~DOOR_STATUS; else status_flag_reg|=DOOR_STATUS; //если дверь открыта, то сбросить флаг
if (OPEN_PIN) status_flag_reg&=~OPEN_KEY; else status_flag_reg|=OPEN_KEY;      //если кнопка не нажата, то сбросить флаг
}
 
//процедура сканирования клавиатуры
void key(void)
{
static unsigned char i,j,k,l;
 
if (l<INPUT_DELAY) l++;                                                        //если счетчик определения максимальной паузы при вводе не переполнен, то инкремент
else
    {
    if (status_flag_reg&NEW_PRES)                                              //если же пауза слишком большая - счетчик переполнен и кнопка была нажата, то
        {
        saund(10,17);                                                          //сигнал превышения паузы при вводе
        for (j=0; j<CODE_SIZE; j++) input_code[j]=0;                            //очистить массив введенного кода
        status_flag_reg&=~NEW_PRES;                                            //сбросить флаг нажатия на кнопку
        i=0;j=0;k=0;                                                            //сброс счетчиков
        };
    };
 
for (i=1; i<=KEY_SIZE; i++)                                                    //цикл сканирования клавиатуры
    {
    if ((~KEY_PORT)&(1<<i))                                                    //если сканируемая кнопка нажата, то
        {
        l=0;                                                                    //сбрасываем счетчик для определения паузы при вводе
        status_flag_reg|=NEW_PRES;                                              //установить флаг нажатия на кнопку
        saund(0,1);                                                            //сигнал подтверждения нажатия
        while((~KEY_PORT)&(1<<i)) {};                                          //ничего не делать пока кнопка нажата
        delay_ms(200);                                                          //предотвращение дребезга
        input_code[j]=KEY_MASS[i];                                              //введенный символ заносим в массив ввода
        if ((j++)==(CODE_SIZE-1))                                              //если массив ввода заполнен, то
            {
            for (j=0; j<CODE_SIZE; j++) new_code[j]=input_code[j];              //введенный код сохранить как новый
            status_flag_reg|=NEW_CODE;                                          //установить флаг нового кода
            for (j=0; j<CODE_SIZE; j++) if (input_code[j]==real_code[j]) k++;  //цикл посимвольной проверки введенного кода
            if (k==CODE_SIZE)                                                  //если совпали все символы, то
                {
                status_flag_reg|=CODE_COMPARE;                                  //устанавливаем флаг
                saund(17,25);                                                  //сигнал подтверждения кода
                }
            else  if(!(status_flag_reg&PGM_MODE))saund(10,17);                  //иначе, если не режим программирования, то сигнал ошибки
            for (j=0; j<CODE_SIZE; j++) input_code[j]=0;                        //очистить массив введенного кода
            status_flag_reg&=~NEW_PRES;                                        //сбросить флаг нажатия на кнопку
            i=0;j=0;k=0;                                                        //сброс счетчиков                                                 
            };
        };
    };
}

//программная процедура
void main(void)
{
static unsigned char i;
ini();                                                                          //инициализация контроллера
saund(0,1);
delay_ms(4000);                                                                //пауза 5с
if (DOOR_PIN) actuator(OPEN); else actuator(CLOSE);                            //если дверь открыта, то открыть замок, иначе закрыть замок
 
if (!(KEY_PORT&0b00011110))                                                    //если  при вкл. нажаты кнопки 1234, то начинаем цикл программирование
    {
    saund(25,35); saund(25,35);                                                //сигнал подтверждения входа в режим программирования
    while(!(KEY_PORT&0b00011110)) {};                                          //ничего не делать пока кнопки нажаты
    delay_ms(200);                                                              //предотвращение дребезга
    status_flag_reg|=PGM_MODE;                                                  //установить флаг режима программирования
    while (status_flag_reg&PGM_MODE)                                            //цикл выполняется пока есть флаг режима программирования
        {
        if (tim1_ovf_count0>KEY_DELAY) {tim1_ovf_count0=0; key();};            //периодически сканируется клавиатура
        if (status_flag_reg&NEW_CODE)                                          //если введен новый код, то
            {
            for (i=0; i<CODE_SIZE; i++) eep_code[i]=new_code[i];                //сохранить новый код в ЕЕПРОМ
            status_flag_reg&=~NEW_CODE;                                        //сбросить флаг нового кода
            status_flag_reg&=~PGM_MODE;                                        //сбросить флаг режима программирования
            saund(17,25);                                                        //сигнал подтверждения обновления кода
            };
        };
    };
 
for (i=0; i<CODE_SIZE; i++) real_code[i]=eep_code[i];                          //читать код из ЕЕПРОМ
 
while (1)                                                                      //цикл рабочего режима
    {
    if (tim1_ovf_count0>KEY_DELAY) {tim1_ovf_count0=0; sensor(); key();};
    switch (status_flag_reg&0b00000011)
        {
        case 0b00000000:                                                        //замок открыт, дверь открыта
            {
//            saund(1,9);                                                        //сигнализация открытой двери
            tim1_ovf_count1=AVTO_CLOSE_DELAY-CLOSE_DELAY;                      //начать отсчет перед закрытием замка
            status_flag_reg&=~CODE_COMPARE;
            break;
            };
        case 0b00000001:                                                        //замок открыт, дверь закрыта
            {                                                           
            saund(1,9);                                                        //сигнализация открытого замка
            if (status_flag_reg&OPEN_KEY) tim1_ovf_count1=0;                    //предотвращает передергивание замка при нажатой кнопке "ОТКРЫТЬ"
            if (tim1_ovf_count1>AVTO_CLOSE_DELAY) actuator(CLOSE);              //автоматическое закрытие по истечению паузы, если дверь не была открыта
            status_flag_reg&=~CODE_COMPARE;
            break;
            };
        case 0b00000010:                                                        //замок закрыт, дверь открыта (ошибочная ситуация)
            {
            actuator(OPEN);                                                    //открыть замок
            status_flag_reg&=~CODE_COMPARE;
            break;
            };
        case 0b00000011:                                                        //замок закрыт, дверь закрыта
            {
            if ((status_flag_reg&CODE_COMPARE)|(status_flag_reg&OPEN_KEY))      //если флаг верного кода или кнопка "ОТКРЫТЬ" нажато, то
                {
                actuator(OPEN);                                                //открыть замок
                status_flag_reg&=~CODE_COMPARE;                                //сбросить флаг верного кода
                };
            tim1_ovf_count1=0;                                                  //сбрасывается счетчик для автоматического закрытия
            break;
            };
        };
    };
}
Реклама
Ответить

Вернуться в «Цифровая техника»