; Име на файла: Temp_sens_CLCD.asm ;************************************************************** LIST P=18F252 ; Задаване типа на микроконтролера ; Алтернативи за PIC18FXX2: ; 18F242, 18F252, 18F442, 18F452 ;**** Включване на заглавен файл с дефинициите на SFR-регистрите *** IFDEF __18F242 ; Ако микроконтролерът е PIC18F242 #include ; Използвай файл "P18F242.INC" ENDIF IFDEF __18F252 ; Ако микроконтролера е PIC18F252 #include ; Използвай файл "P18F252.INC" ENDIF IFDEF __18F442 ; Ако микроконтролерът е PIC18F442 #include ; Използвай файл "P18F442.INC" ENDIF IFDEF __18F452 ; Ако микроконтролерът е PIC18F452 #include ; Използвай файл "P18F452.INC" ENDIF ;******* Конфигуриращи битове ************************************** __CONFIG _CONFIG1H, _OSCS_OFF_1H & _HS_OSC_1H __CONFIG _CONFIG2L, _BOR_OFF_2L & _PWRT_ON_2L __CONFIG _CONFIG2H, _WDT_OFF_2H __CONFIG _CONFIG3H, _CCP2MX_OFF_3H __CONFIG _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L __CONFIG _CONFIG7H, _EBTRB_OFF_7H ;******* Константи, използвани в програмата ************************ ;------- Тактова честота на микроконтролера Fosc, [Hz] ------------- Fosc EQU D'10000000' ; 10 MHz ;------------------------------------------------------------------- ; Константи, използвани при комуникацията с TCN75 Address_byte_rd EQU B'10010001' Address_byte_wr EQU B'10010000' ; Адреси на регистрите на температурен сензор TCN75 TEMP_reg EQU B'00000000' ; Регистър за такущата температура CONFIG_reg EQU B'00000001' ; Конфигурационен регистър HYST_reg EQU B'00000010' ; Регистър за задаване на хистерезис TEMP_TH_reg EQU B'00000011' ; Регистър за прагова стойност ; Конфигурационен байт за температурен сензор TCN75 TS_config_byte EQU B'00011100' ; Режим термостат ; Активно ниво '1' ;******* Дефиниране на променливите, използвани в програмата ******* ;------- Банка за бърз достъп (Access Bank) ------------------------ CBLOCK H'000' ; Начален адрес на Access Bank WREG_TEMP ; Променливи, използвани за съхранение на STATUS_TEMP ; съдържанието на регистри WREG, STATUS и BSR BSR_TEMP ; при обслужване на прекъсване с нисък приоритет Flag_register_0 ; Регистър за потребителски флагове Temp_L ; Променливи, изпозлване за съхранение на Temp_H ; прочетенета стойност за температурата Temp_100 ; Променливи, изпозлвани за визуализация на Temp_10 ; температурата Temp_1 ; Temp_0.1 ; LAST_REG ; Адрес на последния регистър от Access Bank, ; използван в програмата ENDC ; Дефиниране на начален адрес за променливите, използвани в макросите ; от заглавните файлове <..._macros.inc> Macros_vars SET LAST_REG ;------- Банка 0 --------------------------------------------------- CBLOCK H'080' ; Начален адрес на Банка 0 ENDC ;------- Банка 1 --------------------------------------------------- CBLOCK H'100' ; Начален адрес на Банка 1 LAST_REG_1 ; Адрес на последния регистър от Банка 1, ; използван в програмата ENDC ; Дефиниране на начален адрес за променливите, използвани в подпрограмите ; от заглавните файлове <..._config.inc> и <..._prog.inc>. Header_vars SET LAST_REG_1 ;******* Дефиниране на данни за запис в EEPROM паметта ************* ; ORG 0xf00000 ; DE "Test Data",0,1,2,3,4,5 ; Примерни данни ;******* Дефиниране на входно-изходните изводи ********************* ;******* Дефиниране на потребителски флагове *********************** #define My_flag_1 Flag_register_0,0 ;******************************************************************* ;**Използвани заглавни файлове с предварително дефинирани макроси*** ; #include ; #include #include ;******************************************************************* ;******************************************************************* ; Потребителска програма ;******************************************************************* ORG 0x0000 ; Вектор на НУ goto Start ; Преход към началото на програмата ORG 0x0008 ; Вектор на прекъсване с висок приоритет goto ISR_HI ; Преход към обслужващата програма ORG 0x0018 ; Вектор на прекъсване с нисък приоритет goto ISR_LO ; Преход към обслужващата програма ;******************************************************************* ; Начало на програмата (инициализация на микроконтролера) ;******************************************************************* Start movlb H'01' ; Избор на Банка 1 bsf RCON,IPEN ; Използване на приоритетни прекъсвания clrf Flag_register_0 ; Нулиране на потребителските флагове movlw H'07' ; Конфигуриране изводите на PORTA movwf ADCON1 ; за работа като цифрови В/И изводи call Init_TIMER ; Инициализиране на системния таймер ; Потребителски код за инициализация goto Main ; Преход към главната програма ;******************************************************************* ; Използвани подпрограми ;******************************************************************* ;******* Използвани заглавни файлове с предварително ************ ;******* дефинирани функции под формата на подпрограми ************ ;------- Заглавни файлове за параметризация на функциите ----------- ; Конфигурационен файл за системния таймер #include #include #include ;------------------------------------------------------------------- ;------- Заглавни файлове, съдържащи кода на функциите ------------- ; Подпрограми и макроси, необходими за използване на системния таймер #include #include #include ;------------------------------------------------------------------- ;******* Програми за обслужване на прекъсванията ******************* ;------- Програма за обслужване на прекъсвания с висок приоритет --- ISR_HI btfsc INTCON,TMR0IF ; Прекъсване от Таймер 0? bra serv_TIMER ; Да, обслужване bra next_int ; Не, провери следващият източник serv_TIMER ; Обслужване на прекъсването от Таймер 0, call Update_TIMER ; чрез който се обезпечава работата на bcf INTCON,TMR0IF ; системния таймер next_int ; *** Код за обслужване на прекъсванията с висок приоритет *** END_HI retfie FAST ; Връщане от ISR и възстановяване на регистри ; WREG, STATUS и BSR ;------- Програма за обслужване на прекъсвания с нисък приоритет --- ISR_LO movff STATUS,STATUS_TEMP ; Съхраняване съдържанието movff WREG,WREG_TEMP ; на регистри STATUS, WREG movff BSR,BSR_TEMP ; и BSR ; *** Код за обслужване на прекъсванията с нисък приоритет *** END_LO movff BSR_TEMP,BSR ; Възстановяване съдържанието movff WREG_TEMP,WREG ; на регистри STATUS, WREG movff STATUS_TEMP,STATUS ; и BSR retfie ;------ Други подпрограми ------------------------------------------ ;******************************************************************* ; Главна програма ;******************************************************************* Main call Init_CLCD ; Инициализация на LCD модула call Init_MSSP_I2C ; Инициализация на модул MSSP ; за режим I2C ;------ Конфигуриране на сензора ----------------------------------- call I2C_IDLE_CHECK ; Проверка за свободна магистрала call START_cond ; Условие "START" movlw Address_byte_wr ; Зареждане на адреса в WREG call Send_I2C_addr ; Адресиране на датчика movlw CONFIG_reg ; Адрес на конфигурационния регистър call Send_I2C_byte ; Изпращане на дареса movlw TS_config_byte ; Зареждане на конфигурационния байт call Send_I2C_byte ; Изпращане на байта call RESTART_cond ; Повторно условие START ;------ Задаване на температурен праг ------------------------------ movlw Address_byte_wr ; Зареждане на адреса в WREG call Send_I2C_addr ; Адресиране на датчика movlw TEMP_TH_reg ; Адрес на регистъра за прагова стойност call Send_I2C_byte ; Изпращане на адреса movlw D'26' ; Прагова стойност - MSB call Send_I2C_byte ; Изпращане на старшия байт movlw D'0' ; Прагова стойност - LSB call Send_I2C_byte ; Изпращане на младшия байт call RESTART_cond ; Повторно условие START ;------ Задаване на хистерезис ------------------------------------- movlw Address_byte_wr ; Зареждане на адреса в WREG call Send_I2C_addr ; Адресиране на датчика movlw HYST_reg ; Адрес на регистъра за хистерезис call Send_I2C_byte ; Изпращане на адреса movlw D'24' ; Стойност за хистерезиса - MSB call Send_I2C_byte ; Изпращене на старшия байт movlw D'0' ; Стойност за хистерезиса - LSB call Send_I2C_byte ; Изпращане на младшия байт call STOP_cond ; Условие STOP ;------ Код за четене на температурния сензор ---------------------- read_temp_sensor call I2C_IDLE_CHECK ; Проверка за свободна магистрала call START_cond ; Условие START movlw Address_byte_wr ; Зареждане на адреса в WREG call Send_I2C_addr ; Адресиране на датчика movlw TEMP_reg ; Адрес на регистъра за температурата call Send_I2C_byte ; Изпращане на адреса call RESTART_cond ; Повторно условие START movlw Address_byte_rd ; Зареждане на адреса в WREG call Send_I2C_addr ; Адресиране на датчика call Receive_I2C_byte ; Приемане на страшия байт за movwf Temp_H ; стойността на температурата bsf LAST_byte ; Флаг LAST_byte = 1 call Receive_I2C_byte ; Приемане на младшия байт за movwf Temp_L ; стойността на температурата call STOP_cond ; Условие STOP ;------ Код за определяне на стойността за температурата ----------- bcf STATUS,C ; Нулиране на флаг С rlcf Temp_L,f ; Изместване наялво през С rlcf Temp_H,f ; Изместване наялво през С bnc pos_temp ; Преход при липса на пренос movlw '-' ; Знак "-" за отрицателна температура movwf Temp_100 ; negf Temp_H ; Получаване на абсолютната стойност ; за температурата pos_temp bcf STATUS,C ; Нулиране на флаг С rrcf Temp_H,f ; Изместване надясно през С bnc round ; Преход при липса на пренос movlw '5' ; Зареждане ASCII кода на 5 в movwf Temp_0.1 ; променливата за десетите bra disp_temp ; Преход към кода за визуализация round movlw '0' ; Зареждане ASCII кода на 0 в movwf Temp_0.1 ; променливата за десетите ;------ Код за визуализация ---------------------------------------- disp_temp BIN08BCD3 Temp_H ; Получаване на BCD формат movlw '-' ; Проверка дали стойността за cpfseq Temp_100 ; температурата е отрицателна bra pos_val ; Не bra neg_val ; Да pos_val movff DIG_100,Temp_100 ; Копиране на стойността за BCD_to_ASCII Temp_100 ; температурата в променливи neg_val movff DIG_10,Temp_10 ; Temp_100 - Temp_0.1 и BCD_to_ASCII Temp_10 ; получаване на ASCII кода nz_1 movff DIG_1,Temp_1 ; от BCD стойностите BCD_to_ASCII Temp_1 ; Text_to_CLCD H'00',"Temp=" ; Извеждане на текст movlw '0' ; Проверка дали стойността cpfseq Temp_100 ; за стотиците е 0 bra show_100 ; Не, визуализиране movlw ' ' ; Да, празен символ bra show_100_empty ; show_100 movf Temp_100,w ; (Temp_100) -> WREG show_100_empty call Send_CLCD_char ; Изпращене на символа към LCD movlw '0' ; Проверка дали стойността cpfseq Temp_10 ; за десетиците е 0 bra show_10 ; Не, визуализиране movlw ' ' ; Да, празен символ bra show_10_empty ; show_10 movf Temp_10,w ; (Temp_10) -> WREG show_10_empty call Send_CLCD_char ; Изпращане на символа към LCD movf Temp_1,w ; (Temp_1) -> WREG call Send_CLCD_char ; Изпращане на символа към LCD movlw ',' ; ',' -> WREG call Send_CLCD_char ; Изпращане на символа към LCD movf Temp_0.1,w ; (Temp_0.1) -> WREG call Send_CLCD_char ; Изпращане на символа към LCD movlw H'DF' ; Код за символ "градус" call Send_CLCD_char ; Изпращане на символа към LCD movlw 'C' ; 'С' -> WREG call Send_CLCD_char ; Изпращане на символа към LCD Delay_Xms D'5000' ; Закъснение 1 s bra read_temp_sensor ; Повтори цикъла отначало END ; Край на програмата