SUBTITL "CONTROLLER RFID" ;+-------------------------------------------------------------------------+ ;¦ Программа контроллера устройства радиочастотной идентификации ¦ ;+-------------------------------------------------------------------------+ ; INCLUDE ; ; Назначение выводов ; #define R_OFF PORTC,3 ; p.7 #define INPUT PORTC,4 ; p.6 #define OSER PORTB,1 ; p.12 последовательный интерфейс #define SKIP_IF_BORROW BTFSC STATUS,C #define SKIP_IF_NOTBORROW BTFSS STATUS,C #define SKIP_IF_CARRY BTFSS STATUS,C #define SKIP_IF_NOTCARRY BTFSC STATUS,C TRIS_PORTC EQU B'00110000' INIT_PORTC EQU B'00111110' ; ¦¦¦¦¦¦ ; ¦¦¦¦¦+------ ; ¦¦¦¦+------- ; ¦¦¦+-------- ; ¦¦+--------- 0 R_OFF ; ¦+---------- 1 INPUT ; +----------- TRIS_PORTB EQU B'00111100' INIT_PORTB EQU B'00000011' ; ¦¦¦ ; ¦¦+------ ; ¦+------- 1 OSER ; +-------- ; SPORTC EQU 08H ; #define FR_OFF SPORTC,3 ; #define FOUTB SPORTC,1 ; #define FOUTA SPORTC,0 ; #define FOUTS SPORTC,2 ; SPORTB EQU 09H ; Предыдущее состояние PORTB #define FOSER SPORTB,1 #define FOTEST SPORTB,0 COUNT EQU 0AH ; Счетчик общего назначения COUNT2 EQU 0BH ; Счетчик общего назначения 2 TMP1 EQU 0CH ; Регистр общего назначения SYSSTATE EQU 0DH ; Состояние главного процесса ; XXXXXXXX ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+------ \ Состояние главного процесса ; ¦¦¦¦¦¦+------- / ; ¦¦¦¦¦+-------- 1 - Цикл приема кода, 0 - цикл обработки событий ; ¦¦¦¦+--------- 1 - Код принят ; ¦¦¦+---------- ; ¦¦+----------- ; ¦+------------ ; +------------- #define FPROC SYSSTATE,2 ; Идентификатор текущего процесса #define FACCEPT SYSSTATE,3 ; Флаг принятого кода COD1 EQU 10H ; Буфер принимаемого кода COD2 EQU 11H ; COD3 EQU 12H ; COD4 EQU 13H ; COD5 EQU 14H ; COD6 EQU 15H ; COD7 EQU 16H ; COD8 EQU 17H ; ; TIMRH EQU 18H ; Таймер включения считывателя кода TIMRL EQU 19H ; ORG 0000 BEGIN: MOVWF OSCCAL CLRF FSR MOVLW TRIS_PORTC ; Назначение направления портов TRIS PORTC ; MOVLW INIT_PORTC MOVWF PORTC MOVWF SPORTC MOVLW TRIS_PORTB ; Назначение направления портов TRIS PORTB ; MOVLW INIT_PORTB MOVWF PORTB MOVWF SPORTB MOVLW B'11000111' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- PS0 предварительный делитель для WDT или T0 ; ¦¦¦¦¦¦+-- PS1 ( 256 ) ; ¦¦¦¦¦+--- PS2 ; ¦¦¦¦+---- PSA 1 - предварительный делитель для WDT иначе для T0 ; ¦¦¦+----- T0SE 1 - внешнее тактирование по спаду иначе по нарастанию ; ¦¦+------ T0CS 1 - тактирование по внешнему входу иначе по частоте Fosc/4 ; ¦+------- GPPU 0 - разрешение режима PULL-UP на выв GP0,GP1,GP3 ; +-------- GPWU 0 - разрешение режима WAKE-UP на выв GP0,GP1,GP3 ; ; После предделителя частота= 4000000/(4*256) = 3906.25 период = 256 мкс ; Переполнение таймера происходит каждые 256*256=65536 мкс и служит ; сигналом к переключению рабочих процессов. ; OPTION CLRF TMR0 ; ; Время процессора разделяется между двумя процессами по 65.536 мс на каждый ; BEGIN_TASKS: BTFSC FPROC ; Переключение между процессами управляется ; флагом FPROC GOTO SYNC_START ; Первый процесс - это непосредственно ; идентификация транспондера BSF STATUS,PA0 GOTO MAIN_PROC ; Второй процесс выполняет остальные действия ; связанные с функциями прибора ;+---------------------------------------------------+ ;¦ Подпрограмма вставки бита ¦ ;+---------------------------------------------------+ INSBIT: ; RLF COD8 ; 1 RLF COD7 ; 1 RLF COD6 ; 1 RLF COD5 ; 1 RLF COD4 ; 1 RLF COD3 ; 1 RLF COD2 ; 1 RLF COD1 ; 1 RETURN ; 2 ---> SUM 10 ;+---------------------------------------------------+ ;¦ Подпрограмма задержки ¦ ;+---------------------------------------------------+ DELAY93uS: MOVLW .22 MOVWF COUNT DEL2: NOP DECFSZ COUNT,F GOTO DEL2 NOP RETURN ;+---------------------------------------------------+ ;¦ Подпрограмма передачи байта ¦ ;+---------------------------------------------------+ SEND_BYTE: MOVLW 8 MOVWF COUNT2 BCF FOSER MOVF SPORTB,W MOVWF PORTB CALL DELAY93uS NOP NOP NOP SBY1: RRF TMP1,F BCF FOSER BTFSC STATUS,C BSF FOSER MOVF SPORTB,W MOVWF PORTB CALL DELAY93uS DECFSZ COUNT2,F GOTO SBY1 BSF FOSER MOVF SPORTB,W NOP NOP NOP NOP MOVWF PORTB CALL DELAY93uS RETURN ;+---------------------------------------------------+ ;¦ Подпрограмма преобразования в ASCII код ¦ ;+---------------------------------------------------+ HEX_ASCII: ANDLW B'00001111' MOVWF TMP1 MOVLW H'0A' SUBWF TMP1,W ; TMP1-A BTFSS STATUS,C GOTO DIG09 DIGAF: MOVLW .55 ADDWF TMP1 RETURN DIG09: MOVLW .48 ADDWF TMP1 RETURN ;+--------------------------------------------------------------------------+ ;¦ Цикл считывания карточки ¦ ;+--------------------------------------------------------------------------+ ; Принимается 128 бит бифазно-модулированного кода (см. описание E5530) ; Код всегда начинается с байта E6h ; ; ; Легче всего определить присутствие на входе информационного сигнала ; по наличию характерного импульса. ; Порядок приема кода ; 64 такта таймера (16мс) на поиск длинного импульса ; ---+ +---- ; ¦ ¦ ; ¦ ¦ ; +--------------+ ; ¦ 252..336 мкс ¦ ; ; Если найти не удалось, то не продолжать прием до следующего включени процесса ; Задний срез длинного импульса является информационным фронтом. ; SYNC_START: BSF FOTEST MOVF SPORTB,W MOVWF PORTB BCF FPROC CLRF COD1 ; Очистить место для принимаемого кода CLRF COD2 ; CLRF COD3 ; CLRF COD4 CLRF COD5 CLRF COD6 CLRF COD7 CLRF COD8 CLRF COUNT MOVLW .63 MOVWF COUNT2 SYNC1: ; Ожидать состояния лог.1 BTFSC INPUT GOTO SYNC2 BTFSS TMR0,7 ; Если истекло 128 такта таймера, ; то прекратить прием GOTO SYNC1 GOTO RECEIPT_END SYNC2: ; Ожидать спада BTFSS INPUT GOTO SYNC3 BTFSS TMR0,7 ; Если истекло 128 такта таймера, ; то прекратить прием GOTO SYNC2 GOTO RECEIPT_END SYNC3: ; Зафиксирован спад. Начало приема длинного импульса ; Ожидать подъём BTFSC INPUT ; 1 GOTO SYNC4 ; 1 INCF COUNT ; 1 BTFSS COUNT,6 ; 1 Если прошло более 64 циклов проверки (64*6=384 мкс), ; то прекратить прием импульса GOTO SYNC3 ; 2 GOTO SYNC_START SYNC4: MOVLW .42 ; 1 SUBWF COUNT,W ; 1 COUNT-42 BTFSS STATUS,C ; 1 GOTO SYNC_START ; 1 Импульс оказался короче 252 мкс. Возврат MOVLW .56 ; 1 SUBWF COUNT,W ; 1 COUNT-56 BTFSC STATUS,C ; 1 GOTO SYNC_START ; 1 Импульс оказался длинее 336 мкс. Возврат ; ; От момента обнаружения окончания импульса прошло 10..16 мкс ; Принят первый бит = 1 ; ; ; До начала основного цикла пропустить 127 мкс ; ; Задержка 127-11=116 мкс MOVLW .38 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 BSF STATUS,C ; 1 RECEIPTBIT: CALL INSBIT ; 12 ; Экспериментальные данные показали наличие временных искажений приходящих ; импульсов, которые имеют хорошую зависимость от предыдущих 2-х переданных ; битов. ; Это было использовано для коректировки моментов считывания состояния ; на входе по экспериментально подобранной таблице. ; Конкретные табличные значения сильно зависят от номиналов элементов ; на схеме и в большинстве случаев не могут быть взяты без изменений. ; ; ; Таблица времменных диапазонов считывания битов ; ; Предыдущие биты Задержка 1 Задержка 2 Задержка 3 ; (до среза) (после среза) (до конца интервала) ; ; 00 64 128 64 ; 01 40 176 40 ; 10 72 112 72 ; 11 32 160 64 ; ; ; Оценить предыдущие биты ; MOVLW B'00000011'; 1 ANDWF COD8,W ; 1 ADDWF PCL ; 2 GOTO PREBIT00 ; 2 SUM 5 GOTO PREBIT01 ; GOTO PREBIT10 ; GOTO PREBIT11 ; PREBIT00: ; Задержка 64-20=44 мкс MOVLW .14 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 CLRF TMP1 ; 1 ; ; Чтение до фронта ; BSF STATUS,C ; 1 BTFSS INPUT ; 1 BCF STATUS,C ; 1 RLF TMP1 ; 1 Сохранить состояние до фронта ; Задержка 128-4=124 мкс MOVLW .40 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 NOP ; 1 NOP ; 1 ; ; Чтение после фронта ; BSF STATUS,C ; 1 BTFSS INPUT ; 1 BCF STATUS,C ; 1 RLF TMP1 ; 1 Записать состояние после фронта ; Задержка 64-14=50 мкс MOVLW .16 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 GOTO DECODEBIT ; 2 PREBIT01: ; Задержка 40-20=20 мкс MOVLW .6 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 CLRF TMP1 ; 1 ; ; Чтение до фронта ; BSF STATUS,C ; 1 BTFSS INPUT ; 1 BCF STATUS,C ; 1 RLF TMP1 ; 1 Сохранить состояние до фронта ; Задержка 176-4=172 мкс MOVLW .56 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 NOP ; 1 NOP ; 1 ; ; Чтение после фронта ; BSF STATUS,C ; 1 BTFSS INPUT ; 1 BCF STATUS,C ; 1 RLF TMP1 ; 1 Записать состояние после фронта ; Задержка 40-14=26 мкс MOVLW .8 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 GOTO DECODEBIT ; 2 PREBIT10: ; Задержка 72-20=52 мкс MOVLW .16 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 NOP ; 1 CLRF TMP1 ; 1 ; ; Чтение до фронта ; BSF STATUS,C ; 1 BTFSS INPUT ; 1 BCF STATUS,C ; 1 RLF TMP1 ; 1 Сохранить состояние до фронта ; Задержка 112-4=108 мкс MOVLW .35 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 NOP ; 1 ; ; Чтение после фронта ; BSF STATUS,C ; 1 BTFSS INPUT ; 1 BCF STATUS,C ; 1 RLF TMP1 ; 1 Записать состояние после фронта ; Задержка 72-14=58 мкс MOVLW .18 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 NOP ; 1 NOP ; 1 GOTO DECODEBIT ; 2 PREBIT11: ; Задержка 32-20=12 мкс MOVLW .3 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 CLRF TMP1 ; 1 NOP ; 1 ; ; Чтение до фронта ; BSF STATUS,C ; 1 BTFSS INPUT ; 1 BCF STATUS,C ; 1 RLF TMP1 ; 1 Сохранить состояние до фронта ; Задержка 160-4=156 мкс MOVLW .51 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 NOP ; 1 ; ; Чтение после фронта ; BSF STATUS,C ; 1 BTFSS INPUT ; 1 BCF STATUS,C ; 1 RLF TMP1 ; 1 Записать состояние после фронта ; Задержка 64-14=50 мкс MOVLW .16 ; 1 MOVWF COUNT ; 1 DECFSZ COUNT ; 1 GOTO $-1 ; 2 NOP ; 1 GOTO DECODEBIT ; 2 DECODEBIT: MOVLW B'00000011'; 1 ANDWF TMP1,W ; 1 ADDWF PCL ; 2 GOTO SYNC_START ; 2 SUM 5 Если комбинация состояний равна GOTO SETBIT1 ; 00 или 11 то это ошибка и весь GOTO SETBIT0 ; код следует принимать заново GOTO SYNC_START ; SETBIT1: BSF STATUS,C ; 1 DECFSZ COUNT2 ; 1 GOTO RECEIPTBIT ; 2 GOTO SRHEADER SETBIT0: BCF STATUS,C ; 1 DECFSZ COUNT2 ; 1 GOTO RECEIPTBIT ; 2 GOTO SRHEADER ; ; Поиск заголовка ; SRHEADER: MOVLW .64 ; 1 MOVWF COUNT ; 1 SRHEADER1: MOVLW H'E6' ; 1 18*63 = 1134 мкс максимальное время поиска XORWF COD1,W ; 1 BTFSC STATUS,Z ; 1 GOTO HEADER_SEARCHED ; 2 ; Прокрутка буфера на один бит BSF STATUS,C ; 1 BTFSS COD1,7 ; 1 BCF STATUS,C ; 1 RLF COD8 ; 1 RLF COD7 ; 1 RLF COD6 ; 1 RLF COD5 ; 1 RLF COD4 ; 1 RLF COD3 ; 1 RLF COD2 ; 1 RLF COD1 ; 1 DECFSZ COUNT ; 1 GOTO SRHEADER1 ; 2 ; ; Заголовок не найден ; GOTO RECEIPT_END HEADER_SEARCHED: ; ; Здесь должна быть процедура сравнения полученного кода с истинным ; ACCEPT_OK: BSF FACCEPT ; Если код правильный, то выставляется флаг NOT_ACCEPT2: SWAPF COD1,W ; В любом случае полученный код CALL HEX_ASCII ; передается на выход по последовательному CALL SEND_BYTE ; интерфейсу MOVF COD1,W ; CALL HEX_ASCII CALL SEND_BYTE SWAPF COD2,W CALL HEX_ASCII CALL SEND_BYTE MOVF COD2,W CALL HEX_ASCII CALL SEND_BYTE SWAPF COD3,W CALL HEX_ASCII CALL SEND_BYTE MOVF COD3,W CALL HEX_ASCII CALL SEND_BYTE SWAPF COD4,W CALL HEX_ASCII CALL SEND_BYTE MOVF COD4,W CALL HEX_ASCII CALL SEND_BYTE SWAPF COD5,W CALL HEX_ASCII CALL SEND_BYTE MOVF COD5,W CALL HEX_ASCII CALL SEND_BYTE SWAPF COD6,W CALL HEX_ASCII CALL SEND_BYTE MOVF COD6,W CALL HEX_ASCII CALL SEND_BYTE SWAPF COD7,W CALL HEX_ASCII CALL SEND_BYTE MOVF COD7,W CALL HEX_ASCII CALL SEND_BYTE SWAPF COD8,W CALL HEX_ASCII CALL SEND_BYTE MOVF COD8,W CALL HEX_ASCII CALL SEND_BYTE MOVLW H'0D' MOVWF TMP1 CALL SEND_BYTE MOVLW H'0A' MOVWF TMP1 CALL SEND_BYTE RECEIPT_END: MOVF TMR0,W ; Дождаться окончания интервала времени BTFSS STATUS,Z ; отведенного процессу идентификации GOTO $-2 ; GOTO BEGIN_TASKS ; ORG 200 ;+--------------------------------------------------------------------------+ ;¦ Основной процесс устройства ¦ ;+--------------------------------------------------------------------------+ MAIN_PROC: BSF FPROC ; ; Здесь программируются задачи связанные с основной функциональностью ; прибора ; BCF FACCEPT CLRF COUNT ; Дополнительная задержка 256*3=768 мкс DECFSZ COUNT ; GOTO $-1 MOVF TMR0,W BTFSS STATUS,Z GOTO $-2 BCF STATUS,PA0 GOTO BEGIN_TASKS END