; ; "mlan_3a.txt" файл обработчика шины microLAN ; под магистральный адаптер, обеспечивающий подтяжку к +5 и к GND ; с модулем обработки CRC8 ; ; заготовка для работы с DS18...20 или аналогичныой ИС ; используются акумулятор ; и регистры текущего РБ ; ;------------------------------------------------------ ; используется "паразитное питание" посредством сигнала L_APD=0 ; при активации портов модуля соблюдать последовательность: ; установить комбинацию в порту, обеспечивающем выходной сигнал ; L_APU=1, L_APD=0 и M_DAT=1 ; перевести порт в режим вывода данных по L_APU и L_APU ; и ввода данных по M_DAT ; выдать L_APU=0 (подать питание на шину "паразитки") ; ;------------------------------------------------------ ; ; ------------ константы ------------ ; ; tm20 equ 7 ; tm26 equ 9 ; tm46 equ 16 ; tm80 equ 27 ; tm86 equ 29 ; tm400 equ 134 ; tm480 equ 161 ; константы из соображений 1 цикл=1uS ; m_cfg9 equ 0b00011111 ; разрешение 9 бит, время преобразования 93,75 mS ; m_cfg10 equ 0b00111111 ; разрешение 10 бит, время преобразования 187,5 mS ; m_cfg11 equ 0b01011111 ; разрешение 11 бит, время преобразования 375 mS ; m_cfg12 equ 0b01111111 ; разрешение 12 бит, время преобразования 750 mS ; mk_conv_t equ 0x44 ; (CONVERT T) команда запуска преобразования температуры ; mk_rd_spad equ 0xBE ; (READ SCRATCHPAD) команда чтения "блокнота" из DS18B20 ; mk_wr_spad equ 0x4E ; (WRITE SCRATCHPAD) команда записи Th:Tl:Config в блокнот DS18B20 ; mk_wr_eep equ 0x48 ; (COPY SCRATCHPAD) команда записи Th:Tl:Config ; ; из блокнота DS18B20 в EEPROM DS18B20 ; mk_rd_eep equ 0xB8 ; (RECALL E2) команда чтения Th:Tl:Config ; ; из EEPROM DS18B20 в блокнота DS18B20 ; mk_scip_rom equ 0xCC ; (SKIP ROM) команда "не выполнять персональную адресацию" ; ; применяется преамбулой во всех блоках обмена при одиночном ; ; датчике ; mk_read_rom equ 0x33 ; (READ ROM) чтение из DS18B20 группового кода изделия ; ; и индивидуального номера ( пакет из 8 байт в составе ; ; байт family code, 6 байт serial number и байт CRC ) ; ; M_DAT equ 2 ; (0) позиционный номер линии данных ; L_APU equ 1 ; (1) позиционный номер линии APU ; L_APD equ 0 ; (3) позиционный номер линии APD ; flags ; m_erd equ 0 ; флаг ошибки "линия mLAN не отвечает" ; ; в области флагов ошибок ; m_ecrc equ 1 ; флаг ошибки при проверке CRC кода пакета mLAN ; ; в области флагов ошибок ; ; --- регистры GPR --- ; область udata_ovr или прерприсвоение как #define nameX nameY ; gradus_l equ tmp_0 ; младший байт текущей температуры ; gradus_h equ tmp_1 ; старший байт текущей температуры ; th_us1 equ tmp_2 ; уставка термостата максимальный порог/пользовательский байт ; tl_us2 equ tmp_3 ; уставка термостата минимальный порог/пользовательский байт ; m_cfg equ tmp_4 ; байт конфигурации датчика DS18B20 ; m_res0 equ tmp_5 ; резерв, всегда 0xFF ; m_res1 equ tmp_6 ; резерв, всегда 0x0C ; m_res2 equ tmp_7 ; резерв, всегда 0x10 ; m_crc equ tmp_8 ; контрольная сумма пакета ; m_data equ tmp_9 ; буфер данных для приема/передачи ; m_cntp equ tmp_a ; счетчик длины пакета ; m_cntb equ tmp_b ; счетчик бит приемника/передатчика байта ; m_mcntt equ tmp_c ; счетчик задержки (djnz cntt_mlan,$ = 2машинных цикла) ; m_flags equ tmp_d ; флаги обработчиков uLAN ; m_tmp_fsr equ tmp_e ; РВХ содержимого fsr на время выполнения модулей m_ ; m_summ equ tmp_f ; накопитель результата в расчете CRC ; m_tmp ; времянка ; port_m equ PORTA ; () переприсвоение порта ; ;------------------------------------------------------------------------ ; MN CODE ; ;--------------------------------------- ; DTTC - генератор импульса reset термодатчика и проверка импульса ; "присутствия" m_dttc bsf port_m,L_APU ; отключить паразитку bcf m_flags,m_erd nop nop nop bsf port_m,L_APD ; активировать уровень запроса movlw tm480 movwf m_mcntt tmm0 decfsz m_mcntt,f goto tmm0 ; ждем завершение импульса запроса 480uS bcf port_m,L_APD ; отключить L_APD nop nop nop movlw .26 ; линия M_DAT подключена к + через подтяжку в 2килоома movwf m_cntb ; периодический опрос линии M_DAT через 20uS в течении 480uS m_tstpp movlw tm20 movwf m_mcntt m_tstpp1 decfsz m_mcntt,f goto m_tstpp1 btfss port_m,M_DAT ; ждем состояние M_DAT=0 goto wait_mdh decfsz m_cntb,f goto m_tstpp bsf m_flags,m_erd ; если за весь период опросов ответа нет - m_erd=1 wait_mdh btfss port_m,M_DAT ; ждем окончание ответа датчика (M_DAT=1) goto wait_mdh bcf port_m,L_APU ; восстановить паразитку movlw tm400 movwf m_mcntt ; ждем защитный интервал 400uS tmm1 decfsz m_mcntt,f goto tmm1 return ; ;--------------------------------------- ; ; приемник байта в стандарте сетей microLAN ; вызов call rxb1 ; по выходу принятый байт в регистре m_data m_rxb1 bsf port_m,L_APU ; отключить паразитку nop nop movlw 8 movwf m_cntb rexik bsf port_m,L_APD ; активировать уровень запроса movlw 4 movwf m_mcntt tmm2 decfsz m_mcntt,f goto tmm2 bcf port_m,L_APD ; деактивировать уровень запроса movlw 3 movwf m_mcntt tmm2a decfsz m_mcntt,f goto tmm2a bcf STATUS,C btfsc port_m,M_DAT bsf STATUS,C rrf m_data,f movlw tm46 movwf m_mcntt tmm3 decfsz m_mcntt,f goto tmm3 decfsz m_cntb,f goto rexik bcf port_m,L_APU ; восстановить паразитку nop nop return ; ;--------------------------------------- ; ; передатчик байта в стандарте сетей microLAN ; перед вызовом передаваемый байт разместить в m_data ; вызов call txb1 m_txb1 bsf port_m,L_APU ; отключить паразитку nop nop movlw 8 movwf m_cntb texik bsf port_m,L_APD ; активировать уровень запроса movlw 4 movwf m_mcntt tmm4 decfsz m_mcntt,f goto tmm4 rrf m_data,f btfsc STATUS,C ; исходно было L_APD=1 (M_DAT=STATUS.C=0) bcf port_m,L_APD ; передача M_DAT=1 если STATUS.C=1 (L_APD=0) movlw tm46 movwf m_mcntt tmm5 decfsz m_mcntt,f goto tmm5 ; ждем ~45uS bcf port_m,L_APD ; восстановить L_APD=0 nop nop decfsz m_cntb,f goto texik bcf port_m,L_APU ; восстановить паразитку nop nop return ; ;--------------------------------------- ; ; CRC - КОНТРОЛЬ для пакета из 9 байт (8 данных+CRC) ; или 8 байт - модуль расчета задается в макросе вызова ; блок данных предварительно размещается в tmp_0-tmp_8 РПД ; исходные данные НЕ РАЗРУШАЮТСЯ! m_crck_id movlw 8 goto m_crck2 m_crck movlw 9 m_crck2 movwf m_cntp ; счетчик бит равен 9 (или 8 для ИД кода) bcf m_flags,m_ecrc ; сброс флага ошибки movf FSR,w movwf m_tmp_fsr ; храним текущий FSR movlw gradus_l ; указатель на начало массива блокнота movwf FSR clrf m_summ ; очистить накопитель результата l_crc1 movlw 8 movwf m_cntb ; счетчик бит =8 movf INDF,w ; читаем текущий байт данных в W movwf m_data ; и копируем его же в m_data l_crc2 xorwf m_summ,w ; xor битов 0, результат в w movwf m_tmp ; передано во времянку rrf m_tmp,f ; и результат xor битов 0 накопителя и текущих данных ; передан в С btfss STATUS,C ; в зависимости от результата по биту 0 goto p_crc1 ; или уходим в завершение movlw 0x18 xorwf m_summ,f ; или ксорим второй узел p_crc1 rrf m_summ,f ; результат сдвигаем вправо с учетом С rrf m_data,f ; кольцевой сдвиг исходных данных, ; что поступило в старший бит безразлично movf m_data,w ; передали в W (с копией в m_data) decfsz m_cntb,f ; счетчик бит данных - 1 goto l_crc2 ; продолжить от l_crc2 если m_cntb не равен 0 incf FSR,f ; продвижка указателя decfsz m_cntp,f ; счетчик байт - 1 goto l_crc1 ; продолжить от l_crc1 до исчерпания массива tstf m_summ ; если CRC правильна в накопителе 0 btfss STATUS,Z bsf m_flags,m_ecrc ; если m_summ не равно 0 установить m_ecrc=1 movf m_tmp_fsr,w movwf FSR ; восстановим FSR перед выходом return ; ;--------------------------------------- ; ; командный пакет запуска преобразования ; term_strt call m_dttc movlw mk_scip_rom movwf m_data call m_txb1 movlw mk_conv_t movwf m_data call m_txb1 return ; ;--------------------------------------- ; ; командный пакет чтения текущих данных блокнота ; m_rd9 movf FSR,w movwf m_tmp_fsr ; храним текущий FSR movlw 9 movwf m_cntp movlw gradus_l movwf FSR call m_dttc movlw mk_scip_rom movwf m_data call m_txb1 movlw mk_rd_spad movwf m_data call m_txb1 l_rd9 call m_rxb1 movf m_data,w movwf INDF incf FSR,f decfsz m_cntp,f goto l_rd9 movf m_tmp_fsr,w movwf FSR ; восстановим FSR перед выходом return ; ;--------------------------------------- ;