|
; Программа управления дверцей/шторкой диспенсера(устройство выдачи наличных)
; В данной пьесе участвуют следующие лица и исполнители; Входящие сигналы:
; DoorIsClose датчик - дверца закрыта, активный '1' световой поток перекрыт
; DoorIsOpen датчик - дверца открыта, активный '1' световой поток перекрыт; CloseDoor команда закрыть дверь, активный '0'
; OpenDoor команда открыть дверь, активный '0'; Исходящие сигналы:
; StateIsClose сигнализация диспенсеру - дверца закрыта, активный '1'
; StateIsOpen сигнализация диспенсеру - дверца открыта, активный '1'; MP и MM управление сдвоенным оптроном транзисторные выходы которого
; включени в "H" мост и управляют микромоторчиком дверцы
; если MP != MM то мотор будет крутится в ту или иную сторону.
; DDR соответствующих ножек тоже должны быть установлены в '1'; Есть еще "действующие лица" которых сложно
; задетектировать/идентифицировать/предположить.
; Это подклинивание механизма, злоумышленник вставляющий посторонние предметы,
; Дед Мороз примораживающий механику и т.д.; А также массовка в составе таймеров, ватч-догов и т.д.
; Общий вид пьесы.
; После инициализации портов и сбросов всех сигналов(ножек) в неактивное сотояние
; процессор переходит в неактивное состояние.
; Опрос датчиков, фильтрация помех, выполнение действий происходит
; по прерыванию таймера 0.
; Тактирование процессора от внутреннего RC генератора 1МГц.
; Прерывание 1000000/(256*256), что составит около 0,066 секунд
; Фильтрация от помех состояния датчиков упрощенная.
; Каждый раз по прерыванию "заталкиваем" в регистр по 1 при активном
; сигнале и 0 при неактивном.
; решение принимаем при значении в регистре 0x00 или 0xFF
; Таким образом время действия сигнала не менее 0,066*8=0,5 секунд.; Собственно пьеса о проделках таймера.
; 1-й АКТ
; Опросить датчики DoorIsClose, DoorIsOpen и при равенстве 0x00 или 0xFF
; выставить соответствующие потенциалы для диспенсера StateIsClose, StateIsOpen
; 2-й АКТ
; Опросить сигналы(команды) CloseDoor, OpenDoor
; Проанализировать сначала пару CloseDoor/DoorIsClose и включить мотор
; в нужном направлении.
; Если первая пара не требует отработки проанализировать аналогично OpenDoor/DoorIsOpen.
; Для того чтобы предотвратить бесконечную отработку команды CloseDoor/OpenDoor,
; вводится переменная MotorToOff, наверное 1 байт будет достаточно -
; 255*0.066=16 секунд. Которая инициализируются при включении/отключении мотора.
; 3-й АКТ
; Если мотор включен то декрементировать MotorToOff
; до срабатывания требуемого датчика или при достижении 0, отключать мотор.
; таким образом бесконечная отработка команды будет предотвращена.
; 4-й АКТ
; Диспенсер держит активную команду до 2-х минут, злоумышленник или
; сбой механики может привести к тому что, после 16 секунд, дверца не займет
; требуемого положения и в действие вступит опять АКТ 2, мотор снова включится.
; Заклиненый мотор имеет очень низкое сопротивление и много мощности выделяется на
; транзисторах "H" моста. Перегревается самый близкий к стабилизатору питания мотора.
; Совместный нагрев и ведет к отказу транзистора. Таким образом нужно вводить
; еще одну переменную для отсчета паузы, после не успешной попытки закрыть/открыть
; дверцу, для предотвращения перегрева. Пауза должна быть около 2-х минут, чтобы
; дать возможность остыть транзисторам и не слишком большой чтобы программа
; управления диспенсером не посчитала сбой полным отказом. Назовем эту переменную
; TimeForCool. Ее рассчетное значение:
; 2 минуты= 120 секунд=120/0,066=1800 срабатываний таймера 0.
; Эпилог
; Теперь выстроим порядок проверки условий для изменения состояния мотора
; по мере убывания приоритета:; 1) TimeForCool==0
; 2) Опрос команд CloseDoor, OpenDoor и датчиков DoorIsClose, DoorIsOpen
; 3) Проверка MotorToOff
; 4) Проверка датчика DoorIsClose
; (при подаче питания/провисания дверцы от выработки механики); Получилось не драматическое произведение а детектив,
; самое интересное в последней главе :-).include "tn26def.inc"
; ножки входных сигналов уже разведены на плате изменить нельзя.
; да и часть исходных текстов тоже досталась по наследству :-)..equ CloseDoor = PB4
.equ OpenDoor = PB6.equ DoorIsClose = PA0
.equ DoorIsOpen = PB0; выходные сигналы
.equ StateIsClose = PB1
.equ StateIsOpen = PB3; Входы встречно-включенных оптронов, направление вращения двигателя
; и защита от сквозных токов в мосте
.equ MM = PA5
.equ MP = PA3; переменные
.def temp =R16
.def temp2 =R17
; байт для подсчета времени, на отключения мотора, тайм аут на команду
.def MotorToOff = R18; байты для фильтрации от помех при опросе датчиков
;.def StateClose = R19
;.def StateOpen = R20.def CurentState = R21 ; текущее сотояние логического состояния контроллера
.equ None = 0
.equ Closing = 1
.equ Opening = 2; слово для подсчета времени на охлаждение транзисторов/мотора
.def lTimeForCool = R24
.def hTimeForCool = R25.include "isrtable.inc" ; здесь ничего интересного, таймер 0 отрабатывается.
; Константы :-) будем менять здесь, что-бы не рыскать по тексту
.equ _MotorToOff = 100 ; 255 = 16 c половиной секунд
.equ _TimeForCool = 900 ; 1800 = две минуты;.equ SignaledState = 0x03 ; датчик сработал и маска сколько бит анализировать
;.equ UnSignaledState = 0x00 ; датчик не сработалSYSRES:
cli
wdr
ldi temp,0x0C
out WDTCR,temp ;Watch DOG on 0.25sec
sbi ACSR,7 ;Comparator Disableldi temp,1<
out MCUCR,temp clr temp
out GIMSK,temp ; эти прерывания нас не интересуютldi temp, 1<
out TIMSK, temp ldi temp,(1<
out DDRA,temp ser temp ; Все ножки подтянем
out PORTA,templdi temp,(1<
out DDRB, temp ldi temp,~((1<
out PORTB,templdi temp,4 ;SETUP T/C0 (CK/256)~0,066sec 256*256 циклов
out TCCR0,templdi temp,127
out SP,tempser temp ;FLAGSs INT OFF
out TIFR,temp; Обнулим счетчики и фильтры
clr hTimeForCool
clr lTimeForCool
clr MotorToOffldi CurentState, Closing ; по включению проверим закрыта ли дверь
sei
; все проинициализировали теперь пусть таймер работает
TheTimeToSleep:
nop
sleep
nop
rjmp TheTimeToSleep
;------------------------------------------------------------
; Таймер о переполнился, прошло 0,065 секунды
OVF_0:
wdr; трансляция состояния датчиков положения двери
sbic PINA, DoorIsClose
sbi PORTB, StateIsClose
sbis PINA, DoorIsClose
cbi PORTB, StateIsClosesbic PINB, DoorIsOpen
sbi PORTB, StateIsOpen
sbis PINB, DoorIsOpen
cbi PORTB, StateIsOpen
; проверим, может hardware еще не остыло :-)tst lTimeForCool
brne WaitCool
tst hTimeForCool
brne WaitCoolrjmp CheckCommands ; считаем что остыло, будем пробовать закрывать, открывать
; декрементируем время паузы на охлаждение
WaitCool:
sbiw lTimeForCool,1
rjmp EndISR
; Теперь анализируем команды, в начале на закрытие потом на открытие
CheckCommands:
sbis PINB, CloseDoor
rjmp MakeCloseDoorsbis PINB, OpenDoor
rjmp MakeOpenDoor; или может прошлую команду не доработали ?
cpi CurentState, Closing
breq MakeCloseDoorcpi CurentState, Opening
breq MakeOpenDoor; команд нет, а дверца НЕ закрыта ?
; cpi StateClose, SignaledState ; датчик сработал и отфильтрован?
; breq EndISR ; дверца закрыта, уходим по английски не прощаясь :-)
rjmp EndISR ; нет ни команд, ни не оконченных действий
; пытаемся закрыть дверцу
MakeCloseDoor:
; cpi StateClose, SignaledState ; датчик сработал и отфильтрован?
sbic PINA, DoorIsClose
rjmp SuccessMove ; датчик и команда совпадают ничего не надо делатьldi CurentState, Closing
sbi PORTA,MM ; выберем направление движения
cbi PORTA,MP
rjmp MakeMove ; собственно на обработку включенияMakeOpenDoor:
; cpi StateOpen, SignaledState ; датчик сработал и отфильтрован?
sbic PINB, DoorIsOpen
rjmp SuccessMove ; датчик и команда совпадают ничего не надо делатьldi CurentState, Opening
cbi PORTA,MM ; выберем направление движения
sbi PORTA,MP
rjmp MakeMove ; собственно на обработку включения
MakeMove:
sbi DDRA,MM ; пустили мотор
sbi DDRA,MP
cpi MotorToOff, 0
breq StartMotorTimer ; Команда только пришла запускаем таймер на выполнения
; команда уже выполняется, проверяем может время вышло и пора отключатся?
dec MotorToOff
brne EndISR ; пока нет, выходим из прерывания
; Ваше время истекло :-(
cbi DDRA,MM
cbi DDRA,MP ; остановили мотор
ldi hTimeForCool, High(_TimeForCool) ; установили задержку для остывания
ldi lTimeForCool, Low(_TimeForCool)
rjmp EndISRStartMotorTimer:
ldi MotorToOff, _MotorToOff ; максимальное время отработки команды
rjmp EndISR
SuccessMove:
cbi DDRA,MM
cbi DDRA,MP ; остановили мотор
clr MotorToOff ;
ldi CurentState, None
EndISR:
reti
E-mail: info@telesys.ru