SUBTITL "Thermo regulator" ;+-------------------------------------------------------------------------+ ;¦ Программа терморегулятора на PIC16C62A ¦ ;¦ Частота кварца - 8 МГц ¦ ;¦ Внутренняя частота - 2 МГц ¦ ;+-------------------------------------------------------------------------+ ; INCLUDE INCLUDE ; ORG 0000 GOTO BEGIN ORG 0004 GOTO INTERRUPT ;+-------------------------------------------------------------------------+ ;¦ Начало программы ¦ ;+-------------------------------------------------------------------------+ BEGIN: CLRF STATUS CLRF FSR CLRF TMR0 ;Clear Timer0 MOVLW B'00110111' ; ¦¦¦¦¦¦ ; ¦¦¦¦¦+- K1 ; ¦¦¦¦+-- K2 ; ¦¦¦+--- K3 ; ¦¦+---- OVERHEAT ; ¦+----- KEY ; +------ CALIBR MOVWF PORTA ANDLW B'11111000' MOVWF RA_STATE MOVLW B'00000000' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- A ; ¦¦¦¦¦¦+-- B ; ¦¦¦¦¦+--- C ; ¦¦¦¦+---- D ; ¦¦¦+----- E ; ¦¦+------ F ; ¦+------- G ; +-------- H MOVWF PORTB MOVLW B'01111011' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- SENS1 ; ¦¦¦¦¦¦+-- SENS2 ; ¦¦¦¦¦+--- DISCHARGE ; ¦¦¦¦+---- ; ¦¦¦+----- ; ¦¦+------ ; ¦+------- TX ; +-------- CONTR MOVWF PORTC MOVWF RC_STATE CLRF PCLATH MOVLW B'01100000' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- RBIF флаг прерывания по изменению на порте B ; ¦¦¦¦¦¦+-- INTF флаг прерывания по входу RB0/INT ; ¦¦¦¦¦+--- T0IF флаг прерывания по переполнению таймера T0 ; ¦¦¦¦+---- RBIE разрешение прерываний по изменению на порте B ; ¦¦¦+----- INTE разрешение прерываний по входу RB0/INT ; ¦¦+------ T0IE разрешение прерываний по переполнению T0 ; ¦+------- PEIE разрешение прерываний от переферийных устройств ; +-------- GIE глобальное разрешение прерываний MOVWF INTCON MOVLW B'00000100' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- TMR1IF флаг прерывания по переполнению таймера T1 ; ¦¦¦¦¦¦+-- TMR2IF флаг прерывания по концу цикла T2 ; ¦¦¦¦¦+--- CCP1IF флаг прерывания от модуля захвата/сравнения ; ¦¦¦¦+---- SSPIF флаг прерывания от последовательного порта ; ¦¦¦+----- ; ¦¦+------ ; ¦+------- ; +-------- MOVWF PIR1 CLRF TMR1L CLRF TMR1H MOVLW B'00000000' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- TMR1ON таймер включен/выключен (1/0) ; ¦¦¦¦¦¦+-- TMR1CS 1 - внешний источник, 0 - внутренний Fosc/4 ; ¦¦¦¦¦+--- T1SYNC 1 - не синхронизировать внешний источник ; ¦¦¦¦+---- T1OSCEN 1 - разрешение внешнего осцилятора ; ¦¦¦+----- T1CKPS0 коэффицент предварительного делителя ; ¦¦+------ T1CKPS1 00 - 1:1, 01 - 1:2, 10 - 1:4, 11 - 1:8 ; ¦+------- ; +-------- MOVWF T1CON CLRF TMR2 MOVLW B'00000000' ; ¦¦¦¦¦¦¦ ; ¦¦¦¦¦+-- T2CKPS1..0 предварительный делитель 1:1,1:4,1:8,1:16 ; ¦¦¦¦¦ ; ¦¦¦¦+--- TMR2ON включение счетчика ; +------- TOUTPS3..0 постделитель 1:1...1:16 MOVWF T2CON CLRF SSPBUF ; CLRF SSPCON ; CLRF CCPR1L ; CLRF CCPR1H ; CLRF CCP1CON ; BANK1 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Для версии с PIC16C73A COMF ADCON1 ; Все входы цифровые ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; ; Настройка переода переполнения таймера T0 на 2.048 мс ; MOVLW B'10000011' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- PS0 предварительный делитель для WDT или T0 ; ¦¦¦¦¦¦+-- PS1 1:16 ; ¦¦¦¦¦+--- PS2 ; ¦¦¦¦+---- PSA 1 - предварительный делитель для WDT иначе для T0 ; ¦¦¦+----- T0SE 1 - внешнее тактирование по спаду иначе по нарастанию ; ¦¦+------ T0CS 1 - тактирование по внешнему входу иначе по частоте Fosc/4 ; ¦+------- INTEDG 1 - прерывание по нарастанию на RB0 иначе по спаду ; +-------- RBPU 1 - запрещение подтягивающих резисторов на RB MOVWF OPTION_REG MOVLW B'00110000' ; ¦¦¦¦¦¦ ; ¦¦¦¦¦+- K1 ; ¦¦¦¦+-- K2 ; ¦¦¦+--- K3 ; ¦¦+---- OVERHEAT ; ¦+----- KEY ; +------ CALIBR MOVWF TRISA MOVLW B'00000000' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- A ; ¦¦¦¦¦¦+-- B ; ¦¦¦¦¦+--- C ; ¦¦¦¦+---- D ; ¦¦¦+----- E ; ¦¦+------ F ; ¦+------- G ; +-------- H MOVWF TRISB MOVLW B'00111011' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- SENS1 ; ¦¦¦¦¦¦+-- SENS2 ; ¦¦¦¦¦+--- DISCHARGE ; ¦¦¦¦+---- ; ¦¦¦+----- ; ¦¦+------ ; ¦+------- TX ; +-------- CONTR MOVWF TRISC MOVLW B'00000000' ; ¦¦¦¦¦¦¦¦ ; ¦¦¦¦¦¦¦+- TMR1IE разрешение прерывания от T1 ; ¦¦¦¦¦¦+-- TMR2IE разрешение прерывания от T2 ; ¦¦¦¦¦+--- CCP1IE разрешение прерывания от CCP1 ; ¦¦¦¦+---- SSPIE разрешение прерывания от SSP ; ¦¦¦+----- ; ¦¦+------ ; ¦+------- ; +-------- MOVWF PIE1 BSF PCON,NOT_POR ; Выключение признака сброса по включению CLRF PR2 ; CLRF SSPADD CLRF SSPSTAT BANK0 GOTO START CONVERT: CLRF PCLATH ANDLW H'0F' ADDWF PCL,F RETLW SMV0 RETLW SMV1 RETLW SMV2 RETLW SMV3 RETLW SMV4 RETLW SMV5 RETLW SMV6 RETLW SMV7 RETLW SMV8 RETLW SMV9 RETLW SMVA RETLW SMVB RETLW SMVC RETLW SMVD RETLW SMVE RETLW SMVF GET_SCAN: ANDLW B'00000011' ADDWF PCL,F RETLW B'00000110' RETLW B'00000101' RETLW B'00000011' RETLW B'00000111' ;+-------------------------------------------------------------------------+ ;¦ Обработка прерываний 2.048 мс ¦ ;+-------------------------------------------------------------------------+ INTERRUPT: PUSH: MOVWF TEMP_W SWAPF STATUS,W MOVWF TEMP_STAT MOVF FSR,W MOVWF TEMP_FSR MOVF PCLATH,W MOVWF TEMP_PCLATH BANK0 BTFSC MEAS_DONE GOTO SERV_MEAS_DONE+1 CLRF PCLATH MOVF STATE_MEAS,W ADDWF PCL,F GOTO DISCHARGE GOTO INIT_MEAS_RCAL GOTO MEAS_RCAL GOTO DISCHARGE GOTO INIT_MEAS_SENS1 GOTO MEAS_SENS1 GOTO DISCHARGE GOTO INIT_MEAS_SENS2 GOTO MEAS_SENS2 DISCHARGE: BANK1 MOVLW B'00111011' ; Включить разряд конденсатора MOVWF TRISC MOVLW B'11110000' ; MOVWF TRISA ; Отключть калибровочный резистор BANK0 BCF T1CON,TMR1ON ; Выключить таймер BCF PIR1,TMR1IF ; Сбросить флаг переполнения CLRF TMR1L ; Очистить таймер CLRF TMR1H ; GOTO SERV_MEAS_DONE INIT_MEAS_RCAL: BANK1 MOVLW B'00111111' ; Выключить разряд конденсатора MOVWF TRISC ; MOVLW B'11010000' ; MOVWF TRISA ; Подключить калибровочный резистор BANK0 BSF T1CON,TMR1ON ; Включить таймер GOTO SERV_MEAS_DONE MEAS_RCAL: BTFSS PIR1,CCP1IF GOTO SERV_MEAS_DONE+1 BCF PIR1,CCP1IF ; Сброс флага прерывания модуля CCP1 MOVF CCPR1L,W ; Накопление результата MOVWF TCAL+1 MOVF CCPR1H,W MOVWF TCAL GOTO SERV_MEAS_DONE INIT_MEAS_SENS1: BANK1 MOVLW B'00111110' ; Включить датчик 1 MOVWF TRISC ; BANK0 BSF T1CON,TMR1ON ; Включить таймер GOTO SERV_MEAS_DONE MEAS_SENS1: BTFSS PIR1,CCP1IF GOTO SERV_MEAS_DONE+1 BCF PIR1,CCP1IF ; Сброс флага прерывания модуля CCP1 BCF T1CON,TMR1ON ; Выключить таймер BTFSC PIR1,TMR1IF ; BSF T1_OVER ; Зафиксировать переполнение если было BCF PIR1,TMR1IF ; MOVF CCPR1H,W ; MOVWF TSENS1 ; MOVF CCPR1L,W ; MOVWF TSENS1+1 ; ; ; ; Передать результат по последовательному каналу ; ; SWAPF TMP_SENS1_HI,W ; CALL HEX_TO_ASCII ; MOVWF R2 ; CALL SEND_BYTE ; MOVF TMP_SENS1_HI,W ; CALL HEX_TO_ASCII ; MOVWF R2 ; CALL SEND_BYTE ; SWAPF TMP_SENS1_LO,W ; CALL HEX_TO_ASCII ; MOVWF R2 ; CALL SEND_BYTE ; MOVF TMP_SENS1_LO,W ; CALL HEX_TO_ASCII ; MOVWF R2 ; CALL SEND_BYTE ; MOVLW 0A ; MOVWF R2 ; CALL SEND_BYTE ; GOTO SERV_MEAS_DONE ;HEX_TO_ASCII: ; ANDLW B'00001111' ; ADDLW -0A ; BTFSC STATUS,C ; ADDLW 7 ; ADDLW 3A ; RETURN INIT_MEAS_SENS2: BANK1 MOVLW B'00111101' ; Включить датчик 2 MOVWF TRISC ; BANK0 BSF T1CON,TMR1ON ; Включить таймер GOTO SERV_MEAS_DONE MEAS_SENS2: BTFSS PIR1,CCP1IF GOTO SERV_MEAS_DONE+1 BCF PIR1,CCP1IF ; Сброс флага прерывания модуля CCP1 BCF T1CON,TMR1ON ; Выключить таймер BTFSC PIR1,TMR1IF ; BSF T2_OVER ; Зафиксировать переполнение если было BCF PIR1,TMR1IF ; MOVF CCPR1H,W ; MOVWF TSENS2 ; MOVF CCPR1L,W ; MOVWF TSENS2+1 ; BSF MEAS_DONE ; CLRF STATE_MEAS ; Завершился цикл одного измерения GOTO SERV_MEAS_DONE+1 SERV_MEAS_DONE: INCF STATE_MEAS ; Указать на следующую фазу измерения BTFSS INTCON,T0IF ; Проверить флаг прерывания от таймера T0 GOTO SRT0_DONE ; BCF INTCON,T0IF ; Выполнить процедуру обработки прерывания ; ОБСЛУЖИВАНИЕ РЕГЕНЕРАЦИИ ИНДИКАТОРА MOVLW 0 MOVWF PORTB MOVF CNT_INDC,W ; CALL GET_SCAN ; Перенести лог 0 на следующее знакоместо IORWF RA_STATE,W ; Сохранить состояние линий порта не ; участвующих в регенерации MOVWF PORTA ; Установить 0 на выводе ; ; Обработка нажатия клавиши когда выключены все сегменты ; BTFSC KEY GOTO NO_KEY_DOWN MOVF PORTA,W ANDWF SCANCOD NO_KEY_DOWN: MOVLW VID_BUF ; Вычислить адрес расположения выводимого символа ADDWF CNT_INDC,W ; MOVWF FSR ; MOVF INDF,W ; BTFSS F_BLANK ; Не выводить индикацию если стадия затемнения MOVWF PORTB ; Записать символ в порт B INCF CNT_INDC ; Увеличить счетчик позиций MOVLW 3 ; SUBWF CNT_INDC,W ; Если пройдены все знакоместа то вернуться в SKIP_IF_W_NO_MORE ; начало GOTO NEXT_POS CLRF CNT_INDC ; ; ; Обработка сканирования клавиатуры ; COMF SCANCOD,W ANDLW B'00000111' BTFSC STATUS,Z GOTO NO_KEYPRESS BTFSC KEY_DOWN GOTO END_SERV_KEY BSF KEY_DOWN BSF KEYPRESS MOVWF SCAN GOTO END_SERV_KEY NO_KEYPRESS: BCF KEY_DOWN END_SERV_KEY: MOVLW B'11111111' MOVWF SCANCOD NEXT_POS: DECFSZ CNT01 GOTO SRT0_DONE MOVLW .50 MOVWF CNT01 MOVF TIMEOUT_INDC ; Обработать таймаут режима индикации BTFSC STATUS,Z ; GOTO SRT0_DONE ; DECFSZ TIMEOUT_INDC ; GOTO SRT0_DONE ; BCF INDC1 ; SRT0_DONE: BSF F_BLANK INCF CNT_BLANK BTFSS CNT_BLANK,6 BCF F_BLANK BTFSS STATE_OVER BCF F_BLANK POP: MOVF TEMP_PCLATH,W MOVWF PCLATH MOVF TEMP_FSR,W MOVWF FSR SWAPF TEMP_STAT,W MOVWF STATUS SWAPF TEMP_W, F SWAPF TEMP_W,W CLRWDT RETFIE ; ACCB = ACCB + ACCA ; MADD MOVF ACCA+1,W ADDWF ACCB+1, F ;ADD LSB BTFSC 3,0 ;ADD IN CARRY INCF ACCB, F MOVF ACCA,W ADDWF ACCB, F ;ADD MSB RETLW 0 NOP ; [ACCC,ACCB] = ACCA * ACCB MPY CALL SETUP ;RESULTS IN B(16 MSB'S) AND C(16 LSB'S) MLOOP RRF ACCD, F ;ROTATE D RIGHT RRF ACCD+1, F SKPNC ;NEED TO ADD? CALL MADD RRF ACCB, F RRF ACCB+1, F RRF ACCC, F RRF ACCC+1, F DECFSZ TEMP, F ;LOOP UNTIL ALL BITS CHECKED GOTO MLOOP RETLW 0 NOP SETUP MOVLW 10 MOVWF TEMP MOVF ACCB,W ;MOVE B TO D MOVWF ACCD ; C TO E MOVF ACCB+1,W MOVWF ACCD+1 MOVF ACCC,W MOVWF ACCE MOVF ACCC+1,W MOVWF ACCE+1 CLRF ACCB CLRF ACCB+1 RETLW 0 NOP DIV CALL SETUP MOVLW 20 MOVWF TEMP CLRF ACCC CLRF ACCC+1 DLOOP CLRC RLF ACCE+1, F RLF ACCE, f RLF ACCD+1, F RLF ACCD, F RLF ACCC+1, F RLF ACCC, F MOVF ACCA,W SUBWF ACCC,W ;CHECK IF A>C SKPZ GOTO NOCHK MOVF ACCA+1,W SUBWF ACCC+1,W ;IF MSB EQUAL THEN CHECK LSB NOCHK SKPC ;CARRY SET IF C>A GOTO NOGO MOVF ACCA+1,W ;C-A INTO C SUBWF ACCC+1, F BTFSS STATUS,C DECF ACCC, F MOVF ACCA,W SUBWF ACCC, F SETC ;SHIFT A 1 INTO B (RESULT) NOGO RLF ACCB+1, F RLF ACCB, F DECFSZ TEMP, F ;LOOP UNTILL ALL BITS CHECKED GOTO DLOOP RETLW 0 B2_BCD: BCF STATUS,0 ; clear the carry bit MOVLW .16 MOVWF COUNT CLRF R0 CLRF R1 CLRF R2 LOOP16: RLF ACCB+1, F RLF ACCB, F RLF R2, F RLF R1, F RLF R0, F DECFSZ COUNT, F GOTO ADJDEC RETLW 0 ADJDEC: MOVLW R2 MOVWF FSR CALL ADJBCD MOVLW R1 MOVWF FSR CALL ADJBCD MOVLW R0 MOVWF FSR CALL ADJBCD GOTO LOOP16 ADJBCD: MOVLW 3 ADDWF 0,W MOVWF TEMP BTFSC TEMP,3 ; test if result > 7 MOVWF 0 MOVLW 30 ADDWF 0,W MOVWF TEMP BTFSC TEMP,7 ; test if result > 7 MOVWF 0 ; save as MSD RETLW 0 COMPARE_A_MORE_B: MOVF ACCA,W SUBWF ACCB,W ; check if A>B BTFSS STATUS,Z RETURN ; C=0 if A > B MOVF ACCA+1,W SUBWF ACCB+1,W RETURN ; C=0 if A > B COMPARE_B_MORE_A: MOVF ACCB,W SUBWF ACCA,W ; check if B>A BTFSS STATUS,Z RETURN ; C=0 if B > A MOVF ACCB+1,W SUBWF ACCA+1,W RETURN ; C=0 if B > A ;+-------------------------------------------------------------------------+ ;¦ Инициализация основной программы ¦ ;+-------------------------------------------------------------------------+ START: MOVLW SMV0 MOVWF CIPH1 MOVWF CIPH2 MOVWF CIPH3 CLRF STATE CLRF CNT_INDC CLRF STATE_MEAS CLRF RSENS1 ; Очистка накопителя результатов измерения CLRF RSENS1+1 ; от датчика 1 CLRF RSENS1+2 ; CLRF RSENS2 ; Очистка накопителя результатов измерения CLRF RSENS2+1 ; от датчика 2 CLRF RSENS2+2 ; CLRF CCP_OVER ; Сброс флагов переполнения при измерении MOVLW .64 ; Инициализация счетчика цикла накопления MOVWF CNT_MEAS ; результатов измерения CLRF CNT_MOVAV MOVLW .50 MOVWF CNT01 MOVLW B'11111111' MOVWF SCANCOD CLRF DIAP ; MOVLW C_T1MS ; Установки по умолчанию MOVWF TREFMS ; MOVLW C_T1LS ; MOVWF TREFLS ; MOVLW C_TOVRHMS MOVWF TREFOVRHMS MOVLW C_TOVRHLS MOVWF TREFOVRHLS MOVLW C_THYSTEROVMS MOVWF THYSTEROVMS MOVLW C_THYSTEROVLS MOVWF THYSTEROVLS MOVLW C_THYSTERMS MOVWF THYSTERMS MOVLW C_THYSTERLS MOVWF THYSTERLS MOVLW B'00000101' ; Включить перехват при нарастании MOVWF CCP1CON BSF INTCON,GIE ; Разрешение прерываний MAIN_CIKL: BTFSS MEAS_DONE ; Если окончено измерение , GOTO END_SERV_MEAS_DONE ; то обработать результат ; ; T[sens]*R[cal] ; Вычислить сопротивление датчика 1 R[sens]= ----------------- ; T[cal] ; MOVF TSENS1,W ; MOVWF ACCA ; MOVF TSENS1+1,W ; MOVWF ACCA+1 ; MOVLW RCALLS ; MOVWF ACCB+1 ; MOVLW RCALMS ; MOVWF ACCB ; CALL MPY ; MOVF TCAL+1,W MOVWF ACCA+1 MOVF TCAL,W MOVWF ACCA CALL DIV ; MOVF ACCB+1,W ; Накопление результата от датчика 1 ADDWF RSENS1+2 ; в рег. RSENS1,RSENS1+1,RSENS1+2 BTFSS STATUS,C ; GOTO MS11 ; MOVLW 1 ADDWF RSENS1+1 BTFSC STATUS,C INCF RSENS1 MS11: MOVF ACCB,W ADDWF RSENS1+1 BTFSC STATUS,C INCF RSENS1 ; ; T[sens]*R[cal] ; Вычислить сопротивление датчика 2 R[sens]= ----------------- ; T[cal] ; MOVF TSENS2,W ; MOVWF ACCA ; MOVF TSENS2+1,W ; MOVWF ACCA+1 ; MOVLW RCALLS ; MOVWF ACCB+1 ; MOVLW RCALMS ; MOVWF ACCB ; CALL MPY ; MOVF TCAL+1,W MOVWF ACCA+1 MOVF TCAL,W MOVWF ACCA CALL DIV MOVF ACCB+1,W ; Накопление результата от датчика 2 ADDWF RSENS2+2 ; в рег. RSENS2,RSENS2+1,RSENS2+2 BTFSS STATUS,C ; GOTO MS21 ; MOVLW 1 ADDWF RSENS2+1 BTFSC STATUS,C INCF RSENS2 MS21: MOVF ACCB,W ADDWF RSENS2+1 BTFSC STATUS,C INCF RSENS2 BCF MEAS_DONE ; Разрешение начала нового измерения ; DECFSZ CNT_MEAS GOTO END_SERV_MEAS_DONE MOVLW .64 ; Если завешена выборка 64 отсчетов MOVWF CNT_MEAS ; то инициализировать новый цикл выборок MOVLW .6 MOVWF COUNT AVERAGE: ; Деление на 64 BCF STATUS,C RRF RSENS1 RRF RSENS1+1 RRF RSENS1+2 BCF STATUS,C RRF RSENS2 RRF RSENS2+1 RRF RSENS2+2 DECFSZ COUNT GOTO AVERAGE ; ; Если буфер скользящего среднего не заполнен, то заполнить его ; текущим результатом ; MOVF CNT_MOVAV,F BTFSS STATUS,Z GOTO MNC1 MOVLW .8 MOVWF COUNT MOVLW BUF_MOVAV MOVWF FSR FILL_BUF: MOVF RSENS1+2,W MOVWF INDF INCF FSR MOVF RSENS1+1,W MOVWF INDF INCF FSR DECFSZ COUNT GOTO FILL_BUF MOVLW BUF_MOVAV MOVWF CNT_MOVAV GOTO MNC2 MNC1: ; ; Записать в буфер скользащего среднего новый результат ; MOVF CNT_MOVAV,W MOVWF FSR INCF CNT_MOVAV MOVF RSENS1+2,W MOVWF INDF MOVF CNT_MOVAV,W MOVWF FSR INCF CNT_MOVAV MOVF RSENS1+1,W MOVWF INDF ; ; Установить указатель на начало если достигнут конец буфера ; MOVLW BUF_MOVAV+16 SUBWF CNT_MOVAV,W ; F - W BTFSS STATUS,C GOTO MNC2 MOVLW BUF_MOVAV MOVWF CNT_MOVAV MNC2: ; ; Вычислить скользящее среднее ; CLRF RSENS1 CLRF RSENS1+1 CLRF RSENS1+2 MOVLW .8 MOVWF COUNT MOVLW BUF_MOVAV MOVWF FSR MNC4: MOVF INDF,W ; Накопление результата INCF FSR ADDWF RSENS1+2 ; в рег. RSENS1,RSENS1+1,RSENS1+2 BTFSS STATUS,C ; GOTO MNC3 ; MOVLW 1 ADDWF RSENS1+1 BTFSC STATUS,C INCF RSENS1 MNC3: MOVF INDF,W INCF FSR ADDWF RSENS1+1 BTFSC STATUS,C INCF RSENS1 DECFSZ COUNT GOTO MNC4 MOVLW .3 MOVWF COUNT MOVAVERAGE: ; Деление на 8 BCF STATUS,C RRF RSENS1 RRF RSENS1+1 RRF RSENS1+2 DECFSZ COUNT GOTO MOVAVERAGE ;-------------------------------------------------------------------- ; Выполнение регулировочной функции для датчика 1 ; BTFSC T1_OVER ; Проверка переполнения GOTO DOWN MOVF RSENS1+2,W MOVWF ACCB+1 MOVF RSENS1+1,W MOVWF ACCB CALL CALCULAT BTFSS R_OVER GOTO NOT_SENS1_OVER BSF T1_OVER GOTO DOWN NOT_SENS1_OVER: MOVF ACCB,W MOVWF DEGREESENS1 MOVF ACCB+1,W MOVWF DEGREESENS1+1 ; ; Проверка выхода за верхний предел ; CLRF ACCA ; Сложить номинальную величину с MOVF TREFLS,W ; гистерезисом ADDWF THYSTERLS,W ; MOVWF ACCA+1 ; BTFSC STATUS,C ; INCF ACCA ; MOVF TREFMS,W ADDWF THYSTERMS,W ADDWF ACCA CALL COMPARE_B_MORE_A ; Сравнить с измеренной величиной BTFSC STATUS,C ; GOTO NO_UP BTFSC OVERHEAT GOTO NO_UP BSF P_CONTROL MOVF RC_STATE,W MOVWF PORTC ; NO_UP: ; ; Проверка выхода за нижний предел ; CLRF ACCA ; Вычесть из номинальной величины MOVF THYSTERLS,W ; гистерезис SUBWF TREFLS,W ; MOVWF ACCA+1 ; BTFSS STATUS,C DECF ACCA MOVF THYSTERMS,W SUBWF TREFMS,W ADDWF ACCA CALL COMPARE_A_MORE_B BTFSC STATUS,C GOTO NO_DOWN DOWN: BCF P_CONTROL MOVF RC_STATE,W MOVWF PORTC ; NO_DOWN: ;-------------------------------------------------------------------- ; Выполнение регулировочной функции для датчика 2 ; BTFSC T2_OVER ; Проверка переполнения GOTO DOWN_OV MOVF RSENS2+2,W MOVWF ACCB+1 MOVF RSENS2+1,W MOVWF ACCB CALL CALCULAT BTFSS R_OVER GOTO NOT_SENS2_OVER BSF T2_OVER GOTO DOWN_OV NOT_SENS2_OVER: MOVF ACCB,W MOVWF DEGREESENS2 MOVF ACCB+1,W MOVWF DEGREESENS2+1 ; ; Проверка выхода за верхний предел ; CLRF ACCA ; Сложить номинальную величину с MOVF TREFOVRHLS,W ; гистерезисом ADDWF THYSTEROVLS,W ; MOVWF ACCA+1 ; BTFSC STATUS,C ; INCF ACCA ; MOVF TREFOVRHMS,W ADDWF THYSTEROVMS,W ADDWF ACCA CALL COMPARE_B_MORE_A ; Сравнить с измеренной величиной BTFSC STATUS,C ; GOTO NO_UP_OV BSF OVERHEAT ; Блокирование регулировки BSF OVER ; Включение внешнего сигнала BSF STATE_OVER BCF P_CONTROL MOVF RC_STATE,W MOVWF PORTC ; NO_UP_OV: ; ; Проверка выхода за нижний предел ; CLRF ACCA ; Вычесть из номинальной величины MOVF THYSTEROVLS,W ; гистерезис SUBWF TREFOVRHLS,W ; MOVWF ACCA+1 ; BTFSS STATUS,C DECF ACCA MOVF THYSTEROVMS,W SUBWF TREFOVRHMS,W ADDWF ACCA CALL COMPARE_A_MORE_B BTFSC STATUS,C GOTO NO_DOWN_OV DOWN_OV: BCF STATE_OVER NO_DOWN_OV: ;--------------------------------------------------------- ; Обслуживание индикации температуры ; BTFSC INDC1 GOTO INDC_T2 BTFSS T1_OVER ; Проверка переполнения GOTO INDC_T1 INDC_T_OVER: MOVLW SMVDOWN MOVWF CIPH1 MOVWF CIPH2 MOVWF CIPH3 GOTO END_INDC INDC_T1: MOVF DEGREESENS1+1,W MOVWF ACCB+1 ;STORE LSB MOVF DEGREESENS1,W MOVWF ACCB ;STORE MSB GOTO INDC_T INDC_T2: BTFSC T2_OVER ; Проверка переполнения GOTO INDC_T_OVER MOVF DEGREESENS2+1,W MOVWF ACCB+1 ;STORE LSB MOVF DEGREESENS2,W MOVWF ACCB ;STORE MSB INDC_T: ;--------------------------------------------------------- ; Форматирование данных для вывода на индикатор ; CALL FORMAT END_INDC: CLRF RSENS1 CLRF RSENS1+1 CLRF RSENS1+2 CLRF RSENS2 CLRF RSENS2+1 CLRF RSENS2+2 CLRF CCP_OVER ; Сброс флагов имевших место переполнений END_SERV_MEAS_DONE: BTFSS KEYPRESS GOTO NOT_KEYPRESS BCF KEYPRESS BTFSC SCAN,0 GOTO PRESS_0 BTFSC SCAN,1 GOTO PRESS_1 BTFSC SCAN,2 GOTO PRESS_2 NOT_KEYPRESS: GOTO MAIN_CIKL_DONE PRESS_0: BTFSS INDC1 ; Сбросить блокировку можно только врежиме GOTO PRS01 ; индикации BTFSC STATE_OVER ; Выключить перегрузку можно только GOTO MAIN_CIKL_DONE ; если температура упала ниже нижнего предела BCF OVER BCF OVERHEAT GOTO MAIN_CIKL_DONE PRS01: BSF INDC1 MOVLW .30 MOVWF TIMEOUT_INDC GOTO MAIN_CIKL_DONE PRESS_1: ; ; Переход в режим установки температурного диаппазона ; PRS13: MOVF TREFLS,W MOVWF ACCB+1 ;STORE LSB MOVF TREFMS,W MOVWF ACCB ;STORE MSB CALL FORMAT MOVLW .50 ; Таймаут 10 сек MOVWF TIMEOUT_INDC PRS12: BTFSS KEYPRESS GOTO PRS11 BCF KEYPRESS BTFSC SCAN,0 GOTO MAIN_CIKL_DONE BTFSC SCAN,1 GOTO NEXT_DIAP GOTO PRS11 NEXT_DIAP: INCF DIAP MOVLW 6 ; SUBWF DIAP,W ; Если пройден цикл то вернуться в начало SKIP_IF_W_MORE CLRF DIAP MOVLW C_THYSTERMS MOVWF THYSTERMS MOVLW C_THYSTERLS MOVWF THYSTERLS MOVF DIAP BTFSS STATUS,Z GOTO NDI1 MOVLW C_T1MS ; MOVWF TREFMS ; MOVLW C_T1LS ; MOVWF TREFLS ; GOTO PRS13 NDI1: MOVLW 1 SUBWF DIAP,W BTFSS STATUS,Z GOTO NDI2 MOVLW C_T2MS ; MOVWF TREFMS ; MOVLW C_T2LS ; MOVWF TREFLS ; GOTO PRS13 NDI2: MOVLW 2 SUBWF DIAP,W BTFSS STATUS,Z GOTO NDI3 MOVLW C_T3MS ; MOVWF TREFMS ; MOVLW C_T3LS ; MOVWF TREFLS ; GOTO PRS13 NDI3: MOVLW C_THYSTERMS1 MOVWF THYSTERMS MOVLW C_THYSTERLS1 MOVWF THYSTERLS MOVLW 3 SUBWF DIAP,W BTFSS STATUS,Z GOTO NDI4 MOVLW C_T4MS ; MOVWF TREFMS ; MOVLW C_T4LS ; MOVWF TREFLS ; GOTO PRS13 NDI4: MOVLW 4 SUBWF DIAP,W BTFSS STATUS,Z GOTO NDI5 MOVLW C_T5MS ; MOVWF TREFMS ; MOVLW C_T5LS ; MOVWF TREFLS ; GOTO PRS13 NDI5: MOVLW C_T6MS ; MOVWF TREFMS ; MOVLW C_T6LS ; MOVWF TREFLS ; GOTO PRS13 PRS11: MOVF TIMEOUT_INDC ; По истечении таймаута вернуться в главный BTFSS STATUS,Z ; режим GOTO PRS12 ; GOTO MAIN_CIKL_DONE PRESS_2: GOTO MAIN_CIKL_DONE MAIN_CIKL_DONE: GOTO MAIN_CIKL ;+-------------------------------------------------------------------------+ ;¦ Преобразование времени в сопротивление ¦ ;¦ ¦ ;¦ Вход : ACCA,ACCA+1 - время заряда через датчик ¦ ;¦ TCAL,TCAL+1 - время заряда через калибровочный резистор¦ ;¦ Константа : RCALMS,RCALLS - сопротивление калибровочного резистора ¦ ;¦ ¦ ;¦ 2. Вычислить индекс I в таблице "сопротивление-температура" ¦ ;¦ как целую часть от деления R[sens] на 5.12 ¦ ;¦ ¦ ;¦ ¦ ;¦ 3. Вычислить температуру : ¦ ;¦ ¦ ;¦ T[I]-T[I+1] ¦ ;¦ T = T[I] - ------------- * (R[sens]-I*5.12) ¦ ;¦ 5.12 ¦ ¦ ;¦ ¦ ;+-------------------------------------------------------------------------+ CALCULAT: ; ; Табличное преобразование ; TABL_CONV: BCF R_OVER ; Проверка на допустимое значение MOVLW B'01111110' SUBWF ACCB,W ; F - W BTFSC STATUS,C BSF R_OVER MOVF ACCB,W MOVWF ACCE RRF ACCE ; Вычисляется индекс I в таблице MOVF ACCE,W ; Деление на 512 CALL THERMO_HI ; Взять температуру T(I) -> ACCC MOVWF ACCC ; MOVF ACCE,W ; CALL THERMO_LO MOVWF ACCC+1 INCF ACCE MOVF ACCE,W CALL THERMO_HI ; Взать температуру T(I+1) -> ACCD MOVWF ACCD ; MOVF ACCE,W ; CALL THERMO_LO MOVWF ACCD+1 ; ; Вычислить: ; T(I)-T(I+1) ; T(I) - ------------- * (K-I) ; 512 ;----------------------------------------------------------------- ; Вычисление T(I)-T(I+1) : ACCA = ACCC - ACCD MOVF ACCD+1,W SUBWF ACCC+1,W ; MOVWF ACCA+1 BTFSS STATUS,C INCF ACCD MOVF ACCD,W SUBWF ACCC,W MOVWF ACCA ; Вычисление [T(I)-T(I+1)]*(K-I) : [ACCC,ACCB] = ACCA * ACCB MOVLW B'00000001' ANDWF ACCB CALL MPY ; ACCC -> ACCE ; Деление на 512 MOVF ACCC,W MOVWF ACCC+1 BCF STATUS,C RRF ACCB+1,W MOVWF ACCC RRF ACCC+1 BTFSS STATUS,C ; Округление GOTO TAC1 MOVLW 1 ADDWF ACCC+1 BTFSC STATUS,C INCF ACCC TAC1: ; Результат в ACCC ; Вычесть из T(I) ACCB = ACCE - ACCC MOVF ACCC+1,W SUBWF ACCE+1,W ; MOVWF ACCB+1 BTFSS STATUS,C INCF ACCC MOVF ACCC,W SUBWF ACCE,W MOVWF ACCB RETURN FORMAT: CALL B2_BCD ; Перевод двоичного числа в ACCB,ACCB+1 ; в формат 5-и разр. двочно-десятичного числа ; R0,R1,R2 MOVF R0,W BTFSC STATUS,Z GOTO EXP1 MOVF R0,W CALL CONVERT MOVWF CIPH1 SWAPF R1,W CALL CONVERT MOVWF CIPH2 MOVF R1,W CALL CONVERT MOVWF CIPH3 GOTO FORMAT_DONE EXP1: MOVF R1,W ANDLW B'11110000' BTFSC STATUS,Z GOTO EXP2 SWAPF R1,W CALL CONVERT MOVWF CIPH1 MOVF R1,W CALL CONVERT MOVWF CIPH2 BSF CIPH2,7 ; Поставить запятую SWAPF R2,W CALL CONVERT MOVWF CIPH3 GOTO FORMAT_DONE EXP2: MOVF R1,W CALL CONVERT MOVWF CIPH1 BSF CIPH1,7 ; Поставить запятую SWAPF R2,W CALL CONVERT MOVWF CIPH2 MOVF R2,W CALL CONVERT MOVWF CIPH3 FORMAT_DONE: RETURN ;+---------------------------------------------------+ ;¦ Подпрограмма задержки ¦ ;+---------------------------------------------------+ DELAY93uS: MOVLW .22 ; 1 MOVWF R0 ; 1 DEL2: NOP ; 1 DECFSZ R0,F ; 1 GOTO DEL2 ; 2 NOP ; 1 RETURN ; 2 сумма 93 t=93 мкс ;+--------------------------------------------------------------------------+ ;¦ Подпрограмма передачи байта ¦ ;¦ Вход : R2 - передаваемый байт ¦ ;+--------------------------------------------------------------------------+ SEND_BYTE: MOVLW 8 ; 1 MOVWF R1 ; 1 BCF P_TX ; 1 MOVF RC_STATE,W ; 1 MOVWF PORTC ; 1 CALL DELAY93uS ; 2 + 93 NOP ; 1 NOP ; 1 NOP ; 1 ; SBY1: ; RRF R2,F ; 1 BCF P_TX ; 1 BTFSC STATUS,C ; 1 BSF P_TX ; 1 MOVF RC_STATE,W ; 1 MOVWF PORTC ; 1 t=104 мкс CALL DELAY93uS ; ; DECFSZ R1,F ; GOTO SBY1 ; ; ; BSF P_TX ; MOVF RC_STATE,W ; MOVWF PORTC ; NOP ; NOP ; NOP ; NOP ; CALL DELAY93uS ; ; RETURN ORG 400H ; ; Сопротивление ; Температура ; HEX формат ; 5.12 104.21 28B5 ; 10.24 82.77 2055 ; 15.36 71.18 1BCE ; 20.48 63.33 18BD ; 25.60 57.45 1671 ; 30.72 52.78 149E ; 35.84 48.91 131B ; 40.96 45.62 11D2 ; 46.08 42.77 10B5 ; 51.20 40.25 0FB9 ; 56.32 38.00 0ED8 ; 61.44 35.97 0E0D ; 66.56 34.13 0D55 ; 71.68 32.43 0CAB ; 76.80 30.87 0C0F ; 81.92 29.41 0B7D ; 87.04 28.06 0AF6 ; 92.16 26.79 0A77 ; 97.28 25.60 0A00 ; 102.40 24.48 0990 ; 107.52 23.42 0926 ; 112.64 22.42 08C2 ; 117.76 21.46 0862 ; 122.88 20.55 0807 ; 128.00 19.68 07B0 ; 133.12 18.85 075D ; 138.24 18.05 070D ; 143.36 17.29 06C1 ; 148.48 16.55 0677 ; 153.60 15.85 0631 ; 158.72 15.17 05ED ; 163.84 14.51 05AB ; 168.96 13.87 056B ; 174.08 13.26 052E ; 179.20 12.67 04F3 ; 184.32 12.09 04B9 ; 189.44 11.53 0481 ; 194.56 10.99 044B ; 199.68 10.47 0417 ; 204.80 9.96 03E4 ; 209.92 9.47 03B3 ; 215.04 8.98 0382 ; 220.16 8.51 0353 ; 225.28 8.06 0326 ; 230.40 7.61 02F9 ; 235.52 7.18 02CE ; 240.64 6.75 02A3 ; 245.76 6.34 027A ; 250.88 5.93 0251 ; 256.00 5.54 022A ; 261.12 5.15 0203 ; 266.24 4.77 01DD ; 271.36 4.40 01B8 ; 276.48 4.03 0193 ; 281.60 3.67 016F ; 286.72 3.32 014C ; 291.84 2.98 012A ; 296.96 2.64 0108 ; 302.08 2.31 00E7 ; 307.20 1.99 00C7 ; 312.32 1.67 00A7 ; 317.44 1.36 0088 ; 322.56 1.05 0069 ; 327.68 0.75 004B ; ; MSB THERMO_HI: CLRF PCLATH BSF PCLATH,2 ANDLW H'3F' ADDWF PCL,F retlw 058H retlw 028H retlw 020H retlw 01BH retlw 018H retlw 016H retlw 014H retlw 013H retlw 011H retlw 010H retlw 00FH retlw 00EH retlw 00EH retlw 00DH retlw 00CH retlw 00CH retlw 00BH retlw 00AH retlw 00AH retlw 00AH retlw 009H retlw 009H retlw 008H retlw 008H retlw 008H retlw 007H retlw 007H retlw 007H retlw 006H retlw 006H retlw 006H retlw 005H retlw 005H retlw 005H retlw 005H retlw 004H retlw 004H retlw 004H retlw 004H retlw 004H retlw 003H retlw 003H retlw 003H retlw 003H retlw 003H retlw 002H retlw 002H retlw 002H retlw 002H retlw 002H retlw 002H retlw 002H retlw 001H retlw 001H retlw 001H retlw 001H retlw 001H retlw 001H retlw 001H retlw 000H retlw 000H retlw 000H retlw 000H retlw 000H retlw 000H ; LSB THERMO_LO: CLRF PCLATH BSF PCLATH,2 ANDLW H'3F' ADDWF PCL,F retlw 000H retlw 0B5H retlw 055H retlw 0CEH retlw 0BDH retlw 071H retlw 09EH retlw 01BH retlw 0D2H retlw 0B5H retlw 0B9H retlw 0D8H retlw 00DH retlw 055H retlw 0ABH retlw 00FH retlw 07DH retlw 0F6H retlw 077H retlw 000H retlw 090H retlw 026H retlw 0C2H retlw 062H retlw 007H retlw 0B0H retlw 05DH retlw 00DH retlw 0C1H retlw 077H retlw 031H retlw 0EDH retlw 0ABH retlw 06BH retlw 02EH retlw 0F3H retlw 0B9H retlw 081H retlw 04BH retlw 017H retlw 0E4H retlw 0B3H retlw 082H retlw 053H retlw 026H retlw 0F9H retlw 0CEH retlw 0A3H retlw 07AH retlw 051H retlw 02AH retlw 003H retlw 0DDH retlw 0B8H retlw 093H retlw 06FH retlw 04CH retlw 02AH retlw 008H retlw 0E7H retlw 0C7H retlw 0A7H retlw 088H retlw 069H retlw 04BH END