EData 0,100,40,2,$FF,%00111100," DVERI1 "," DVERI1 "," DVERI1 "," DVERI1 ","79139990000","F","79139991111", "F","79139992222","F"
Declare Reminders= OFF'
Declare Warnings = OFF '
Declare FSR_CONTEXT_SAVE = OFF'
Declare Optimiser_Level 3 '
'-------------------------- ------------------------------------
Device = 16F628 '
Xtal = 4 '
Config BODEN_OFF, PWRTE_ON, WDT_OFF, LVP_OFF, MCLRE_OFF, INTRC_OSC_NOCLKOUT, DATA_CP_ON
'intrc_osc_noclockout - чтобы кварц не ставить
'mclre_off - потому что используется porta.5, можно и другой порт использовать
'pwrte_on - обязательно для лучшего запуска
'cp_on, data_cp_on - чтобы никто не считал программу
'-------------------------- Описание проекта ---------------------------------
'Проект : GSMSTOR
'Автор : Admin
'Версия : 1.0.0 от 21.10.2009
'-------------------------- Опции компилятора --------------------------------
'-------------------------- Настройки USART ----------------------------------
Declare Hserial_Baud 19200 ' Скорость передачи данных, бод для сименсов C35 и C45
Declare Hserial_TXSTA = %00100100 ' Включить передатчик USART
Declare Hserial_RCSTA = %10010000 ' Включить приемник USART
Declare Hserial_Clear = On ' Автоматическая очистка бита ошибки переполнения
'-------------------------- ------------------------------------
Declare All_Digital = On 'Все порты - цифровые
'-------------------------- START------------------------------------
Dim char[8] As Byte'переменные для хранения букв латинского алфавита при перекодировке
Dim pdu[8] As Byte 'Данные PDU формата
Dim tmp[8] As Byte 'Массив временных переменных
Dim ch[8] As Byte 'Массив временных переменных
Dim id[8] As Byte 'Массив для считывания значений записанных ключей из EEPROM
Dim ID_real[8] As Byte 'Массив для считанных с ключа значений кода ключа
Dim x As Byte 'Счетчик
Dim j As Byte 'Счетчик
Dim I As Byte 'Счетчик
Dim z As Byte 'Счетчик
Dim PN[13] As Byte 'Массив для считывания телефонных номеров
Dim ALARMFLAGS As Byte 'Переменная флагов тревоги
Dim count_ As Byte 'Переменная - счетчик циклов дозвонов и отправки SMS
Symbol onSMS = ALARMFLAGS .5 'Флаг разрешения отправки SMS
Symbol onCall = ALARMFLAGS .4 'Флаг разрешения дозвона
Symbol CH_4_ALLOW = ALARMFLAGS.3 'Флаг разрешения слежения за четвертым каналом
Symbol CH_3_ALLOW = ALARMFLAGS.2 'Флаг разрешения слежения за третьим каналом
Symbol CH_2_ALLOW = ALARMFLAGS.1 'Флаг разрешения слежения за вторым каналом
Symbol CH_1_ALLOW = ALARMFLAGS.0 'Флаг разрешения слежения за первым каналом
Dim Start_OXR As Bit 'Флаг режима охраны
Dim delrun As Byte 'Переменная - задержка после открытия двери
Dim DELAY As Byte 'Задержка для прослушивания при дозвоне на номер хозяина
Dim numCall As Byte 'Планировалось использовать для счета числа дозвонов
Dim SN As Byte 'Начало тел. номера
Dim EN As Byte 'Конец тел. номера
Dim SS As Byte 'Начало SMS
Dim ES As Byte 'Конец SMS
Dim ADDR_TEMP As Byte 'Временная переменная для адреса записи
Dim addr As Byte 'Адрес записи
Dim edat As Byte 'Временная переменная для записываемых данных
Dim date As Byte 'Данные для записи
Dim Num As Byte 'Переменная для хранения количества ключей в EEPROM
Symbol INPUT_1 = PORTB.7 'Канал 1
Symbol INPUT_2 = PORTB.6 'Канал 2
Symbol INPUT_3 = PORTB.5 'Канал 3
Symbol INPUT_4 = PORTB.4 'Канал 4
Symbol INPORT = PORTA.5 'Вход для включения режима записи ключей
Symbol LED = PORTA.0 'Светодиод
Symbol dq = PORTA.1 'Вход для ключей
Clear 'Очистим RAM
PORTB=%11110010 'Настроим portb
CMCON = 7 'Отключим компараторы
TRISB = %11110010 'Каналы - на вход, ключ - на вход, остальные - на выход
TRISA = %00100010
OPTION_REG = %10000000 'Отключим подтяжку на portb
LED = 1 'Моргнем светодиодом
DelayMS 1000 'чтобы узреть начало работы
LED = 0
CONTr = 0
GoSub SETPARAM 'Считаем параметры из EEPROM
WRITE_KEY: 'Начало программы
If INPORT = 0 Then 'Проверяем, если режим записи ключей включен, то
GoSub DS1990 'считываем значение ключа
If id[0] = $1 Then 'Если это - DS1990, то
If Num = 255 Then 'если в памяти не записан ни один ключ, то
addr=74 : edat = 0 'присваиваем адрес начала записи первого ключа
EndIf 'и число, показывающее, куда записывать следующий ключ
If Num = 0 Then 'Если в памяти уже записан один ключ, то
addr=80 : edat = 1 'присваиваем адрес начала записи второго ключа
EndIf 'и число, показывающее, куда записывать следующий ключ
If Num = 1 Then 'Если в памяти уже записано два ключа, то
addr=86 : edat = 2 'присваиваем адрес начала записи третьего ключа
EndIf 'и число, показывающее, куда записывать следующий ключ
If Num = 2 Then 'Если в памяти уже записано три ключа, то
addr=92: edat = 3 'присваиваем адрес начала записи четвертого ключа
EndIf 'и число, показывающее, куда записывать следующий ключ
If Num = 3 Then 'Если в памяти уже записано четыре ключа, то
addr = 74: edat = 0 'присваиваем адрес начала записи первого ключа
EndIf 'и число, показывающее, куда записывать следующий ключ
For I = 0 To 5
ADDR_TEMP = addr + I
date = id[I + 1]
GoSub WRITE_ 'Теперрь записываем считанный ключ по указанному адресу
Next
ADDR_TEMP = 4: date = edat 'Записываем число, показывающее, куда записывать следующий ключ
GoSub WRITE_ 'по адресу 4
High LED 'Моргнем светодиодом, указывая пользователю, что запись
DelayMS 1000 'ключа завершена
Low LED
EndIf
GoTo WRITE_KEY 'переходим на начало
EndIf 'Если не включен режим записи ключей
DelayMS 2000 'то ожидаем 2 секунды перед началом работы сторожа
CheckPhone: 'Инициализация
GoSub TURN_LED 'Могрнем, показывая, что идет обмен с телефоном
HSerOut ["AT" ,13]
HSerIn 500, CheckPhone,[Wait("OK")]'Ждем ответа, если нет , то снова на CheckPhone
CheckPhone2:
GoSub TURN_LED 'то же самое, только
HSerOut ["AT+CMGF=0" ,13] 'команда другая - включаем PDU формат
HSerIn 500, CheckPhone2,[Wait("OK")]'Ждем ответа от телефона
loop:
DelayMS 900 'Задержка для видимости моргания светодиода
GoSub DS1990 'Проверяем, вставлен ли ключ
If id[0] = $1 Then 'Если поднесен ключ
GoSub Read_ 'Сравниваем с записанными значениями
EndIf
SSSS:
If Start_OXR = 1 Then 'Если включен режим охраны
OPTION_REG.7 = 0 'Включаем подтягивающие резисторы
LED = 1 'Зажигаем светодиод, отображая режим охраны
If INPUT_1 = 1 Then 'И сразу проверяем канал охраны на разрыв
If CH_1_ALLOW = 1 Then 'Если разрешено слежение за ним
Gosub Zaderzh
If Start_OXR = 0 Then EEEE 'Если хозяин отключил охрану, то вернемся
SS = 6: ES = 13 'устанавливаем адрес начала и конца слова для SMS в EEPROM
GoSub GO_EACH_CH 'и переходим на оповещение
EndIf
EndIf
If INPUT_2 = 1 Then 'И сразу проверяем канал охраны на разрыв
If CH_2_ALLOW = 1 Then 'Если разрешено слежение за ним
Gosub Zaderzh
If Start_OXR = 0 Then EEEE 'Если хозяин отключил охрану, то вернемся
SS = 14: ES = 20 'устанавливаем адрес начала и конца слова для SMS в EEPROM
GoSub GO_EACH_CH 'и переходим на оповещение
EndIf
EndIf
EEEE:
OPTION_REG.7 = 1 'отключим подтяжку на portb
LED = 0 '
DelayMS 500 'погасим светодиод
EndIf
GoTo loop 'Начнем сначала
GO_EACH_CH:
LED = 1
If onSMS = 1 Then 'Если разрешена отправка SMS
SN = 38: EN = 49 'Считаем
GoSub SETNUM 'первый телефонный номер
GoSub SendSMS 'и отправим на него SMS
SN = 50: EN = 61 'Считаем
GoSub SETNUM 'второй телефонный номер
GoSub SendSMS 'и отправим на него SMS
SN = 62: EN = 73 'Считаем
GoSub SETNUM 'третий телефонный номер
GoSub SendSMS 'и отправим на него SMS
EndIf
DelayMS 5000 'Задержка нужна, так как телефон не успевает отработать
'команду отправки последнего SMS
If onCall = 1 Then 'Если разрешен дозвон
SN = 38: EN = 49 'считаем
GoSub SETNUM 'первый телефонный номер
GoSub Call_ 'и позвоним на него
SN = 50: EN = 61 'считаем
GoSub SETNUM 'второй телефонный номер
GoSub Call_ 'и позвоним на него
SN = 62: EN = 73 'считаем
GoSub SETNUM 'третий телефонный номер
GoSub Call_ 'и позвоним на него
EndIf
LED = 0 'выключим светодиод
Return
'-------------------------------------------------------------------------------------
SendSMS: 'Начало подпрограммы кодирования текста в PDU формат
j = 0
For I = SS To ES
char [j] = ERead I 'Считаем текст СМС в формате ASCII
Inc j
Next
'-----Преобразуем в PDU
tmp[1]=char[1] << 7
tmp[2]=char[2] << 6
tmp[3]=char[3] << 5
tmp[4]=char[4] << 4
tmp[5]=char[5] << 3
tmp[6]=char[6] << 2
tmp[7]=char[7] << 1
For z = 0 To 6
pdu[z]=tmp[z + 1] + (char[z] >> z)
Next z
Check_: 'Начало отправки сообщения на указанный номер (PN[i]), в формате PDU (pdu[i])
If CONTr = 2 Then ret1 'Если произойдет сбой, то после первого раза остановимся
HSerOut ["AT+CMGS=22",13]'команда на отправку сообщения
Inc CONTr
HSerIn 5000, Check_,[Wait(">")]'ожидание подтверждения команды
'Непосредственно отправка сообщения
HSerOut ["0011FF0B91", PN[1],PN[0],PN[3],PN[2],PN[5],PN[4],PN[7],PN[6],PN[9],PN[8],PN[11],PN[10],_
"0000AA","08",Hex2 pdu[0], Hex2 pdu[1], Hex2 pdu[2], Hex2 pdu[3], Hex2 pdu[4], Hex2 pdu[5], Hex2 pdu[6],Hex2 pdu[7],26]
HSerOut [13]
DelayMs 3000
ret1: CONTr = 0
Return 'Возврат из ПП отправки SMS
Call_: 'ПП дозвона по указанному телефонному номеру (PN[i])
If CONTr = 2 Then ret2 'Если произойдет сбой, то после первого раза остановимся
HSerOut ["ATD+",PN[0],PN[1],PN[2],PN[3],PN[4],PN[5],PN[6],PN[7],PN[8],PN[9],PN[10],";",13] 'Звоним...
DelayMS 5000 'Задержка
HSerOut ["AT+CPAS" ,13]'Проверка состояния телефона
Inc CONTr
HSerIn 5000, Call_,[Wait("4")] 'Если состояние не то, которое нам нужно (вызов), то на метку Call_
'чтобы попытаться еще раз
For x = 1 To DELAY 'Даем время хозяину прослушать помещение
DelayMS 1000
Next
HSerOut ["ATH",13] 'Отменяем вызов по окончанию
ret2: CONTr = 0
Return
WRITE_:
EWrite ADDR_TEMP,[ date] 'Процедура записи переменных по указанным адресам
Return
Read_: 'ПП считывания кода ключа и сравнения с записанными в память ключами
For z = 74 To 98 Step 6 'Ключи записаны последовательно с 74 ячейки по 98
addr = z 'По 6 байт на каждый ключ
For j = 0 To 5
ID_real[j] = ERead addr + j 'Непосредственно считывание из памяти записанных ключей
Next
'Сравниваем только что считанные значения ключа с записанными:
If ID_real[0]=id[1] And ID_real[1]=id[2] And ID_real[2]=id[3] And ID_real[3]=id[4] And ID_real[4]=id[5] And ID_real[5]=id[6] then
'Если ключ совпадает с одним из записанных
If Start_OXR = 1 Then 'то, если охрана включена
Start_OXR = 0 'отключим ее
LED = 0 'погасим светодиод
Else 'Если же охрана выключена
LED = 1 'Зажжем светодиод, указывая на начало постановки на охрану
'DelayMS 25000 'Это время дается хозяину на выход из помещения
Start_OXR = 1 'Включаем охрану
EndIf
GoTo EXIT_ 'выходим
EndIf
Next 'Если ключ не совпал с текущим записанным, то сравниваем со следующим
EXIT_:
Return
DS1990:
OWrite dq, 1, [$33] 'Процедура чтения кода ключа
ORead dq, 0, [Str id\8] 'в переменную ID[i]
Return
TURN_LED: 'ПП моргания светодиодом
LED = 1
DelayMS 250
LED = 0
Return
SETPARAM: 'ПП считывания параметров работы прибора
flags = ERead 0 'Считаем флаги
delrun = ERead 1 'Считаем задержки
DELAY = ERead 2 'Считаем задержки
' numCall = ERead 3
Num = ERead 4 'Считаем число, указывающее на кол-во уже записанных ключей
ALARMFLAGS = ERead 5 'Считаем переменную установок тревоги
Return
SETNUM: 'ПП считывания телефонных номеров
I = 0
For x = SN To EN
PN[I] = ERead x
Inc I
Next
Return
Zaderzh:
For I = 1 To delrun 'то задерживаемся на указанное время
High LED 'В это время, если зашел хозяин
DelayMS 75 'ему дается возможность отключить охрану
Low LED 'отображаем этот режим светодиодом
DelayMS 100 '
GoSub DS1990 'здесь хозяин может отключить охрану
If id[0] = $1 Then
GoSub Read_
EndIf 'в нормальный режим
Next
Return
End
|