Программный блок ожидания активности в сети
1. Проверим бит RCIF в регистре PIR1.
2. Если бит установлен, пропустим следующую команду.
3. Вызовем подпрограмму обработки команды.
4. Вернемся к началу.
Вот и вся программа:
Start: BTFSS PIR1, RCIF ; Ждем прихода первого символа команды.
GOTO start
CALL cmnd ; С приходом первого символа начинаем обработку. GOTO start
Следующая трудность спрятана как раз в этом месте, хотя я умудрился наступить на эти грабли при обработке «іпі». Разумная, как мне казалось, конструкция:
Start: BTFSS PIRl, RCIF ; Ждем прихода первого символа команды.
GOTO start
Работать в режиме отладки MPLAB не хотела. Я все перепроверил многократно. Все было правильно, но анимация программы безнадежно застревала, я решил, что программа не работает. Понять, в чем здесь дело, помогло обращение к сайту Microchip, где на форуме этот вопрос уже обсуждался Причина столь не очевидного поведения программы очевидна (когда знаешь). Отладчик в цикле опроса ждет прохождения нескольких тысяч тактов внутреннего генератора, работающего на частоте в 4-20 МГц до заполнения регистра, которое происходит с частотой примерно 10 кГц. Вдобавок, настройки отладчика по умолчанию делают анимацию хорошо воспринимаемой (одно или два перемещения в секунду), но дождаться нескольких тысяч таких перемещений лично у меня ума не хватило.
Обработку команды я опять оформил в виде подпрограммы.
; Обработка команды - проверка адреса, определение команды.
Cmnd: BCF STATUS, Z MOVF RCREG, 0
XORLW 0x52 ; Проверим наш ли модуль R (52h).
BTFSS STATUS, Z ; Если нет вернемся.
RETURN
Inl: BTFSS PIR1, RCIF ; Ждем прихода первого символа адреса.
GOTO inl ; Если совпадает, продолжим. MOVF RCREG, 0 BCF STATUS, Z
XORWF 0x21, 0 ; Первый символ адреса в регистре 21h.
BTFSS STATUS, Z
RETURN
In2: BTFSS PIRl, RCIF ; Ждем прихода второго символа адреса.
GOTO in2 ; Если совпадает, продолжим. MOVF RCREG, 0 BCF STATUS, Z
XORWF 0x22, 0 ; Второй символ адреса в регистре 22h.
BTFSS STATUS, Z
RETURN
ІпЗ: BTFSS PIR1, RCIF ; Ждем прихода символа.
GOTO іпЗ ;Если следом символ команды, продолжим. MOVF RCREG, О BCF STATUS, Z
XORLW 0x24 ; Символ команды "$" (24h) . BTFSC STATUS, Z
CALL swtch ; Вызываем подпрограмму выполнения. RETURN
; Подпрограмма определения команды N (включить), F
(выключить)
; или S (состояние).
Swtch: CLRW
In4: BTFSS PIR1, RCIF ; Ждем прихода символа. GOTO in4
MOVF RCREG, 0 ; Прочитаєм номер реле.
MOVWF 0x23 ; Сохраним номер реле в регистре 23h
MOVLW 0x30 ; Запишем регистр 30h в аккумулятор.
SUBWF 0x23, 0 ; Переведем символ в номер.
MOVWF 0x23 ; Сохраним номер реле в регистре 23h
In5: BTFSS PIR1, RCIF ; Ждем прихода символа. GOTO in5
MOVF RCREG, 0 ; Разберем N-включить, F-выключить, S - статус.
MOVWF 0x24 ; Сохраним команду в регистре 24h. BCF STATUS, Z
XORLW 0x4E ; Включение N (4Eh) . BTFSC STATUS, Z ; Если нет, то пропустим. CALL cmdset
MOVF 0x24, 0 ; Перепишем из 24h в аккумулятор. BCF STATUS, Z
XORLW 0x46 ; Выключение F (46h) . BTFSC STATUS, Z ; Если нет, то пропустим. CALL cmdreset
MOVF 0x24, 0 ; Перепишем из 24h в аккумулятор. BCF STATUS, Z
XORLW 0x53 ; S (53h) запрос статуса. BTFSC STATUS, Z ; Если нет, то пропустим. CALL stat
; Сохраним состояние всех реле в энергонезависимой памяти. ; Перепишем регистр 30h состояния реле в EEPROM.
CLRW
MOVLW 0x00 ; Запишем Oh в аккумулятор.
MOVWF EEADR ; Запишем адрес Oh в регистр адреса.
BCF STATUS, RPl; Выбор банка 0.
BCF STATUS, RPO
CLRW
ADDWF 0x30,0 ; Запишем содержимое 3Oh в аккумулятор.
COMF 0x30,0 ; Инвертируем перед сохранением.
BSF STATUS, RP0 ; Выбор банка 1.
BCF STATUS, RPl
MOVWF EEDATA
BSF STATUS, RPO
BCF STATUS, RPl ; Выбор банка 1. BSF EECONl, WREN ; Разрешить запись. BCF INTCON, GIE ; Запретить прерывания. MOVLW 0x55
MOVWF EECON2 ; Записать 55h. MOVLW OxAA
MOVWF EECON2 ; Записать AAh.
BSF EECONl, WR ; Установить флаг для начала запись. BSF INTCON, GIE ; Разрешить прерывания. BCF EECONl, WREN ; Запретить запись.
; Запись 55h и AAh относятся к обязательным при работе с EEPROM.
BCF STATUS, RPl ; Выбор банка 0. BCF STATUS, RPO
Chkwr: BTFSS PIR1, EEIF ; Проверка завершения записи. GOTO chkwr CLRW
ADDWF 0x30, 0
MOVWF PORTA ; Перепишем 30h в порт. BCF PIR1, EEIF ; Сбросим флаг. RETURN
В этом месте работы с отладчиком я вначале проверил выполнение двух команд подряд. Все работало. Затем я вписал запись состояния реле в EEPROM с проверкой окончания записи. И, естественно, обнаружил, что вторая команда перестала выполняться. Но теперь я быстрее сообразил, что запись занимает время, в течение которого успевает пройти необработанная часть команды. Я не стал «городить огород», вставив между двумя нужными командами третью, ненужную. Хочу еще заметить, что изготовитель микросхем советует осуществить проверку записи в EEPROM, которая вставляется после проверки завершения записи. Я этого не сделал. Но после создания прототипа я могу переделать программу, удалив из слова команды символьное представление номера модуля и номера реле, могу сделать и программное задание адреса. Тогда и добавлю проверку правильности записи в EEPROM.