Главная » Статьи » Proton PICBasic

Практический пример: замок с ключами IButton на 12F675
Используемый контроллер - PIC12F675 (сначала я делал под 12F629, но оказалось, их у меня уже не осталось, все использовал). Они отличаются только наличием в 675 модуля АЦП. Я его просто выключил (пока выключал, мне пришла идея, что АЦП можно было использовать для измерения уровня заряда аккумулятора для замка). Мне не понадобился аккумулятор, поскольку на заводе всегда есть электричество, потом я использую замок на 24 вольта, и, тем более, планируется использовать его только днем, а на ночь, когда никого нет, закрывать на обычный замок. Замок взят от домофона (был в наличии). Вообще все сделано из подножного материала. Итак:

IButton это микросхема, помещенная в стальной корпус, своим видом напоминающий таблетку. В этой микросхеме лазером записан уникальный код, состоящий из 8 байт.

 

1-й байт - это идентификатор семейства микросхем Dallas Semiconductor. В нашем случае он равен 1(в случае DS18B20 он равен, по-моему, $28. Не помню сейчас).
Байты со второго по 7 занимает уникальный код из 48 бит (8 бит x 6 байт), который может составить более чем 280 трлн. комбинаций, что исключает повторяемость и представляет надежность в использовании.

8-й байт содержит контрольную сумму для проверки правильности считывания. Мы не будем его использовать.

Я вижу прибор так - снаружи - порт под ключ и все(за отсутствием покупного, я сделал его сам из металлической пластины с отверстием диаметром 17мм. Внутри этого отверстия, изолированно от его краев, вогнал болт под звездочку со сточенной головкой и ко всему этому подвел два проводка). Внутри помещения - сам девайс, блок питания, блок управления и кнопка открытия изнутри(как, собственно и работает замок домофона).

Вот, собственно, схема прибора:

 

Эта схема была разработана буквально за полчаса, с учетом всех корректировок(и программных и схемных). В это же время я писал программу. На виртуальное создание ушло в целом около 3 часов. На изготовление законченного устройства еще часа 4, поскольку дело было на работе, где меня постоянно отвлекают(мешают отдыхать, в общем).

Прибор позволяет записать 5 ключей. При желании, это число можно увеличить. Пусть это будет вашим домашним заданием. Если не получится самим, то обращайтесь. Обсуждение - в форуме.
Итак, открываем Proton IDE и пишем программу(если кто-то не умеет писать, можно просто скопировать отсюда).
 

 

 

 

DEVICE = 12F675 'Выберем микроконтроллер

DECLARE XTAL= 4                    'Частота генератора

DECLARE REMINDERS NO      'Отключим предупреждения компилятора

ALL_DIGITAL YES                     'Выключим АЦП

'Включим защиту данных и программы, выключим внешний вход сброса,

'включим сброс при включении питания, включим "собаку" для надежности

'устройства, используем внутренний генератор:

CONFIG CPD_OFF, CP_ON, MCLRE_OFF, PWRTE_ON, WDT_ON, INTRC_OSC_NOCLKOUT

SYMBOL Key = GPIO.0              'Вход считывания ключа

SYMBOL Zamok = GPIO.1          'Выход управления замком

SYMBOL OpenButton = GPIO.2  'Вход кнопки открытия вручную

SYMBOL Programm = GPIO.4    'Джампер для записи ключей

SYMBOL Led = GPIO.5              'Светодиод для индикации процесса записи ключа

DIM Flags AS BYTE                   'Переменная для хранения флагов управления

DIM ID[8] AS BYTE                  'ID ключа

DIM D[6] AS BYTE                   'Переменная для считывания ключей из EEPROM

DIM Num AS BYTE                   'Переменная для хранения числа записанных ключей

DIM Count_1 AS BYTE              'Счетчик 1

DIM Count_2 AS BYTE              'Счетчик 2

DIM addr AS BYTE                    'Переменная для хранения адреса

DIM date AS BYTE                    'Переменная для хранения данных ключа

SYMBOL Write_OK = Flags.0    'Флаг окончания записи кода ключа в EEPROM

SYMBOL OpenEnable = Flags.1 'Флаг разрешения открытия

'--------------------------Начало программы-----------------------------

SET_OSCCAL OSCCAL      'Загрузим калибровочную константу в регистр OSCCAL

GPIO = %000000                    'Настроим порты

CMCON = 7                          'Компаратор нам не нужен, отключим его

TRISIO = %011101                'Настроим направление работы портов(см. выше описание портов)

OPTION_REG = %00001100 'Разрешим подтягивающие резисторы, прерывание - по спаду

                                              'предделитель на 16 включим перед WDT

WPU = %011101                    'Настроим подтягивающие резисторы индивидуально для каждого порта

Flags = 0                                'Обнулим флаги

Num = EREAD 0                  'Число записанных ключей располагается по нулевому адресу EEPROM

GOTO Main                          'Все, закончили настройку, начинаем основной цикл

'-----------------------Начало основного цикла--------------------------------

Main:

CLRWDT ' Очистим WDT

IF OpenButton = 0 THEN   'Проверяем, была ли нажата кнопка

OpenEnable = 1                 'Ставим флаг, разрешающий открытие двери

ENDIF

OWRITE Key, 1, [$33]         'Отправляем запрос по шине 1-Wire

OREAD Key, 0, [STR ID\8] 'Читаем шину в массив переменных id

IF ID[0] = $1 THEN             'Если первый байт считанных значений равен 1(это идентификатор ключа I-Button DS1990),

IF Write_OK = 0 THEN       'то, если сброшен флаг окончания записи кода ключа

IF Programm = 0 THEN       'и джампер разрешает запись

GOSUB Writte                      'то переходим на ПП записи кода ключа

ELSE                                    'А если джампер установлен не на запись

GOSUB Compare                 'То переходим на сравнение записанных в EEPROM ключей

ENDIF                                 'и только что считанного

ENDIF

ELSE

Write_OK = 0                      'Сбрасываем флаг окончания записи

                                            'Этот флаг нужен для того, чтобы

                                            'за время прикосновения не записалось

                                            'несколько ключей. Он сбрасывается только

                                            'после того, как ключ был отсоединен

ENDIF

IF OpenEnable = 1 THEN    'Если установлен флаг, разрешающий открытие двери

GOSUB DoorOpen              'То переходим на метку открытия замка

OpenEnable = 0                    'И сбрасываем этот флаг

ENDIF

GOTO Main                       'Идем на начало цикла

'--------------------Подпрограмма записи кода ключа---------------------------

Writte:

SELECT Num                    'Проверяем переменную Num(число уже записанных ключей)

CASE 5,255                       'Если там ничего не записано(значение FF), или стоит цифра 5(записано уже 5 ключей)

Num = 1                              'то записываем туда 1(будем записывать первый ключ)

addr = 2                               'Устанавливаем адрес для записи этого ключа

CASE 1                              'Если записан 1 ключ,

Num = 2                              'то записываем туда 2(второй ключ)

addr = 8                              'Для записи второго ключа адрес - 8, так как записывать нам надо всего 6 значений

CASE 2                             'И так далее...

Num = 3                            'Ставим 3

addr = 14

CASE 3

Num = 4                            'Ставим 4

addr = 20

CASE 4

Num = 5                            'Ставим 5 - максимальное число ключей

addr = 26

ENDSELECT

FOR Count_1 = 0 TO 5   'Так как нам нет надобности записывать байт идентификации

                                        'и байт CRC, то требуется всего 6 ячеек для 

                                        'хранения непосредственно уникального номера ключа

EWRITE addr + Count_1 , [ID[Count_1 + 1]] 'При записи каждого байта

                                        'инкрементируем адрес(с помощью Count_1)

                                        'и прибавляем единицу к считанному коду(пропускаем байт

                                        'идентификатора)

NEXT Count_1

EWRITE 0,[Num]           'Здесь мы записываем число ключей в нулевую ячейку

Write_OK = 1                  'Ставим флаг, что запись прошла успешно

Led = 1                            'Зажигаем светодиод, показывая пользователю, что

                                        'запись окончена и можно убрать ключ

FOR Count_2 = 1 TO 150'на 1,5 секунды

CLRWDT                       'очищаем WDT в это время

DELAYMS 10                '150 раз по 10 мс = 1,5 сек

NEXT Count_2

Led = 0                           'Гасим светодиод

RETURN

'--------------------------Подпрограмма сравнения записанных и считанного ключей

Compare:

FOR Count_1 = 2 TO 26 STEP 6 'Мы знаем, что записывали первый ключ во вторую

                                                     'ячейку

FOR Count_2 = 0 TO 5                'и нужно считать 6 байт в переменную D[]

D[Count_2] = EREAD Count_1 + Count_2

NEXT

                                                    'После этого мы сравниваем два массива D[] и ID[]

                                                    'Но в ID[0] хранится идентификатор, а в D[0] - первый байт уникального кода

                                                    'Поэтому сравниваем нулевой байт с первым и так далее...

IF D[0]=ID[1] AND D[1]=ID[2] AND D[2]=ID[3] AND D[3]=ID[4] AND D[4]=ID[5] AND D[5]=ID[6] THEN

FOR Count_2 = 0 TO 5              'Если совпадают комбинации, то сразу

ID[Count_2] = 0                          'Затираем ID[](считанный ключ), чтобы

NEXT Count_2                           'в следующем проходе не открыть замок

OpenEnable = 1                          'И разрешаем открытие двери

ENDIF

NEXT Count_1     

RETURN

'---------------------Подпрограмма открытия двери---------------------------

DoorOpen:

Zamok = 1                                'Подаем 1 на базу транзистора

Led = 1                                    'Зажигмем светодиод

FOR Count_1 = 1 TO 100       'Ждем 1 секунду

DELAYMS 10                        '100 раз по 10 мс

CLRWDT                               'Очищаем WDT

NEXT

Zamok = 0                               'Закрываем замок

Led = 0                                   'Гасим светодиод

RETURN

END                                      'Конец

Так, программа окончена. Берем программатор SmartProg 2:

(если у кого-то его нет, то берем другой :)) ) и зашиваем микроконтроллер.

Все просто. Разводим плату(я это делаю прямо в Ares - меня устраивает). Потом берем утюг и лазер. Ой, лазерный принтер. Делаем плату. У меня это происходило так:

    ->     ->  

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

 

Опять же, если кто-то вдруг не имеет такого станочка, то можно воспользоваться тем, что есть под рукой. У меня, например, в гараже лежит микродрелька, но пользоваться ей неудобно, да и слабо тянет.

В результате всех этих манипуляций получается такая платка, которую я делал, собственно, под такую коробочку:

 Я взял простую распределительную коробку и засунул все туда.

На двери повесил все так:

Замечательно!

Все работает. Если у кого-то что-то не работает или если есть вопросы, задаем в форуме.

Все исходники - здесь. Для удобсвтва, я вложил туда даташит на 12F629/675 на русском языке.

Надеюсь, вам понравилась статья и вы откликнетесь и добавите что-нибудь из собственной коллекции.

Спачибо за внимание.

PS: Одно замечание: стабилизатор на 12 В греется и довольно неплохо, поэтому, рекомендую использовать либо токоограничивающий резистор(думаю, поможет), либо радиатор, либо промежуточный стабилизатор вольт на 18.

PPS: Сначала кнопка планировалась срабатывать по прерыванию на INT, но сколько я ни бился, периодически открывание двери https://dveri-vivaldi.ru/ происходило при простом касании даже минуса схемы, не говоря уже о центральном контакте порта ключа. Голову сломал, как прерывание срабатывает, ничего так и не надумал. И осциллографом смотрел и не осциллографом. Реально программа уходила в прерывание и там разрешала открытие, причем иногда два раза подряд. В итоге решил, что простая проверка в цикле основной программы будет самое то. В данный момент программа полностью работоспособна. 

PPPS: В итоге на разработку ушло больше времени, чем я написал выше. 




Категория: Proton PICBasic | Добавил: ADMIN (02.05.2011)
Просмотров: 18011 | Комментарии: 5 | Теги: статья, замок, пример, Программа, Протон, ibutton | Рейтинг: 4.6/5
Всего комментариев: 5
1 Doberman53   (26.02.2012 14:46) [Материал]
ссылка с ошибкой http://www.picbasic.ru/proton/IButton.rar

2 ADMIN   (26.02.2012 16:07) [Материал]
Все исправил. Сейчас все в порядке

3 MiXaS   (09.09.2015 13:04) [Материал]
Спасибо, Максим! Доступно. Меня давно интересовало как работает ibutton, но тут я нашел для себя самое важное—это запрос кода ключа. спасибо!

4 MiXaS   (09.09.2015 17:07) [Материал]
Сейчас посидел попытал код в железе. Есть глюк, иногда открывает дверь на чужой ключ, но достигается это дребезгом. Добавил к коду контрольную сумму и теперь вообще отлично работает. не было еще ложных срабатываний. Так что crc8 необходим!

5 electron-86   (06.12.2022 00:52) [Материал]
Приветствую! Не могли бы вы прикрепить исходник, пожалуйста.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]