; Име на файла: Temp_sens_CLCD.asm
;**************************************************************
LIST P=18F252 ; Задаване типа на микроконтролера
; Алтернативи за PIC18FXX2:
; 18F242, 18F252, 18F442, 18F452
;**** Включване на заглавен файл с дефинициите на SFR-регистрите ***
IFDEF __18F242 ; Ако микроконтролерът е PIC18F242
#include <P18F242.INC>; Използвай файл "P18F242.INC"
ENDIF
IFDEF __18F252 ; Ако микроконтролера е PIC18F252
#include <P18F252.INC>; Използвай файл "P18F252.INC"
ENDIF
IFDEF __18F442 ; Ако микроконтролерът е PIC18F442
#include <P18F442.INC>; Използвай файл "P18F442.INC"
ENDIF
IFDEF __18F452 ; Ако микроконтролерът е PIC18F452
#include <P18F452.INC>; Използвай файл "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 <add_sub_macros.inc>
; #include <mul_div_macros.inc>
#include <BCD_macros.inc>
;*******************************************************************
;*******************************************************************
; Потребителска програма
;*******************************************************************
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 <SYS_TIMER_config.inc>
#include <SPI_and_I2C_config.inc>
#include <CLCD_config.inc>
;-------------------------------------------------------------------
;------- Заглавни файлове, съдържащи кода на функциите -------------
; Подпрограми и макроси, необходими за използване на системния таймер
#include <SYS_TIMER_prog.inc>
#include <SPI_and_I2C_prog.inc>
#include <CLCD_prog.inc>
;-------------------------------------------------------------------
;******* Програми за обслужване на прекъсванията *******************
;------- Програма за обслужване на прекъсвания с висок приоритет ---
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 ; Край на програмата