;****************************************************************************** ; Filename: 1-Wire_Task.asm * ; Date: 15/12/2015 * ; File Version: 000.001 * ; Author: PSW.RU * ; Company: Labs * ;****************************************************************************** ; * ; Files required: P18F4431.INC, Pic18_M.INC,LCD_Text.asm * ; * ;****************************************************************************** #include Define.inc ;Определения Констант и переменных для модуля ; набор шагов в реализации протокола 1-Wire с аппаратными задержками на таймере-0 ; прескалер 1/4, такт задержки = 1/3 мкс, все цифры микросекунд умножаем на 3 ;***************************************************************************** #ifdef W1_Pin ; Самый глобальный переклюк - можно не убирать файл из проекта ; при убирании подсистемы из AddIncludeFiles.bat ;***************************************************************************** #include Proj_Dir\1W\1-Wire_Task_M.inc ;Макро для модуля вынес - разрослись ;extern T5_R1,T5_R2,T5_R3,T5_R4; extern InitAll,CaseBra;Table_1W;CalcCRC, global W1_Task W1_Task code W1_Task W1_Page ; movlb 0x0 ; BSR на Банк0 для StepTask movlf MaxW1Pointer,W1_Temp,BANKED; - GoToWreg,BANKED ; Макс значение вычисляемого перехода movf W1_Route,W,BANKED ; ;bz DoneW1_Task ; Начало алгоритма - нулевой указатель "проги" 1-Wire cpfsgt W1_Temp,BANKED ; (f) - (WREG) skip if (f) > (WREG); (unsigned comparison) retlw 0x0 ;bra DoneW1_Task ; Указатель больше максимума - без перехода ; GoToWreg 1,W1_Temp,BANKED ; NumShiftWreg,TempBuff,Adr1 Переход на смещение из WREG, 1 раз сдвиг - ; Разверну макрос для макс быстродействия. BraReg W1_Route,BANKED ;;BraReg macro RegPoint,Adr1 ; смещение номера БРА - в регистре ;rcall CaseBra ; Смещение в WREG - Опробуем новую саб прогу - работает тоже ; массив команд по 2 байта типа BRA или RETLW. BRA шагает на +/- 1024 команд, сложно не достать. ; условные БРА шагают на +/- 127 команд. #include Proj_Dir\1W\1-Wire_Task.INC ; Описание шагов реализации протокола Step_0 ; .if Debug_1W == 0; При отладке наличие датчика не опрашивается ;************** ; btfsc W_1_Flg,4,ACCESS ; Строка напечатана ? ; retlw 0x0 ; Ждём печати выданной строки ;************** ; .else .endif #ifdef LCD_Present movff KeyBuf,W1_KeyBuf ; Буфер кейбуфера для единой клавы на весь проход алгоритма #endif ; btfsc W1_KeyBuf,7,0 ; Ожидаем нажатие правой кнопы ; retlw 0x0 ; ;Тут будет переключатель выбора алгоритмов через выбор начальных шагов movf W1_AlgRoute,W,BANKED ; Указатель алгоритма, 0= модуль 1-варе висит ;6=скачок к первому шагу нулевого алгоритма минуя нулевой шаг - должно глючить addwf W1_Route,F,BANKED ;Переходим к выбранному алгоритму ;incf W1_Route,F,BANKED ;Переходим к следующему шагу retlw 0x0 ; Переход после опроса других задач ; Первая цель - бесконечный опрос температуры единственного датчика 1-варе, при нажатии правой кнопы ; бесконечное чтение номера единственного датчика 1-варе ; Вторая цель - Бесконечное чтение датчиков по известным номерам в таблице, с размещением результата в ОЗУ согласно порядка перечисления номеров ; Третья цель - бесконечный опрос всех имеющихся датчиков на шине используя "поискром" и чтение температуры с всех датчиков с обнаруженными номерами ; Четвёртая-Пятая цель - ХЗ что, прозапас. ; Итого реальные "проги" начинаются с шага 6. Подпрограммы - с шага 34 Step1 ; это бывший шаг-0 - чтение температуры единственного датчика movlf d'6',W1_Convert_Return,BANKED ; Возврат из п/п movlw DS1820_SKIP_ROM ;; Запись команды SKIP_ROM btfss W1_KeyBuf,7,BANKED ; Ожидаем нажатие правой кнопы movlw DS1820_READROM ;; Запись команды READROM если кнопа нажата ; retlw 0x0 ; ; bra Done_Step_6 ; температура ; bra ReadBufCircle ; серийник movwf W_1_CmdBuf,BANKED ; Запись команды сразу после ВТОРОГО сброса bra Step_40 ; к п/п сброса/записи/конвертации/ожидания/сброса/записи ;retlw 0x0 ;********* Количество и Номера датчиков берутся из таблицы Table_1W Step2 ; это шаг-0 для опроса датчиков с известными номерами ;incf W1_Route,F,BANKED ;Переходим к следующему шагу movlf d'10',W1_Convert_Return,BANKED ; Возврат из п/п 40 movlf DS1820_MATCHROM,W_1_CmdBuf,BANKED ; Запись команды Матч_ROM сразу после ВТОРОГО сброса в пп40 ; Организуем циклер опроса датчиков. При опросе каждого датчика буфер адреса меняется на буфер скратчпада rcall Read_1W_Table ; Инициализируем количество датчиков в W1_Sensor_Count, указатели на таблицы lfsr 0, DS1820_ScratctPad1 ; Будет использоваться при переносе части байт темп из записнухи в выходной буфер movff16 FSR0L,ScratctPad_Ptr1; Запоминаем начальное состояние указателя строки измеренных температур bra Step_40 ; к п/п конвертации и начала опроса 1-варе Step_3 ; Отладочная ветка, циклический сброс шины ;movlf d'41',W1_Route,BANKED ;Переходим к шагу 41 в случае чего clrf W_1_ReadBuf,ACCESS ; В приёмном буфере будет "презенс". ;movlf DS1820_SKIP_ROM,W_1_WriteBuf,BANKED ; Запись команды SKIP_ROM сразу после сброса ;movlf d'41',W1_Write_Return,BANKED ; Сохраняем адрес возврата после записи - шаг №41 movlf d'0',W1_Drv_Return,BANKED ; Сохраняем адрес возврата после сброса - запись bra Step_36 ; к процедуре сброса 1-варе clrf W1_Route,BANKED ;сброс и бесконечный циклер retlw 0x0 Step_4 ;; Отладочная ветка, сброс, запись и чтение байта ;movlf d'41',W1_Route,BANKED ;Переходим к шагу 41 в случае чего ;clrf W_1_ReadBuf,ACCESS ; В приёмном буфере будет "презенс". ;movlf DS1820_SKIP_ROM,W_1_WriteBuf,BANKED ; Запись команды SKIP_ROM сразу после сброса movlf DS1820_READ_SCRATCHPAD,W_1_WriteBuf,BANKED ; пишем команду читать записнуху movlf d'0',W1_Read_Return,BANKED ; адрес "возврата" после п/п чтения байта - сброс проги movlf d'34',W1_Write_Return,BANKED ; Сохраняем адрес возврата после записи - чтение movlf d'35',W1_Drv_Return,BANKED ; Сохраняем адрес возврата после сброса - запись bra Step_36 ; к процедуре сброса 1-варе clrf W1_Route,BANKED ;сброс и бесконечный циклер retlw 0x0 Step_5 ;; Отладочная ветка, запись, чтение, movlf DS1820_READROM,W_1_WriteBuf,BANKED ; Запись команды movlf d'0',W1_Read_Return,BANKED ; адрес "возврата" после п/п чтения байта - сброс проги movlf d'34',W1_Write_Return,BANKED ; Сохраняем адрес возврата после записи - чтение bra Step_35 ; к процедуре записи 1-варе clrf W1_Route,BANKED ;сброс и бесконечный циклер movlf d'41',W1_Route,BANKED ;Переходим к шагу 41 в случае чего clrf W_1_ReadBuf,ACCESS ; В приёмном буфере будет "презенс". movlf DS1820_SKIP_ROM,W_1_WriteBuf,BANKED ; Запись команды SKIP_ROM сразу после сброса movlf d'41',W1_Write_Return,BANKED ; Сохраняем адрес возврата после записи - шаг №41 movlf d'35',W1_Drv_Return,BANKED ; Сохраняем адрес возврата после сброса - запись bra Step_36 ; к процедуре сброса 1-варе clrf W1_Route,BANKED ;сброс и бесконечный циклер retlw 0x0 Step_6 ; Запись команды CONVERT_T или команды READ_SCRATCHPAD - по переклюку movff W_1_ReadBuf,W1_Rx_Byte ; Буферизуем "презенс", анализ тоже .if Debug_1W == 0; При отладке наличие датчика не опрашивается btfss W_1_ReadBuf,7,ACCESS ; Датчик присоединён ? bra SensorNotPresent ; .else .endif ;****;*** В зависимости от необходимости - температура или серийник btfsc W1_KeyBuf,7,BANKED ; Ожидаем нажатие правой кнопы ; retlw 0x0 ; bra Done_Step_6 ; температура bra Step_7 ; серийник SensorNotPresent ; Датчик не выставил "презенс" после сброса, новый сброс. bcf W_1_Flg,2,ACCESS ; По сбросу флаги в нуле были clrf W1_Route,BANKED ;После чтения - сброс и бесконечный циклер bsf W_1_Flg,0,ACCESS ; Модуль 1-Wire требует проца movlf 0xA5,DS1820_ScratctPad+1,BANKED movlf 0x5A,DS1820_ScratctPad,BANKED retlw 0x0 ; новый сброс 1-варе после опроса других задач Done_Step_6 incf W1_Route,F,BANKED ;Переходим к следующему шагу movff W1_Route,W1_Write_Return ; Сохраняем адрес возврата - след шаг movlf DS1820_READ_SCRATCHPAD,W_1_WriteBuf,BANKED ; пишем команду читать записнуху bra Step_35 ; к процедуре записи байта 1-варе Step_7 btfsc W_1_Flg,3,ACCESS ; Первый вызов или возврат из обработчика ? bra NextByteRead ; bsf W_1_Flg,3,ACCESS ; Первый вызов, организуем циклер на чтение 8 байт clrf DS1820_CRC,BANKED ; Чистим CRC movlf d'7',W1_Read_Return,BANKED ; адрес "возврата" после п/п чтения байта ;****;*** В зависимости от необходимости - температура или серийник movlw d'9' ;; Температура - читаем 9 байт btfss W1_KeyBuf,7,BANKED ; Ожидаем нажатие правой кнопы movlw d'8' ;; серийник - читаем 8 байт movwf W1_Byte_Count,BANKED ; Запись команды сразу после ВТОРОГО сброса lfsr 0, DS1820_ScratctPad movff16 FSR0L,ScratctPad_Ptr; Запоминаем новое состояние указателя строки bra Step_34 ; к процедуре чтения байта 1-варе NextByteRead movff16 ScratctPad_Ptr,FSR0L; Берем запомненный указатель строки в ОЗУ movff W_1_ReadBuf,POSTINC0; Переносим принятый 1-В байт в буферок movff16 FSR0L,ScratctPad_Ptr; Запоминаем новое состояние указателя строки decfsz W1_Byte_Count,F,BANKED ; Конец байтам ? bra Step_34 ; к процедуре чтения байта 1-варе ;bra AllByteRead AllByteRead ; Форматация десятичного значения темп тут теперь ; Если контрольная сумма сошлась tstfsz DS1820_CRC,BANKED ; incf DS1820_Err_CRC,F,BANKED ; tstfsz DS1820_CRC,BANKED ; ; movf DS1820_CRC,W,BANKED ; Выставляем флаг Z в соответствии с CRC bra SkipTempConversion ; Если не ноль - десятичная темп не обновляется LED1_Toggle ; btg FotoFire ; Красный СД жгём btg Debug_LED ; rcall TempBCD ; Код вынес в сабпрогу, преобразование при печати теперь SkipTempConversion clrf W1_Route,BANKED ;После чтения - сброс и бесконечный циклер bcf W_1_Flg,2,ACCESS ; Начинаем с команды "конверт". bcf W_1_Flg,1,ACCESS ; Битовый счётчик тоже с нуля. bsf W_1_Flg,0,ACCESS ; Модуль 1-Wire требует проца bcf W_1_Flg,3,ACCESS ; Первый вызов будет чтения многобайтов bsf W_1_Flg,4,ACCESS ; Строка НЕ напечатана retlw 0x0 ; новый сброс 1-варе после опроса других задач retlw 0x0 Step_10 ; Организация циклера записи адреса в шину ; анализ наличия тут не работает - виснет ; .if Debug_1W == 0; При отладке наличие датчика не опрашивается ; btfss W_1_ReadBuf,7,ACCESS ; Датчик присоединён ? ; bra SensorNotPresent ;; .else ; .endif ; incf W1_Route,F,BANKED ;Переходим к следующему шагу rcall Read_1W_Table ; Читаем номер в буфер записнухи, количество уже в W1_Sensor_Count movlf d'8',W1_Byte_Count,BANKED; Количество байт записи адреса lfsr 0, DS1820_ScratctPad ; Инициализируем буфер адреска movff POSTINC0,W_1_WriteBuf ; Первый байт адреска в буфер записи movff16 FSR0L,ScratctPad_Ptr; Запоминаем новое состояние указателя строки movff W1_Route,W1_Write_Return ; Сохраняем адрес возврата - след шаг bra Step_35 ; к процедуре записи первого байта адреса 1-варе ; retlw 0x0 Step_11 ; Тело циклера записи адреса в шину movff16 ScratctPad_Ptr,FSR0L; Берем запомненный указатель строки в ОЗУ movff POSTINC0,W_1_WriteBuf ; Новый байт адреска в буфер записи movff16 FSR0L,ScratctPad_Ptr; Запоминаем новое состояние указателя строки decfsz W1_Byte_Count,F,BANKED ; Конец байтам ? bra Step_35 ; к процедуре записи байта адреса 1-варе ; Весь адрес записан в шину, писать команду чтения записнухи и читать саму записнуху incf W1_Route,F,BANKED ;Переходим к следующему шагу movff W1_Route,W1_Read_Return ; Сохраняем адрес возврата после чтения - след шаг movlf d'34',W1_Write_Return,BANKED; Сохраняем адрес возврата после записи - чтение первого байта movlf DS1820_READ_SCRATCHPAD,W_1_WriteBuf,BANKED ; пишем команду читать записнуху movlf d'9',W1_Byte_Count,BANKED; Количество байт чтения записнухи clrf DS1820_CRC,BANKED ; Чистим CRC lfsr 0, DS1820_ScratctPad ; указатель в начало буфера записнухи movff16 FSR0L,ScratctPad_Ptr; Запоминаем новое состояние указателя строки bra Step_35 ; к процедуре записи байта 1-варе ; retlw 0x0 Step_12 ; циклер чтения байт из записнухи movff16 ScratctPad_Ptr,FSR0L; Берем запомненный указатель строки в ОЗУ movff W_1_ReadBuf,POSTINC0; Переносим принятый 1-В байт в буферок movff16 FSR0L,ScratctPad_Ptr; Запоминаем новое состояние указателя строки decfsz W1_Byte_Count,F,BANKED ; Конец байтам ? bra Step_34 ; к процедуре чтения байта 1-варе ;AllByteRead ;btg FotoFire ; Красный СД жгём btg Debug_LED movff16 ScratctPad_Ptr1,FSR0L; Восстанавливаем состояние указателя строки измеренных температур ;каждый датчик должен оставить одинаковое количество байт в этом буфере movf DS1820_CRC,W,BANKED ; Выставляем флаг Z в соответствии с CRC bnz SkipCopyTemp ; Если не ноль - темп в буфере не обновляется movff DS1820_ScratctPad,POSTINC0 ; Первый байт темпы movff DS1820_ScratctPad+1,POSTINC0; Второй байт темпы LED1_Toggle ;***************** Debug_LED bra NewSens SkipCopyTemp movf POSTINC0,W,ACCESS ; пропускаем пару байт movf POSTINC0,W,ACCESS ; десятичного значения темпы NewSens movff16 FSR0L,ScratctPad_Ptr1; Запоминаем состояние указателя строки измеренных температур dcfsnz W1_Sensor_Count,F,BANKED ; bra AllTempGet ;Step_13 ;NewSens1 ; переход к циклеру датчиков NewSens1 ; Сброс, мачром, к шагу 10 ; Без сброса - не работает, проверил clrf W_1_ReadBuf,ACCESS ; В приёмном буфере будет "презенс". movlf DS1820_MATCHROM,W_1_WriteBuf,BANKED ;Запись указанной команды ROM сразу после сброса movlf d'10',W1_Write_Return,BANKED;адрес возврата после записи команды - шаг №10, запись адреса movlf d'35',W1_Drv_Return,BANKED ;адрес возврата после сброса - запись bra Step_36 ; к процедуре сброса 1-варе ; ********** Кажется здесь обработаны все датчики ********************* AllTempGet ; ; Beeper d'2'; Голос #include Proj_Dir\1W\1-W_Temp.inc ;Обработка полученных температур ; ********** Конец кода реагирования на опрос всех датчиков *********** Step_13 movlf d'13',W1_Route,BANKED ;Ставим адрес для возврата сюда при ожидании ;Все датчики прочитаны, ждём таймаут замера темпы ;WaitTimeL MACRO Literal8,TimeCounter,Adr0,TimeStamp,Adr1 ; Ждём указанное количество тиков WaitTimeL d'67',Tic_100_Counter,ACCESS,W1_TimeStamp,BANKED,0xE1 clrf W1_Route,BANKED ;После чтения - сброс и бесконечный циклер bcf W_1_Flg,2,ACCESS ; Инициализация счётчика датчиков в п/п Read_1W_Table. bcf W_1_Flg,1,ACCESS ; Битовый счётчик тоже с нуля. bsf W_1_Flg,0,ACCESS ; Модуль 1-Wire требует проца bcf W_1_Flg,3,ACCESS ; Первый вызов будет чтения многобайтов bsf W_1_Flg,4,ACCESS ; Строка НЕ напечатана retlw 0x0 ; новый сброс 1-варе после опроса других задач retlw 0x0 Step_34 ; Вызывается из 2 мест шага 7 и из самой себя ; Чтение байта П/П btfsc W_1_Flg,1,ACCESS ; Первый вызов или возврат из обработчика ? bra NextBitRead ; bsf W_1_Flg,1,ACCESS ; Модуль 1-Wire обрабатывает цикл байта movlf d'8',W1_Bit_Count,BANKED ;счётчик битов инициализируем movlf d'34',W1_Drv_Return,BANKED ; адрес "возврата" после битовой операции bra Step_39 ; Читаем бит, он попадает в старший бит буфера NextBitRead ;ложных проходов быть не должно при подсчёте контрольной суммы ; call CalcCRC ; Процедура проверена на документации и серийнике датчика и чтении скратчпада - работает rrncf DS1820_CRC,F,BANKED ; Вращаем минуя перенос movf DS1820_CRC,W,BANKED ; bcf DS1820_CRC,7,BANKED ; чистим старший (место под результат) xorwf W_1_ReadBuf,W,BANKED; Результат XOR входа и старшего бита CRC ; в старшем бите Акк bnn DoneXor ; Заменил на анализ знакового бита (бит-7) movlw b'10001100' ; ************* То Самое "Представление Полинома" xorwf DS1820_CRC,F,BANKED ; инвертируем старший и серединку DoneXor dcfsnz W1_Bit_Count,F,BANKED ; Конец битам ? bra EndReadByte rrncf W_1_ReadBuf,F,BANKED ; сдвинули буферок вправо, прочитанный бит был в 7 разряде. bra Step_39 ; Читаем бит, он попадает в старший бит буфера EndReadByte bcf W_1_Flg,1,ACCESS ; Модуль 1-Wire закончил цикл байта movf W1_Read_Return,W,BANKED ; Пересылка через movwf W1_Route,BANKED ; WREG необходима bra W1_Task ; Обходим возврат управления ибо нет ожидания bsf W_1_Flg,0,ACCESS ; Модуль 1-Wire требует проца retlw 0x0 Step_35 ; Вызывается из самой себя, из первого, второго и третьего шагов, из п/п 40 ; Запись байта П/П btfsc W_1_Flg,1,ACCESS ; Первый вызов или возврат из обработчика ? bra NextBitWrite ; bsf W_1_Flg,1,ACCESS ; Модуль 1-Wire обрабатывает цикл байта movlf d'9',W1_Bit_Count,BANKED ;счётчик битов инициализируем на единицу больше movlf d'35',W1_Drv_Return,BANKED ; адрес "возврата" после битовой операции NextBitWrite dcfsnz W1_Bit_Count,F,BANKED ; Конец битам ? bra EndWriteByte rrcf W_1_WriteBuf,F,BANKED ; Бит в переносе bc Step_38 ; Пишем единицу bra Step_37 ; Пишем ноль EndWriteByte bcf W_1_Flg,1,ACCESS ; Модуль 1-Wire закончил цикл байта movf W1_Write_Return,W,BANKED ; Пересылка через movwf W1_Route,BANKED ; WREG необходима bra W1_Task ; Обходим возврат управления ибо нет ожидания bsf W_1_Flg,0,ACCESS ; Модуль 1-Wire требует проца retlw 0x0 Step_36 ; Вызывается только из шага №1 и п/п шага 40 ; "Подпрограмма" Reset 1-W. Вызывается из какой-либо иной ветки. ;F-1. Опустить линию, Включить линию, выставить номер 1 ветки прерывания таймера5 ; заслать задержку 480 в таймер/компаратор, №2=70, №3=410, запустить таймер, ; сбросить признак запроса проца обработчиком 1-W, ; выставить номер ветки возврата из 1 уровень "стека" movlf d'1',Int_T5_Route,ACCESS ;выставить номер 1 ветки прерывания таймера5 SetDelay d'480',TMR0L,ACCESS; заслать задержку №1 = 480 в таймер/компаратор SetDelay d'70',Delay_T5_N2,BANKED; заслать задержку №2 = 70 SetDelay d'410',Delay_T5_N3,BANKED; заслать задержку №3 = 410 W1_Begin ;Секция полностью одинакового кода обнаружилась W1_Clear ; Опустить линию .if Debug_1W == 0 ; При отладке .else ; setf PR5H,ACCESS ; Период ; setf PR5L,ACCESS ; чистим ; clrf TMR5H,ACCESS ; Таймер ; clrf TMR5L,ACCESS ; Чистим ; bcf PIE3,TMR5IE,ACCESS ; Прерывание Т5 запрет ; ;incf TMR0L,F,ACCESS; ********* попытка подавить неизвестное прерывание в отладчике .endif ; bcf INTCON,GIEL,ACCESS ; Прерывания низкий приоритет запретить bcf INTCON,GIEH,ACCESS ; Прерывания высокий приоритет запретить W1_Output ; Включить линию, и с гарантированным минимальным интервалом bsf T0CON,TMR0ON,ACCESS ; Запуск отсчёта задержки .if Debug_1W == 0 ; При отладке .else ; bsf T5CON,TMR5ON,ACCESS ; Запуск отсчёта задержки ;bcf PIR3,TMR5IF,ACCESS; ********* Прерывание ложный флаг отладчика сброс - попытка подавить ложное прерывание ; bcf INTCON,TMR0IF,ACCESS ;; Сбрасываем флаг Таймера0 .endif bsf INTCON,GIEH,ACCESS ; Прерывания высокий приоритет разрешить ; bsf INTCON,GIEL,ACCESS ; Прерывания низкий приоритет разрешить bcf W_1_Flg,0,ACCESS ; ***** Модуль 1-Wire НЕ требует проца до завершения цепочки прерываний movff W1_Drv_Return,W1_Route ;; выставить номер ветки возврата из 1 уровень "стека" retlw 0x0 Step_37 ; Вызывается только из шага № ЗаписьБайта ; "Подпрограмма" Write 0 bit Send ‘0’ bit to the 1-Wire slaves. Вызывается из какой-либо иной ветки. ; F-2. Опустить линию, Включить линию, выставить номер 4 ветки прерывания таймера5 ; заслать задержку 60 в таймер/компаратор и задержку №2 (10) в буфер, запустить таймер, ; сбросить признак запроса проца обработчиком проца, ; выставить номер следующей ветки фона (возможно номер ветки возврата из 1 уровень "стека") movlf d'4',Int_T5_Route,ACCESS ;выставить номер 4 ветки прерывания таймера5 SetDelay d'60',TMR0L,ACCESS; заслать задержку №1 = 60 в таймер/компаратор SetDelay d'10',Delay_T5_N2,BANKED; заслать задержку №2 = 10 bra W1_Begin ; Команды начала тайм-слота одинаковы, разные лишь величины задержки Step_38 ; Вызывается только из шага № ЗаписьБайта ;"Подпрограмма" Write 1 bit Send ‘1’ bit to the 1-Wire slaves ;F-3. Опустить линию, Включить линию, выставить номер 4 ветки прерывания таймера5 ; заслать задержку 6 в таймер/компаратор и задержку №2 (64) в буфер, запустить таймер, ; сбросить признак запроса проца обработчиком проца, ; выставить номер следующей ветки фона (возможно номер ветки возврата из 1 уровень "стека") movlf d'4',Int_T5_Route,ACCESS ;выставить номер 4 ветки прерывания таймера5 SetDelay d'6',TMR0L,ACCESS; заслать задержку №1 = 6 в таймер/компаратор SetDelay d'64',Delay_T5_N2,BANKED; заслать задержку №2 = 64 bra W1_Begin ; Команды начала тайм-слота одинаковы, разные лишь величины задержки Step_39 ; Вызывается из шага "ЧтениеБайта" ; и "ОпросЗанятости" после записи команды, п/п 40 2 раза ; "Подпрограмма" Read bit Read a bit from the 1-Wire slaves (Read time slot) ;F-4. Опустить линию, Включить линию, выставить номер 1 ветки прерывания таймера5 ; заслать задержку 6 в таймер/компаратор, №2=9, №3=55, запустить таймер, ; сбросить признак запроса проца обработчиком проца, ; выставить номер следующей ветки фона (возможно номер ветки возврата из 1 уровень "стека") movlf d'1',Int_T5_Route,ACCESS ;выставить номер 1 ветки прерывания таймера5 SetDelay d'6',TMR0L,ACCESS; заслать задержку №1 = 6 в таймер/компаратор SetDelay d'9',Delay_T5_N2,BANKED; заслать задержку №2 = 9 SetDelay d'55',Delay_T5_N3,BANKED; заслать задержку №3 = 55 bra W1_Begin ; Команды начала тайм-слота одинаковы, разные лишь величины задержки Step_40 ; п/п сброс, запись "скипРом", запись "конверт", ожидание готовности датчиков, ; второй сброс, вторая команда ROM из буфера W_1_CmdBuf. Шаги экономить нет смысла. movlf d'41',W1_Route,BANKED ;Переходим к шагу 41 в случае чего clrf W_1_ReadBuf,ACCESS ; В приёмном буфере будет "презенс". movlf DS1820_SKIP_ROM,W_1_WriteBuf,BANKED ; Запись команды SKIP_ROM сразу после сброса movlf d'41',W1_Write_Return,BANKED ; Сохраняем адрес возврата после записи - шаг №41 movlf d'35',W1_Drv_Return,BANKED ; Сохраняем адрес возврата после сброса - запись bra Step_36 ; к процедуре сброса 1-варе Step_41 movff W_1_ReadBuf,W1_Rx_Byte ; Буферизуем "презенс", анализ тоже .if Debug_1W == 0; При отладке наличие датчика не опрашивается btfss W_1_ReadBuf,7,ACCESS ; Датчик присоединён ? ; .else .endif ; nop ;****************** заткнул занятость ;****;*** В зависимости от необходимости - температура или серийник bra Done_Step_41 ;bra ReadBufCircle ; ; Датчик не выставил "презенс" после сброса, новый сброс. bcf W_1_Flg,2,ACCESS ; По сбросу флаги в нуле были clrf W1_Route,BANKED ;После чтения - сброс и бесконечный циклер bsf W_1_Flg,0,ACCESS ; Модуль 1-Wire требует проца movlf 0xA5,DS1820_ScratctPad+1,BANKED movlf 0x5A,DS1820_ScratctPad,BANKED retlw 0x0 ; новый сброс 1-варе после опроса других задач Done_Step_41 ;btg FotoFire ; Красный СД жгём btg Debug_LED movlf DS1820_CONVERT_T,W_1_WriteBuf,BANKED ; Запись команды Конверт сразу после СкипРом movlf d'42',W1_Write_Return,BANKED ; Сохраняем адрес возврата после записи - след шаг №42 ; clrf W_1_ReadBuf,ACCESS ; В приёмном буфере ставим "занятость" - не опрашиваем. movff Tic_100_Counter,W1_TimeStamp; Засекаем время в 1/100 сек bra Step_35 ; к процедуре записи байта Step_42 ; .if Debug_1W == 0; При отладке наличие датчика не опрашивается ; btfsc W_1_ReadBuf,7,ACCESS ; Датчик занят ? ; ;.else ; .endif ; nop ;***************** заткнули опрос занятости ; bra Done_Step_42 ; movlf d'42',W1_Drv_Return,BANKED ; Сохраняем адрес возврата после чтения бита - этот шаг ; bra Step_39 ; Читаем бит "занятости", он попадает в старший бит буфера ; Done_Step_42 ; movff TicsCounter,W1_TimeStamp ; Засекаем время в 1/200 сек ;clrf W1_Route,BANKED ;После чтения - сброс и бесконечный циклер clrf W_1_ReadBuf,ACCESS ; В приёмном буфере будет "презенс". movff W_1_CmdBuf,W_1_WriteBuf;,BANKED ; Запись указанной команды ROM сразу после сброса movff W1_Convert_Return,W1_Write_Return;,BANKED ; Сохраняем адрес возврата после записи - шаг №40 movlf d'35',W1_Drv_Return,BANKED ; Сохраняем адрес возврата после сброса - запись bra Step_36 ; к процедуре сброса 1-варе ; ******** Перенесено из включаемого файла на время отладки ;TempBCD ;преобразование младшего байта темп к десятичному виду ;; теперь происходит при печати. Экономия памяти - храним только двоичное значение температуры ;; При отрицательной темп надо дробную часть дополнить до 16 ;; Вызывается из 2 мест - шаг 07 и шаг 12 ; swapf DS1820_ScratctPad,W,BANKED ; Младший байт в акб со сменой ниблов ; andlw 0x0F ;, младший нибл АКБ правильный ; movwf Tmp_0,BANKED ; Накапливаем результат ; swapf DS1820_ScratctPad+1,W,BANKED ; ; andlw 0xF0 ;старший нибл АКБ правильный ; addwf Tmp_0,W,BANKED ; Целая знаковая температура в АКБ ; movwf W1_TempInt,BANKED ; Старший байт темп для знакового вывода байта ; movf DS1820_ScratctPad,W,BANKED ; Младший байт в акб ; andlw 0x0F ;, младший нибл АКБ правильный дробная часть ; btfsc W1_TempInt,7,BANKED ; Знак целой части минус ? ; sublw d'1' ; Дополняем дробную часть ; andlw 0x0F ;, младший нибл АКБ правильный дробная часть ; mullw d'10' ; умножаем дробную часть на 10, максимум 16х10=160 помещается в PRODL ; swapf PRODL,W,ACCESS ; делим результат на 16 ; andlw 0x0F ;, младший нибл АКБ правильный дробная часть *10/16= цифра 0-9 ; movwf W1_TempDot,BANKED ; Дробная часть ; return Read_1W_Table ; ЛЦД модуль тоже не надеется на неизменность указателей во внешнем мире и имеет собственные ; буфера указателей ПЗУ ;movff24 TBLPTRL,TBLPTR_1W_Temp_1 ; Сохраняем внешние значения btfsc W_1_Flg,2,ACCESS ; Первый вызов или очередной адрес ? bra ReadDone bsf W_1_Flg,2,ACCESS movlf low(Table_1W+1),TBLPTRL,ACCESS ;Заслали movlf high(Table_1W+1),TBLPTRH,ACCESS ;в указатель +1 (пропуск ведущёго нуля) clrf TBLPTRU,ACCESS BSF EECON1, EEPGD,0 ; Point to PROGRAM memory tblrd*+ ; Читаем младший байт - количество сообщений всего. movff TABLAT,W1_Sensor_Count ; movff16 TBLPTRL,TBLPTR_1W_Temp_1 ; Сохраняем внутреннее значения bra AllAdrRead ; При первом вызове - только указатели и количество ReadDone movff16 TBLPTR_1W_Temp_1,TBLPTRL ; Восстанавливаем внутренние значения clrf TBLPTRU,ACCESS movlf d'8',W1_Byte_Count,BANKED; Количество байт чтения номера датчика lfsr 0, DS1820_ScratctPad ; BSF EECON1, EEPGD,0 ; Point to PROGRAM memory LoopRead tblrd*+ ; Читаем байт movff TABLAT,POSTINC0 decfsz W1_Byte_Count,F,BANKED ; Конец байтам ? bra LoopRead ; Читаем новый AllAdrRead movff16 TBLPTRL,TBLPTR_1W_Temp_1 ; Сохраняем внутреннее значения ;movff24 TBLPTR_1W_Temp_1,TBLPTRL ; Восстанавливаем внешние значения ;bra AllByteRead return ;**** каждая отдельная строка DB в секции code должна содержать ЧЁТНОЕ количество байт ;**** иначе будет дополнена НУЛЁМ ;**** Секция code_pack лишена этого свойства Table_1W code_pack; 0x800 ; Вынес в конец кода с некоторым запасом - BRA переставали работать global Table_1W ; Во внешний мир - лишь адрес таблиц, всё остальное внутри таблиц. ; Extern InitAll ; Защитный барьер от кода из NOP goto InitAll ; При попытке передать управление этой секции - ресет Table_1W ; Таблица серийников 1-wire датчиков db d'0',d'3' ; Количество идущих далее серийников датчиков #ifdef PCPWM_Board ; Коэффициенты для учебной платы без цепей АЦП db 0x28,0x4C,0x70,0x39,0x01,0x00,0x00,0x0B ; Первый датчик 0724C3-422AE на плате короткие ноги db 0x28,0xBC,0x75,0x39,0x01,0x00,0x00,0xAB ; Второй датчик 0724C3-422AE на проводках db 0x28,0x5B,0x76,0x39,0x01,0x00,0x00,0x49 ; Третий датчик 0724C3-422AE на плате длинные ноги #else ; Боевая буратина с припаянной периферией АЦП - ток, напряжение, термистор db 0x28,0xBC,0x75,0x39,0x01,0x00,0x00,0xAB ; Второй датчик 0724C3-422AE на проводках db 0x28,0x5B,0x76,0x39,0x01,0x00,0x00,0x49 ; Третий датчик 0724C3-422AE на плате длинные ноги db 0x28,0x4C,0x70,0x39,0x01,0x00,0x00,0x0B ; Первый датчик 0724C3-422AE на плате короткие ноги #endif ; ;***************************************************************************** ; #ifdef W1_Pin ; Самый глобальный переклюк - можно не убирать файл из проекта ; при убирании подсистемы из AddIncludeFiles.bat ;***************************************************************************** #endif ;End of program END