;-------------------------------; ; 1-Wire DALLAS sběrnice ; ; vyhledat kódy (5x DS18B20) ; ;-------------------------------; ;slovak@post.cz )S(04.2010; ;-------------------------------; ; Xtal = 4194304Hz ;-------------------------------- LIST P=16F88, R=DEC, MM=ON ;Direktivy překladače include ;Definice názvů registrů ;Nastavení konfigurace procesoru: __CONFIG _CONFIG1,_CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC __CONFIG _CONFIG2,_IESO_OFF & _FCMEN_OFF errorlevel 1, -306 cblock 0x20 MemSTATUS MemPCLATH A1 ;matematické proměnné A2 ; (a jiné funkce) A3 ; B1 ; B2 ; B3 ; C1 ; C2 ; C3 ; D1 ; D2 ; D3 ; X1 ; FL ;Flag, příznaky T_RDS ;data, odeslaná/přijatá CRC ;kontrolní součet IDS ;index DS, pořadí kódu EBDS ;ERROR bit snímače KOD1 ;DS1 Kód, sériové číslo, prvních 8 bitů KOD2 ;DS2 KOD3 ;DS3 KOD4 ;DS4 KOD5 ;DS5 KOD6 ;DS6 KOD7 ;DS7 KOD8 ;DS8 T1L ;DS1 teplota T1H ; (počítadlo poruch) T2L ;DS2 T2H ; T3L ;DS3 T3H ; T4L ;DS4 T4H ; T5L ;DS5 T5H ; T6L ;DS6 T6H ; T7L ;DS7 T7H ; T8L ;DS8 T8H ; R1 ;řád jedničky pro převod HEX/DEC R2 ;řád desítky R3 ;řád stovky R4 ;řád tisíce TE ;desetiné tečky, 0=žádná tečka endc MemW EQU 0x7F ZSC EQU 0xB2 ;znak (kroužek), stupeň Celsia (°C) PDS EQU 5 ;MAX počet snímačů DS #define SC STATUS,C #define SZ STATUS,Z #define E PORTA,2 ;výstup pro LCD #define RS PORTA,4 ; #define DS PORTB,0 ;sběrnice DS čidla, 1-wire #define Znam FL,7 ;znaménko, 1=záporná hodnota ;#define Azn FL,6 ;znaménka pro Mat. výpočty ;#define Bzn FL,5 ; #define ERP FL,4 ;1=ERROR po RESET/PRESENCE #define CONV FL,3 ;1=CONVERT, převod je zapnut #define EB1 EBDS,0 ;DS1, 1=ERROR bit #define EB2 EBDS,1 ;DS2 #define EB3 EBDS,2 ;DS3 #define EB4 EBDS,3 ;DS4 #define EB5 EBDS,4 ;DS5 #define EB6 EBDS,5 ;DS6 #define EB7 EBDS,6 ;DS7 #define EB8 EBDS,7 ;DS8 #define TE1 TE,0 ;1=ZAP tečka (432.1) #define TE2 TE,1 ;1=ZAP tečka (43.21) #define TE3 TE,2 ;1=ZAP tečka (4.321) ;RAM banka 0 (00-7F) RAM0 macro BCF STATUS,RP0 endm ;RAM banka 1 (80-FF) RAM1 macro BSF STATUS,RP0 endm ;******************************** ;reset ORG 0 GOTO Init CALL 41 CALL 83 CALL 40 ;------------------------------- ;přerušení 64Hz (krystal 4194304Hz) MOVWF MemW SWAPF STATUS,W CLRF STATUS MOVWF MemSTATUS MOVF PCLATH,W MOVWF MemPCLATH ;-------------------------------- BTFSS INTCON,TMR0IF ;od TMR0? GOTO EINT ;NE ;-------------------------------- ;přerušení od časovače TMR0 BCF INTCON,TMR0IF ;VYP příznak ;-------------------------------- ;STOP čtení klávesnice ; BTFSS E ;E=1?, sběrnici používá LCD ;dělič pro klávesnici 64/4=16Hz ; DECFSZ KLVD,F ;-1=0? ; GOTO EKLV ; MOVLW 4 ;znovu ; MOVWF KLVD ; naplnit ;čtení klávesnice ; BSF STATUS,RP0 ;Banka1 ; MOVLW B'11110000' ;1=vstup, 0=výstup ; IORWF TRISB,F ;(0a0=0) ; BCF STATUS,RP0 ;Banka0 ; MOVF PORTB,W ;čtení ; MOVF PORTB,W ;čtení ; MOVF PORTB,W ;čtení ; MOVF PORTB,W ;čtení ; MOVF PORTB,W ;čtení ; MOVF PORTB,W ;čtení ; MOVF PORTB,W ;čtení ; ANDLW B'11110000' ;(1a1=1) ; MOVWF KLVP ;uložit ; BSF STATUS,RP0 ;Banka1 ; MOVLW B'00001111' ;PORTB, 0=výstup, 1=vstup ; ANDWF TRISB,F ;(1a1=1) ; BCF STATUS,RP0 ;Banka0 ;EKLV ;-------------------------------- ;dělič pro blikání displeje ; INCF BLIK,F ;+1 ;-------------------------------- ;dělič pro opakování KLV ; DECFSZ KLVO,F ;-1=0? ; GOTO $+2 ; BSF Znova ;=1 ;-------------------------------- ;dělič 64/64=1Hz ; DECFSZ SEKD,F ;-1=0? ; GOTO EINT ;NE ; MOVLW 64 ;znovu ; MOVWF SEKD ; naplnit ;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS; ; 1Hz, SEKUNDA ; ;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS; ;dělič pro podsvícení ; INCFSZ DPO,F ;+1=0? ; GOTO $+2 ; BCF PO ;VYP podsvícení (po 256sek) ;-------------------------------- ;dělič pro návrat na displej 1 ; MOVF DN,F ; BTFSS STATUS,Z ; DECF DN,F ;-------------------------------- ;sekunda+1 ; INCF Sek,F ;+1 ; MOVF Sek,W ; SUBLW 59 ;59-Sek ; BTFSC SC ;C=0? záporné? ; GOTO EINT ;NE ; CLRF Sek ;=0 ;minuta+1 ; INCF Min,F ;+1 ; MOVF Min,W ; SUBLW 59 ;59-Min ; BTFSC SC ;C=0? záporné? ; GOTO MiEE ;NE ; CLRF Min ;=0 ;hodina+1 ; INCF Hod,F ;+1 ; MOVF Hod,W ; SUBLW 23 ;23-Hod ; BTFSC SC ;C=0? záporné? ; GOTO HoEE ; CLRF Hod ;ANO;=0 ;dny v týdnu+1 ; INCF PoNe,F ;+1 ; MOVF PoNe,W ; SUBLW 6 ;6-PoNe ; BTFSS SC ;C=1? kladné? ; CLRF PoNe ;NE;=0 ;dny+1 ; INCF Den,F ;+1 ; MOVF Den,W ; SUBWF MAXden,W ;MAXden-Den ; BTFSC SC ;C=1?; záporné? ; GOTO DnEE ; MOVLW 1 ;ANO ; MOVWF Den ;=1 ;měsíc+1 ; INCF Mes,F ;+1 ; MOVF Mes,W ; SUBLW 12 ;12-Měsíc ; BTFSC SC ;C=0?; záporné? ; GOTO $+3 ;NE ; MOVLW 1 ;ANO ; MOVWF Mes ;=1 ; PROG0 ; CALL MaxDen ;zjistit max. den v měsíci ; PROG1 ; MOVWF MAXden ;uložit ;................................ ;uložit měsíc do EEPROM ;MeEE MOVLW 0x04 ; MOVWF EEADRp ;adresa ; MOVF Mes,W ;data ; CALL EWR ;zápis ;uložit dny do EEPROM ;DnEE MOVLW 0x02 ; MOVWF EEADRp ;adresa ; MOVF PoNe,W ;data ; CALL EWR ;zápis ; INCF EEADRp,F ; MOVF Den,W ;data ; CALL EWR ;zápis ;uložit hodiny do EEPROM ;HoEE MOVLW 0x01 ; MOVWF EEADRp ;adresa ; MOVF Hod,W ;data ; CALL EWR ;zápis ;uložit minuty do EEPROM ;MiEE CLRF EEADRp ;adresa ; MOVF Min,W ;data ; CALL EWR ;zápis ;-------------------------------- ;konec přerušení EINT MOVF MemPCLATH,W MOVWF PCLATH SWAPF MemSTATUS,W MOVWF STATUS SWAPF MemW,F SWAPF MemW,W RETFIE ;TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT ;KLV CLRWDT ;test KLV + opakovaní, sZ=0=něco stisknuto, 1=žádné tlačítko ; MOVF KLVP,W ; XORLW B'11110000' ;(st.=0) ; BTFSS SZ ;=1?, nenulové? (žádné tlačítko) ; GOTO Neco ;něco stisknuto ; BCF Stisk ;=0 ; BSF Znova ;=1 ; RETURN ;Neco ; MOVLW 30 ;30 sekund ; MOVWF DN ; pro návrat na DIS1 ; CLRF DPO ;časovač pro podsvícení ; ; BTFSC Tl1 ;stisknuto TlS? ; CLRF BLIK ;NE, nulovat ; BSF SZ ;=1 ; BTFSS Znova ;=1? odčasováno? ; RETURN ;NE, jako žádné tl. ;zapnout podsvícení ; BTFSC PO ;podsvícení? ; GOTO $+5 ;zapnuté ; BSF PO ;ZAP ; BCF Znova ;=0 ; CLRF KLVO ;MAX čas (3.4s) ; RETURN ; ; MOVLW 6 ;kratší čas (0.1s) ; BTFSS Stisk ;minule stisknuto? ; MOVLW 64 ;delší čas (1s) ; MOVWF KLVO ;nastavit časovač pro opakování ; BTFSS Tl1 ;stisknuto TlS? ; CLRF KLVO ;ANO, MAX čas (4s) ; BCF Znova ;=0 ; BSF Stisk ;=1 ; BCF SZ ;=0 ; RETURN ;WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ;čekat 15000us C15000 MOVLW 0x13 MOVWF C2 MOVLW 0x5F GOTO CEK ;čekat 4100us C4100 MOVLW 0x05 MOVWF C2 MOVLW 0x49 GOTO CEK ;čekat 1640us C1640 MOVLW 0x02 MOVWF C2 MOVLW 0x1B GOTO CEK ;čekat 480us C480 MOVLW 0xA5 GOTO CEK0 ;čekat 405us C405 MOVLW 0x8A GOTO CEK0 ;čekat 100us C100 MOVLW 0x1E GOTO CEK0 ;čekat 60us C60 MOVLW 0x12 GOTO CEK0 ;čekat 46us C46 MOVLW 0x0D GOTO CEK0 ;čekat 40us C40 MOVLW 0x0B CEK0 CLRF C2 CEK MOVWF C1 ;čekací smyčka, čas určuje hodnota v C1,2 (XTAL=4MHz) CEKEJ DECFSZ C1,F GOTO CEKEJ MOVF C2,W BTFSC SZ RETURN CLRWDT DECF C2,F GOTO CEKEJ ;-------------------------------- ;inicializace LCD po zapnutí INILCD CALL C15000 BCF RS BSF E MOVLW B'00001111' ANDWF PORTB,F MOVLW B'00110000' IORWF PORTB,F BCF E CALL C4100 BSF E BCF E CALL C100 BSF E BCF E CALL C40 MOVLW 0x20 CALL WRCMD MOVLW 0x28 CALL WRCMD MOVLW 0x08 CALL WRCMD MOVLW 0x0C CALL WRCMD MOVLW 0x06 CALL WRCMD RETURN ;-------------------------------- ;zápis dat WRDATA BSF RS ;RS=1=sběrnice pro data GOTO $+2 ;-------------------------------- ;zápis příkazu WRCMD BCF RS ;RS=0=sběrnice pro příkazy MOVWF C3 ;schovat data BSF E ;Enable=1 ;horní půlbyt MOVLW B'00001111' ANDWF PORTB,F MOVF C3,W ANDLW B'11110000' IORWF PORTB,F BCF E ;E=0 BSF E ;E=1 ;dolní půlbyt MOVLW B'00001111' ANDWF PORTB,F SWAPF C3,W ;prohodit půlbyt ANDLW B'11110000' IORWF PORTB,F BCF E ;E=0 ;zjistit čas čekání BTFSC RS ;=0?,šlo o příkaz? GOTO C40 ;NE, šlo o data, čekat 40us MOVF C3,W ;test na příkazy: CLEAR a HOME ANDLW B'11001111' ; (1a1=1) BTFSC SZ ;Z=0=ostatní příkazy? GOTO C1640 ;NE, čekat 1.64ms GOTO C40 ;ANO, čekat 40us ;================================ ;Podprogramy, označené malými písmeny, ;jsou převzaté (upravené) z knihy: ;Komunikace mikrokontrolérů s okolím, ;díl 1. a 2. Jiří Hrbáček ;-------------------------------- ;RESET/PRESENCE ;po Resetu odpoví DS Presence pulzem resds BCF DS ;nastavit ERROR test MOVLW 5 ;počet pokusů MOVWF A1 ; BCF ERP ;nulovat ERROR ;RESET RAM1 ;Banka 1 BCF DS ;=OUT, DS=0 RAM0 ;Banka 0 CALL C480 RAM1 ;Banka 1 BSF DS ;=IN, DS=1 RAM0 ;Banka 0 CALL C60 ;PRESENCE pulz BTFSC DS ;=0?, PRESENCE? BSF ERP ;NE, nastavit ERROR CALL C405 ;ERROR test BTFSS ERP ;=0?, v pořádku? RETURN ;ANO DECFSZ A1,F ;-1=0? GOTO resds+3 ;NE, opakovat RESET RETURN ;ERROR (ERP=1) ;-------------------------------- ;načte bajt z DS do T_RDS rdds MOVLW 8 ;počet bitů MOVWF D2 ; BCF DS rdds1 RAM1 ;Banka 1 BCF DS ;=OUT, DS=0 GOTO $+1 ;čekat 5us GOTO $+1 ; NOP ; BSF DS ;=IN RAM0 ;Banka 0 GOTO $+1 ;čekat 6us GOTO $+1 ; GOTO $+1 ; ;datový bit do SC BCF SC ;Log.0 BTFSC DS ;=1? BSF SC ;ANO, Log.1 RRF T_RDS,F ;SC->T_RDS CALL C46 DECFSZ D2,F ;-1=0? GOTO rdds1 ;NE MOVF T_RDS,W RETURN ;................................ ;načte 2 bity z DS do T_RDS,7,6 RDDS2 CLRF T_RDS MOVLW 2 GOTO rdds+1 ;-------------------------------- ;odeslat bajt z T_RDS do DS wrds MOVWF T_RDS MOVLW 8 ;počet bitů MOVWF D2 ; BCF DS wrds1 RRF T_RDS,F ;->SC RAM1 ;Banka 1 BCF DS ;=OUT, DS=0 RAM0 ;Banka 0 BTFSS SC ;=1? ;poslat nulu CALL C60 ;NE GOTO $+1 ;čekat 2us ;poslat jedničku RAM1 ;Banka 1 BSF DS ;=IN, DS=1 RAM0 ;Banka 0 BTFSC SC ;=0? CALL C60 ;NE DECFSZ D2,F ;-1=0? GOTO wrds1 ;NE RETURN ;................................ ;odeslat bit0 z T_RDS do DS WRDS1 MOVLW 1 GOTO wrds+2 ;-------------------------------- ;výpočet CRC vypcrc MOVF T_RDS,W ;kopírovat MOVWF D1 ; MOVLW 8 ;počte bitů MOVWF D2 ; vypcr0 RRF D1,F ;->SC BTFSC SC ;=0? GOTO vypcr3 ;NE BTFSC CRC,7 ;bit7=0? GOTO vypcr4 ;NE vypcr1 BCF SC RLF CRC,F ;<-SC vypcr2 DECFSZ D2,F ;-1=0? GOTO vypcr0 ;NE RETURN vypcr3 BTFSC CRC,7 ;bit7=0? GOTO vypcr1 ;NE vypcr4 MOVLW B'00011000' XORWF CRC,F ;(st.=0) BSF SC RLF CRC,F ;<-SC GOTO vypcr2 ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK ;odeslat Family kód FKOD MOVLW 0x28 ;kód DS18B20 ;odeslat Identifikační kód (z W) IKOD MOVWF A2 ;kód MOVLW 8 ;počet bitů MOVWF A1 ; CALL RDDS2 ;načte 2 bity do T_RDS MOVF A2,W ;kód MOVWF T_RDS ; CALL WRDS1 ;odešle bit0 z T_RDS RRF A2,F ;kód->, příště další bit DECFSZ A1,F ;-1=0? GOTO $-6 ;NE, znova RETURN ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH ;SEARCH ROM, hledat kód čidla, prvních 8 bitů HLEDAT CLRF IDS ;index, pořadí kódu CLRF D1 ;kód (0 až 255) HLE1 CALL resds ;RESET/PRESENCE MOVLW 0xF0 ;SEARCH ROM CALL wrds ; CALL FKOD ;poslat Family kód ;poslat 1.bajt FF MOVLW 0xFF ;poslat 1.bajt CALL IKOD ; MOVF D1,W ;poslat Identifikační kód CALL IKOD ; CALL RDDS2 ;načte 2 bity z DS do T_RDS,7,6 BTFSC SC ;T_RDS=00? RETURN ;ANO, více DS se stejným kódem XORLW B'11000000' BTFSC SZ ;T_RDS=11? GOTO HLE2 ;ANO, žádný DS s tímto kódem ;uložit kód MOVF IDS,W ;index ADDLW KOD1 ; + adresa RAM (kód 1) MOVWF FSR ; do ukazovátka MOVF D1,W MOVWF INDF ;uložit kód na adresu v ukazovátku ;další kód INCF IDS,F ;index+1 MOVLW PDS ;MAX počet kódů (připojených DS) SUBWF IDS,W ;IDS-PDS BTFSC SC ;=0?, záporné? RETURN ;NE, konec, poslední kód HLE2 INCFSZ D1,F ;kód+1=0? GOTO HLE1 ;NE, další kód RETURN ;TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TEPLOTA BTFSS CONV ;=1?, zapnutý převod? GOTO NTIDS ;NE ;čekat na konec převodu BTFSS DS ;=0?, převod běží? RETURN ;ANO BCF CONV ;-------------------------------- ;načte teplotu podle IDS NTIDS ;zapnout DS, podle ROM kódu CALL resds ;RESET BTFSC ERP ;porucha po RESET/PRESENCE GOTO ZEBIT ;ANO MOVLW 0xF0 ;SEARCH ROM CALL wrds ; CALL FKOD ;poslat Family kód ;poslat 1.bajt FF a dokončit kód zbývajících 40 bitů MOVLW 0xFF ;poslat 1.bajt CALL IKOD MOVF IDS,W ;index čidla ADDLW KOD1 ;index + adresa kódu 1 MOVWF FSR ; do ukazovátka MOVF INDF,W ;načíst kód z adresy v ukazovátku CALL IKOD ;poslat Identifikační kód ;-------------------------------- ;dokončit ROM kód MOVLW 40 ;počet bitů MOVWF A1 ;=sériové číslo-IKOD-1.bajt+CRC (48-8-8+8) CALL RDDS2 ;načte 2 bity do T_RDS,7,6 BTFSC SZ ;T_RDS=00? GOTO ZEBIT ;ANO, nepřípustný stav, jako více DS XORLW B'11000000' ;(st.=0) BTFSC SZ ;T_RDS=11? GOTO ZEBIT ;ANO, nepřípustný stav, jako žádné DS CLRW ;(bude vyslána 0) BTFSC T_RDS,6 ;T_RDS=01? MOVLW 1 ;ANO, bude vyslána 1 MOVWF T_RDS CALL WRDS1 ;odešle 1 bit T_RDS,0 DECFSZ A1,F ;-1=0? GOTO $-12 ;NE ;-------------------------------- ;nová teplota do B1,2 MOVLW 0xBE ;READ SCRATCHPAD CALL wrds ; CLRF CRC ;načte Temperature LSB do B1 CALL rdds MOVWF B1 CALL vypcrc ;načte Temperature MSB do B2 CALL rdds MOVWF B2 CALL vypcrc ;-------------------------------- ;načte zbytek Scratchpad, pro CRC MOVLW 7 ;posledních 7 bajtů MOVWF A1 ; CALL rdds CALL vypcrc DECFSZ A1,F ;-1=0? GOTO $-3 ;NE ;-------------------------------- ;test CRC MOVF CRC,F ;CRC=0=souhlasí BTFSS SZ ;=1? GOTO ZEBIT ;NE, zapnout ERROR bit snímače ;-------------------------------; ; výpočet teploty [°C*10] ;B1,2 * 10 / 16 = A1,2 ;-------------------------------; ;zkušební teplota (0xFC90 = -55.0°C) ; MOVLW 0x90 ; MOVWF B1 ; MOVLW 0xFC ; MOVWF B2 ;-------------------------------- CLRF A1 CLRF A2 ;B1,2 * 10 = A1,2 MOVLW 1 CALL x2W ;(B1,2 * 2 = B1,2) + A1,2 MOVLW 2 CALL x2W ;(B1,2 * 4 = B1,2) + A1,2 ;A1,2 / 16 = A1,2 (MSB=0=kladné, 1=záporné) RLF A2,W ;MSB do SC RRF A2,F ;/2 RRF A1,F ; RLF A2,W ;MSB do SC RRF A2,F ;/4 RRF A1,F ; RLF A2,W ;MSB do SC RRF A2,F ;/8 RRF A1,F ; RLF A2,W ;MSB do SC RRF A2,F ;/16 RRF A1,F ; ;-------------------------------- ;uložit teplotu aktuálního čila (podle IDS) BCF SC RLF IDS,W ;index*2 ADDLW T1L ;+ adresa RAM (teplota 1L) MOVWF FSR ; do ukazovátka MOVF A1,W MOVWF INDF ;uložit teplotu L na adresu v ukazovátku INCF FSR,F ;+1 MOVF A2,W MOVWF INDF ;uložit teplotu H na adresu v ukazovátku ;-------------------------------- ;vypnout ERROR bit aktuálního čidla, 0=EBDS,IDS CALL VBIDS ;vybrat bit podle IDS ;VYP bit COMF A2,W ;(negace) ANDWF EBDS,F ;(1a1=1) ;-------------------------------- ;další čidlo DDS INCF IDS,F ;+1 MOVLW PDS ;MAX počet kódů (připojených DS) SUBWF IDS,W ;IDS-PDS BTFSS SC ;=1?, kladné? RETURN ;NE CLRF IDS ;-------------------------------- ;ZAP převod, CONVERT CALL resds ;RESET MOVLW 0xCC ;SKIP ROMM CALL wrds ; MOVLW 0x44 ;CONVERT TEMPERATURE CALL wrds ; BSF CONV RETURN ; GOTO PR ;program regulace ;-------------------------------- ;zapnout ERROR bit aktuálního čidla, 1=EBDS,IDS ;(ponechá zobrazenou starou teplotu) ZEBIT CALL VBIDS ;vybrat bit podle IDS ;ZAP bit MOVF A2,W IORWF EBDS,F ;(0a0=0) ;-------------------------------- ;počítadlo poruch, používá horních 5 bitů v TxH BCF SC RLF IDS,W ;index*2 ADDLW T1H ; + adresa RAM MOVWF FSR ;ukazovátko na T1H,T2H,T3H... MOVLW 8 ADDWF INDF,F ;TxH + 00001000 (bit7=1=naplněno=zobrazit ERROR) GOTO DDS ;-------------------------------; ; Matematicke podprogramy ; ;-------------------------------; ;slovak@post.cz )S(12.2004; ;-------------------------------; ; A1,2,3 / B1,2,3 = C1,2,3 ;24Bit, pouze kladna cisla ;SZ=1=deleni nulou (B1,2,3=0) ;B se nezmeni, v A bude zbytek ;pouziva D1,2,3; X1 LOMENO24 ;test B na nulu; sZ=1=ANO ; MOVF B1,F ; BTFSC STATUS,Z ;nenulove? ; MOVF B2,F ; BTFSC STATUS,Z ;nenulove? ; MOVF B3,F ; BTFSC STATUS,Z ;nenulove? ; RETURN ;B1,2,3=0 ;priprava pro deleni LOM24 MOVF A1,W ;A do D MOVWF D1 ; MOVF A2,W ; MOVWF D2 ; MOVF A3,W ; MOVWF D3 ; CLRF A1 ;nulovat CLRF A2 ; CLRF A3 ; MOVLW 24 ;pocet bitu MOVWF X1 ; BCF STATUS,C ;SC=0 ;deleni LDalsi CALL x2M ;D,A posun vlevo, A-B=C BTFSS STATUS,C ;kladny vysledek? GOTO LZapor ;NE ;LKlad MOVWF A3 ;C do A MOVF C2,W ; MOVWF A2 ; MOVF C1,W ; MOVWF A1 ; LZapor DECFSZ X1,F ;-1=0? GOTO LDalsi ;jeste neni konec ;vysledek RLF D1,W ;posledni x2 MOVWF C1 ; a W do C RLF D2,W ; MOVWF C2 ; RLF D3,W ; MOVWF C3 ; BCF STATUS,Z ;SZ=0 RETURN ;-------------------------------- ; A1,2,3 / B1,2,3 = C1,2,3 ;23Bit; MSB=0=kladne, 1=zaporne ;SZ=1=deleni nulou (B1,2,3=0) ;B se nezmeni, v A bude zbytek ;pouziva D1,2,3; X1; FL,Azn,Bzn ;LOMENO ;test B na nulu; SZ=1=ANO ; MOVF B1,F ; BTFSC STATUS,Z ;nenulove? ; MOVF B2,F ; BTFSC STATUS,Z ;nenulove? ; MOVF B3,F ; BTFSC STATUS,Z ;nenulove? ; RETURN ;B1,2,3=0 ;test A=zaporne ; BCF Azn ;=0 ; BTFSC A3,7 ;MSB=1? ; CALL ZZA ;zmena znamenka A1,2,3 ;test B=zaporne ; BCF Bzn ;=0 ; BTFSC B3,7 ;MSB=0? ; CALL ZZB ;zmena znamenka B1,2,3 ;vypocet ; CALL LOM24 ;vratit B ; BTFSC Bzn ;=0? ; CALL ZZB ;znamenko C, test Azn = Bzn ; BTFSC Azn ;=0? ; GOTO $+4 ;NE ; BTFSC Bzn ;=0? ; GOTO $+3 ;NE ; GOTO $+3 ;Azn = Bzn = 0 ; BTFSS Bzn ;=1? ; CALL ZZC ;NE, zmena znamenka C1,2,3 ; ; BCF STATUS,Z ;SZ=0 ; RETURN ; ;................................ ; D1,2,3 A1,2,3 * 2 a Minus x2M RLF D1,F ;posuv vlevo RLF D2,F ; RLF D3,F ; RLF A1,F ; RLF A2,F ; RLF A3,F ; ;pokracuje MINUS ;-------------------------------- ; A1,2,3 - B1,2,3 = C1,2,3 ;SC=0=zaporny vysledek ;A,B se nezmeni MINUS MOVF B1,W ;W=B1 SUBWF A1,W ;A1-B1=W MOVWF C1 ;C1=W=vysledek1 CLRW ;W=0 BTFSS STATUS,C ;SUB kladne? MOVLW 1 ;W=1 ADDWF B2,W ;B2+W=W CLRF C3 ;C3=0 BTFSC STATUS,C ;ADD nepreteklo? BSF C3,0 ;C3=1 SUBWF A2,W ;A2-W=W MOVWF C2 ;C2=w=vysledek2 MOVF C3,W ;W=C3 BTFSS STATUS,C ;SUB kladne? MOVLW 1 ;W=1 ADDWF B3,W ;B3+W=W CLRF C3 ;C3=0 BTFSC STATUS,C ;ADD nepreteklo? BSF C3,0 ;C3=1 SUBWF A3,W ;A3-W=W BTFSC C3,0 ;C3=0? BCF STATUS,C ;SC=0 MOVWF C3 ;C3=W=vysledek3 RETURN ;-------------------------------- ; A1,2,3 + C1,2,3 = C1,2,3 ;A se nemeni ;PLUS MOVF A1,W ; ADDWF C1,F ;A1+C1=C1 ; BTFSS STATUS,C ;preteklo? ; GOTO $+4 ; INCFSZ C2,F ;+1=0? ; GOTO $+2 ; INCF C3,F ;+1 ; MOVF A2,W ; ADDWF C2,F ;A2+C2=C2 ; BTFSC STATUS,C ;nepreteklo? ; INCF C3,F ;+1 ; MOVF A3,W ; ADDWF C3,F ;A3+C3=C3 ; RETURN ; ;-------------------------------- ; A1,2,3 * B1,2,3 = C1,2,3 ;24Bit, pouze kladna cisla ;A, B se nezmeni ;pouziva D1,2,3; X1; X2 ;KRAT24 ;schovat A do D ; MOVF A1,W ;A do D ; MOVWF D1 ; ; MOVF A2,W ; ; MOVWF D2 ; ; MOVF A3,W ; ; MOVWF D3 ; ;priprava ; CLRF C1 ;nulovat ; CLRF C2 ; ; CLRF C3 ; ; BCF STATUS,C ; ; MOVLW 25 ;pocet bitu+1 ; MOVWF X1 ; ;hledat jednicku ; RRF B3,F ;posuv vpravo ; RRF B2,F ; ; RRF B1,F ; ; MOVF STATUS,W ;ulozit ; MOVWF X2 ; SC ; BTFSC STATUS,C ;=0? ;A+C=C ; CALL PLUS ;jen pri SC=1 ;A*2 ; RLF A1,F ;posuv vlevo ; RLF A2,F ; ; RLF A3,F ; ; ; MOVF X2,W ;obnovit ; MOVWF STATUS ; SC ; ; DECFSZ X1,F ;-1=0? ; GOTO $-13 ;NE ;obnovit A z D ; MOVF D1,W ;D do A ; MOVWF A1 ; ; MOVF D2,W ; ; MOVWF A2 ; ; MOVF D3,W ; ; MOVWF A3 ; ; RETURN ; ;-------------------------------- ; A1,2,3 * B1,2,3 = C1,2,3 ;23Bit, MSB=0=kladne, 1=zaporne ;A, B se nezmeni ;pouziva D1,2,3; X1; X2 ;KRAT ;test A=zaporne ; BCF Azn ; BTFSC A3,7 ;=0? ; CALL ZZA ;zmena znamenka A ;test B=zaporne ; BCF Bzn ; BTFSC B3,7 ;=0? ; CALL ZZB ;zmena znamenka B ;vypocet ; CALL KRAT24 ;A*B=C ;znamenko A ; BTFSC Azn ;=0? ; CALL ZZA ;znamenko B ; BTFSC Bzn ;=0? ; CALL ZZB ;znamenko C, test Azn = Bzn ; BTFSC Azn ;=0? ; GOTO $+4 ;NE ; BTFSC Bzn ;=0? ; GOTO $+3 ;NE ; GOTO $+3 ;Azn = Bzn = 0 ; BTFSS Bzn ;=1? ; CALL ZZC ;NE, zmena znamenka C1,2,3 ; ; BCF STATUS,Z ;SZ=0 ; RETURN ; ;-------------------------------- ;zmena znamenka A1,2,3 ;ZZA BSF Azn ;=1 ; COMF A1,F ; COMF A2,F ; COMF A3,F ; INCFSZ A1,F ;+1,=0? ; RETURN ; INCFSZ A2,F ;+1,=0? ; RETURN ; INCF A3,F ;+1 ; RETURN ; ;-------------------------------- ;zmena znamenka B1,2,3 ;ZZB BSF Bzn ;=1 ; COMF B1,F ; COMF B2,F ; COMF B3,F ; INCFSZ B1,F ;+1,=0? ; RETURN ; INCFSZ B2,F ;+1,=0? ; RETURN ; INCF B3,F ;+1 ; RETURN ; ;-------------------------------- ;zmena znamenka C1,2,3 ;ZZC COMF C1,F ; COMF C2,F ; COMF C3,F ; INCFSZ C1,F ;+1,=0? ; RETURN ; INCFSZ C2,F ;+1,=0? ; RETURN ; INCF C3,F ;+1 ; RETURN ; ;-------------------------------- ;test C=0; SZ=1=ANO ;TC0 MOVF C3,F ; BTFSC STATUS,Z ;nenulove? ; MOVF C2,F ; BTFSC STATUS,Z ;nenulove? ; MOVF C1,F ; RETURN ;-------------------------------- ;B1,2 * 2^W = B1,2 + A1,2 = A1,2 x2W MOVWF C1 ;kolikrát BCF SC RLF B1,F ;<-SC RLF B2,F ; DECFSZ C1,F ;-1=0? GOTO $-4 ;znova MOVF B1,W ADDWF A1,F ;B1+A1=A1 BTFSC SC ;nepřeteklo? INCF A2,F ;ANO, +1 MOVF B2,W ADDWF A2,F ;B2+A2=A2 RETURN ;-------------------------------- ;vybrat bit, A2=2^IDS VBIDS MOVF IDS,W ;index MOVWF A1 ; CLRF A2 ;A2=2^A1 (A1=MAX 7) BSF SC RLF A2,F ;<-SC DECF A1,F ;-1 COMF A1,W ;(negace) BTFSS SZ ;A1=FF? GOTO $-4 ;NE RETURN ;-------------------------------- ;převod HEX/DEC, vstup A1,2, výstup R1,2,3,4 HEXDEC ;upravit záporné číslo BCF Znam ;=0 BTFSS A2,7 ;=1? GOTO PHD BSF Znam ;=1, záporné ;změna znaménka A1,2 COMF A2,F COMF A1,F INCFSZ A1,F ;+1=0? GOTO PHD INCF A2,F ;+1 ;převod PHD CLRF A3 MOVLW 0xE8 ;1000 do B MOVWF B1 ; MOVLW 0x03 ; MOVWF B2 ; CLRF B3 ; CALL LOMENO24 ;A/B=C, zbytek je v A MOVF C1,W ;uložit řád 1000 MOVWF R4 ; HDPA1 MOVLW 0x64 ;100 do B MOVWF B1 ; CLRF B2 ; CALL LOMENO24 ;A/B=C, zbytek je v A MOVF C1,W ;uložit řád 100 MOVWF R3 ; MOVLW 0x0A ;10 do B MOVWF B1 ; CLRF B2 ; CALL LOMENO24 ;A/B=C, zbytek je v A MOVF C1,W ;uložit řád 10 MOVWF R2 ; MOVF A1,W ;uložit řád 1 MOVWF R1 ; ; RETURN ;PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP P5M MOVF R4,F ;řád 1000 BTFSS SZ ;R4>0? GOTO PR4 ;ANO GOTO PRINT3 ;NE ;PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP PRINT MOVLW 0x20 ;mezera MOVF TE,F BTFSC SZ CALL WRDATA ;TE=0, poslat mezeru PRINT4 MOVF R4,F ;řád 1000 [-4321] BTFSS SZ GOTO PZR4 ;nenulové BTFSC TE3 GOTO PZR4T ;TE3=ZAP MOVLW 0x20 ;mezera CALL WRDATA PRINT3 MOVF R3,F ;řád 100 [-321] BTFSS SZ GOTO PZR3 ;nenulové BTFSC TE2 GOTO PZR3T ;TE2=ZAP MOVLW 0x20 ;mezera CALL WRDATA PRINT2 MOVF R2,F ;řád 10 [-21] BTFSS SZ GOTO PZR2 ;nenulové BTFSC TE1 GOTO PZR2T ;TE1=ZAP MOVLW 0x20 ;mezera CALL WRDATA CALL POZN ;znaménko nebo mezera GOTO PR1 PZR2 CALL POZN ;znaménko nebo mezera PRR2 CALL POR2 ;řád 10 BTFSC TE1 GOTO PTR1 ;TE1=ZAP GOTO PR1 ;TE1=VYP PZR3 CALL POZN ;znaménko nebo mezera CALL POR3 ;řád 100 MOVF TE,F BTFSC SZ GOTO PR21 ;TE=0 PT2T BTFSS TE2 GOTO PR2T ;TE2=VYP GOTO PTR21 ;TE2=ZAP PZR4 CALL POZN ;znaménko nebo mezera PR4 CALL POR4 ;řád 1000 MOVF TE,F BTFSC SZ GOTO PR321 ;TE=0 BTFSC TE3 GOTO PTR321 ;TE3=ZAP CALL POR3 ;řád 100 GOTO PT2T PZR2T CALL POZN ;znaménko nebo mezera PR2T CALL POR2 ;řád 10 PTR1 CALL POTE ;poslat tečku GOTO PR1 PZR3T CALL POZN ;znaménko nebo mezera CALL POR3 ;řád 100 PTR21 CALL POTE ;poslat tečku GOTO PR21 PZR4T CALL POZN ;znaménko nebo mezera CALL POR4 ;řád 1000 PTR321 CALL POTE ;poslat tečku PR321 CALL POR3 ;řád 100 PR21 CALL POR2 ;řád 10 PR1 MOVF R1,W ;řád 1 PIOR IORLW B'000110000' PWRET CALL WRDATA ;PRINT W + RETURN RETURN ;................................ ;poslat znaménko nebo mezeru POZN MOVLW 0x20 ;mezera BTFSC Znam ;záoprné číslo? (Znam=1) MOVLW 0x2D ;- GOTO PWRET ;poslat tečku POTE MOVLW 0x2E ;. GOTO PWRET ;poslat řád 1000 POR4 MOVF R4,W ;řád 1000 GOTO PIOR ;poslat řád 100 POR3 MOVF R3,W ;řád 100 GOTO PIOR ;poslat řád 10 POR2 MOVF R2,W ;řád 10 GOTO PIOR ;blikat při nastavování ;BLIKS BTFSC BLIK,4 ; MOVLW 0x20 ;mezera ; RETURN ;-------------------------------- ;zobrazit ERROR ZERROR MOVLW " " CALL WRDATA MOVLW "C" CALL WRDATA MOVLW "H" CALL WRDATA MOVLW "Y" CALL WRDATA MOVLW "B" CALL WRDATA MOVLW "A" CALL WRDATA MOVLW " " CALL WRDATA RETURN ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII Init ;obnovení RAM z EEPROM 0x00-0x22 ; CLRF EEADRp ;počáteční adresa EEPROM ; MOVLW Min ;počáteční adresa RAM ; MOVWF FSR ; CALL ERead ;čtení ; MOVWF INDF ;zápis ; INCF EEADRp,F ;adresa+1 ; INCF FSR,F ;data+1 ; MOVF EEADRp,W ; SUBLW 0x22 ;poslední adresa EEPROM ; BTFSC SC ;záporné? ; GOTO $-7 ;NE ;základní nastavení procesoru BSF STATUS,RP0 ;Banka1 CLRF INTCON CLRF PIE2 MOVLW B'11101011' ;PORTA, 0=výstup, 1=vstup MOVWF TRISA ; MOVLW B'00000110' ;PORTB, 0=výstup, 1=vstup MOVWF TRISB ; MOVLW B'00000000' ;digi. vstupy MOVWF ANSEL ; MOVLW B'11100101' ;RA0=AN0, RA1=AN1, RA3=Vref+ ; MOVWF ADCON1 ;Configure A/D inputs MOVLW B'01000101' ;předdělič 1:64 pro TMR0 MOVWF OPTION_REG ; MOVLW B'00000000' ;přerušení od MOVWF PIE1 ; BCF STATUS,RP0 ;Banka0 ; MOVLW B'10000011' ;AD časování, výběr AD vstupu, ZAP AD ; MOVWF ADCON0 ; ; MOVLW B'00000000' ;předdělič 1:1 pro TMR1 ; MOVWF T1CON ; ; CLRF PORTB CALL INILCD ;iniciace LCD ; MOVLW 0x01 ; MOVWF DeSR CALL WRCMD ;smazat LCD BSF PORTB,3 ;ZAP podsvícení LCD CLRF TE BSF TE1 MOVLW B'10100000' ;G,TMR0 MOVWF INTCON ;zapnout přerušení ; CLRF Sek ; CALL MaxDen ; MOVWF MAXden ;uložit ; BCF RT0 ; BCF RT1 ; BCF SN ; CLRF DN ; CLRF DPO ; BSF PO ; MOVLW B'11110000' ; MOVWF KLVP ;-------------------------------- ;první řádek MOVLW 0x80 CALL WRCMD MOVLW " " CALL WRDATA MOVLW "H" CALL WRDATA MOVLW "L" CALL WRDATA MOVLW "E" CALL WRDATA MOVLW "D" CALL WRDATA MOVLW "A" CALL WRDATA MOVLW "M" CALL WRDATA MOVLW " " CALL WRDATA MOVLW "I" CALL WRDATA MOVLW "D" CALL WRDATA MOVLW "." CALL WRDATA MOVLW "K" CALL WRDATA MOVLW "O" CALL WRDATA MOVLW "D" CALL WRDATA MOVLW " " CALL WRDATA MOVLW " " CALL WRDATA ;druhý řádek MOVLW 0xC0 CALL WRCMD MOVLW " " CALL WRDATA MOVLW " " CALL WRDATA MOVLW "5" CALL WRDATA MOVLW "x" CALL WRDATA MOVLW " " CALL WRDATA MOVLW " " CALL WRDATA MOVLW "D" CALL WRDATA MOVLW "S" CALL WRDATA MOVLW "1" CALL WRDATA MOVLW "8" CALL WRDATA MOVLW "B" CALL WRDATA MOVLW "2" CALL WRDATA MOVLW "0" CALL WRDATA MOVLW " " CALL WRDATA MOVLW " " CALL WRDATA MOVLW " " CALL WRDATA CLRF T1L CLRF T1H CLRF T2L CLRF T2H CLRF T3L CLRF T3H CLRF T4L CLRF T4H CLRF T5L CLRF T5H CLRF T6L CLRF T6H CLRF T7L CLRF T7H CLRF T8L CLRF T8H CLRF KOD1 CLRF KOD2 CLRF KOD3 CLRF KOD4 CLRF KOD5 CLRF KOD6 CLRF KOD7 CLRF KOD8 CALL HLEDAT ;------------------------------- START CALL TEPLOTA ;načte teplotu z DS ;------------------------------- ;první řádek MOVLW 0x80 ;pozice v LCD CALL WRCMD BTFSS EB1 ;=1?, Error Bit T1? GOTO ZT1 ;NE, zobrazit novou teplotu BTFSS T1H,7 ;=1?, počítadlo poruch naplněno? GOTO NT2 ;NE, zůstane zobrazena minulá teplota CLRF T1H ;nulovat počítadlo poruch CALL ZERROR ;zobrazit ERROR GOTO NT2 ;zobrazit teplotu 1 ZT1 MOVF T1L,W MOVWF A1 MOVF T1H,W MOVWF A2 CALL HEXDEC ;zobrazit teplotu (v A1,2)°C ; CALL P5M MOVLW ZSC CALL WRDATA MOVLW "C" CALL WRDATA MOVLW " " CALL WRDATA MOVLW " " CALL WRDATA MOVLW " " CALL WRDATA ;-------------------------------- NT2 MOVLW 0x89 CALL WRCMD BTFSS EB2 ;=1?, Error Bit T2? GOTO ZT2 ;NE, zobrazit novou teplotu BTFSS T2H,7 ;=1?, počítadlo poruch naplněno? GOTO START ;NE, zůstane zobrazena minulá teplota CLRF T2H ;nulovat počítadlo poruch CALL ZERROR ;zobrazit ERROR GOTO START ;zobrazit teplotu 2 ZT2 MOVF T2L,W MOVWF A1 MOVF T2H,W MOVWF A2 CALL HEXDEC ;zobrazit teplotu (v A1,2)°C ; CALL P5M MOVLW ZSC CALL WRDATA MOVLW "C" CALL WRDATA ;-------------------------------- ;druhý řádek MOVLW 0xC0 CALL WRCMD ;1 MOVLW " " CALL WRDATA SWAPF KOD1,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVF KOD1,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVLW " " CALL WRDATA ;2 SWAPF KOD2,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVF KOD2,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVLW " " CALL WRDATA ;3 SWAPF KOD3,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVF KOD3,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVLW " " CALL WRDATA ;4 SWAPF KOD4,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVF KOD4,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVLW " " CALL WRDATA ;5 SWAPF KOD5,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVF KOD5,W ANDLW B'00001111' addlw 0x06 ; pricti W + 06h -> W btfsc STATUS,DC addlw 0x07 ; DC=1, DC preteklo cisla jsou A - F (W + 07h) addlw 0x2A ; pricti W + 2Ah (W + 06h + 2Ah = 30h) CALL WRDATA MOVLW " " CALL WRDATA ;-------------------------------- GOTO START ;-------------------------------- END