; Bezdrátový teploměr - DVOUKANÁLOVÝ přijímač ; S kontrolou pomocí inverze a paritního bitu ; ATmega8A / 8 / 8L ; 8MHz interní RC oscilátor ; Vytvořeno 13. III. 2014, upraveno 10. III. 2023 ; autor: DANYK ; http://danyk.cz/avr_btep.html ; -------------------------------------------------- .NOLIST .INCLUDE "m8def.inc" .LIST .DEF BITY=R1 ;pocitadlo bitu (impulzu) .DEF TLAC_PRED=R2 ;pamatuje si stav tlacitek .DEF NULA=R3 ;vždy NULA :) .DEF STAV_PRED=R4 ;registr stavu vstupu pred tim .DEF VYST3=R5 ;registr vystupu 3 .DEF VYST1=R6 ;registr vystupu .DEF VYST2=R7 ;registr vystupu 2 .DEF TERMO1=R8 .DEF TERMO2=R9 .DEF TERMO3=R10 .DEF TERMO4=R11 .DEF TERMO5=R12 .DEF TERMO6=R13 .DEF TERMO7=R14 .DEF TERMO8=R15 .DEF REG=R16 .DEF REG2=R17 .DEF MULTREG=R18 .DEF PREVODL=R20 .DEF PREVODH=R21 .DEF CAS=R22 .DEF CAS2=R23 .DEF CAS_P=R24 ;cas pulzu .DEF STAV=R25 ;registr stavu vstupu .DEF STARI_AL=R26 .DEF STARI_AH=R27 .DEF STARI_BL=R28 .DEF STARI_BH=R29 .EQU SMER=DDRB .EQU PORT=PORTB .EQU SMER2=DDRC .EQU PORT2=PORTC .EQU VSTUPY2=PINC .EQU SMER3=DDRD .EQU PORT3=PORTD .EQU VSTUPY3=PIND .EQU A_MAXL=0x0060 .EQU A_MAXH=0x0061 .EQU A_MINL=0x0062 .EQU A_MINH=0x0063 .EQU B_MAXL=0x0064 .EQU B_MAXH=0x0065 .EQU B_MINL=0x0066 .EQU B_MINH=0x0067 .EQU KOPIE_AL=0x0068 .EQU KOPIE_AH=0x0069 .EQU KOPIE_BL=0x006A .EQU KOPIE_BH=0x006B .CSEG .ORG 0 RJMP START ; vektory preruseni .ORG INT0addr ;preruseni pri zmene na vstupu RJMP SIGNAL .ORG OVF2addr ;preruseni citacem RJMP PRETEK_P .ORG OC1Aaddr ;preruseni citacem RJMP VYHODNOT_PULZ .ORG OC1Baddr ;preruseni citacem RJMP VYHODNOT_VZOREK .ORG OVF1addr ;preruseni citacem RJMP PRETEK_M .ORG OVF0addr ;preruseni citacem0 ridici multiplex. RJMP MULTIPLEX START: ;nastaví port B LDI REG,0xFF OUT SMER,REG LDI REG,0xFF OUT PORT,REG ;nastaví port C LDI REG,0b111000 OUT SMER2,REG LDI REG,0b000111 OUT PORT2,REG ;nastaví port D LDI REG,0b11111011 OUT SMER3,REG LDI REG,0b00000000 OUT PORT3,REG LDI REG,LOW(RAMEND) OUT SPL,REG LDI REG,HIGH(RAMEND) OUT SPH,REG LDI MULTREG,1 ;prednastavi registr stavu multiplexu CLR BITY CLR NULA CLR CAS CLR CAS2 CLR CAS_P CLR STARI_AL CLR STARI_AH CLR STARI_BL CLR STARI_BH LDI REG,0b11 MOV TLAC_PRED,REG SER REG MOV STAV_PRED,REG CLR PREVODL CLR PREVODH LDI REG,0b11111111 MOV TERMO4,REG MOV TERMO8,REG LDI REG,0b10111111 MOV TERMO1,REG MOV TERMO2,REG MOV TERMO3,REG MOV TERMO5,REG MOV TERMO6,REG MOV TERMO7,REG CLR REG STS A_MAXL,REG STS A_MAXH,REG STS B_MAXL,REG STS B_MAXH,REG SER REG STS A_MINL,REG STS A_MINH,REG STS B_MINL,REG STS B_MINH,REG LDI REG,254 STS KOPIE_AL,REG STS KOPIE_AH,REG STS KOPIE_BL,REG STS KOPIE_BH,REG ; NASTAVENI CASOVACE A JEHO PRERUSENI LDI REG,0b00000100 ; preddeli 256 OUT TCCR0,REG ; LDI REG,0b00000000 ; OUT TCCR1A,REG ; LDI REG,0b00000011 ; preddeli 64 OUT TCCR1B,REG ; LDI REG,HIGH(16) ; nastavi porovnavanou hodnotu A OUT OCR1AH,REG ; LDI REG,LOW(16) ; nastavi porovnavanou hodnotu A OUT OCR1AL,REG ; LDI REG,HIGH(64) ; nastavi porovnavanou hodnotu B OUT OCR1BH,REG ; LDI REG,LOW(64) ; nastavi porovnavanou hodnotu B OUT OCR1BL,REG ; LDI REG,0b00000100 ; preddeli 64 OUT TCCR2,REG ; LDI REG,0b01011101 ; povoli preruseni TOIE2, OCIE1A, OCIE1B, TOIE1, TOIE0 OUT TIMSK,REG ; ;NASTAVENI ADC a MCU LDI REG,0b10000001 ;povoli uspani (sleep) a nastavi mod IDLE OUT MCUCR,REG ;reakce INT0 pri jakekoliv zmene LDI REG,0b01000000 ;povoli preruseni INT0 OUT GICR,REG ; ;vypne analog. komparator - neni nikdy vyuzit (setri energii) LDI REG,0b10000000 OUT ACSR,REG SEI ;povoli globalni preruseni ;hlavni smycka SMYCKA: SLEEP RJMP SMYCKA SIGNAL: NOP IN STAV,VSTUPY3 ANDI STAV,0b00000100 CP STAV,STAV_PRED BRNE ZMENIL_SE RETI ZMENIL_SE: MOV STAV_PRED,STAV SBRS STAV,2 RJMP SESTUPNA ; Nabezna hrana _- !!!!!!!!!!!!!! ; ------------------------------------------------------------------ IN CAS,TCNT1L IN CAS2,TCNT1H CPI CAS,16 ;Prah delky zakmitu / kratke mezery CPC CAS2,NULA BRLO KONEC_HRAN OUT TCNT2,NULA RETI ; Sestupna hrana -_ !!!!!!!!!!!!! ; ------------------------------------------------------------------ SESTUPNA: IN CAS,TCNT2 CPI CAS,8 ;Prah delky zakmitu / kratkeho pulzu BRLO KONEC_HRAN OUT TCNT1H,NULA OUT TCNT1L,NULA CPI CAS,128 ;Prah delky dlouheho pulzu / prilis dlouheho pulzu BRLO PULZ_OK CLR VYST1 CLR VYST2 CLR VYST3 CLR BITY CLR CAS_P RJMP KONEC_HRAN PULZ_OK: MOV CAS_P,CAS KONEC_HRAN: RETI VYHODNOT_PULZ: CPI CAS_P,8 ;Prah delky zakmitu / kratkeho pulzu BRLO NEVYHODNOC SBRC STAV,2 RJMP NEVYHODNOC LSL VYST1 ROL VYST2 ROL VYST3 INC BITY CPI CAS_P,32 ;Prah kratkeho / dlouheho pulzu BRLO KRATKY_P INC VYST1 KRATKY_P: NEVYHODNOC: RETI VYHODNOT_VZOREK: SBRC STAV,2 RJMP UKLID_NE RCALL KONTROLA CLR VYST1 CLR VYST2 CLR VYST3 CLR BITY UKLID_NE: RETI PRETEK_P: LDI REG,129 OUT TCNT2,REG RETI PRETEK_M: LDI REG,255 OUT TCNT1H,NULA OUT TCNT1L,REG RETI ;kontrola spravnosti prenosu KONTROLA: LDI REG,24 ;pocet bitu CP BITY,REG ;nesedi-li pocet bitu, zahodi kod BRNE SPATNE_BITY RCALL PRIJEM SPATNE_BITY: RET ;prijeti vzorku se spravnym poctem bitu PRIJEM: ;spocita paritni bit (REG) MOVW REG,VYST1 EOR REG2,REG SWAP REG EOR REG2,REG MOV REG,REG2 LSR REG2 LSR REG2 EOR REG,REG2 MOV REG2,REG LSR REG2 EOR REG,REG2 ANDI REG,1 ;izoluje prijaty paritni bit (REG2) MOV REG2,VYST2 SWAP REG2 ANDI REG2,1 ;zjisti, zda paritni bit sedi CP REG2,REG BREQ SHODA RET SHODA: ;vytvori inverzi inverze MOV REG2,VYST2 COM REG2 COM VYST3 LSR VYST3 ROR REG2 LSR VYST3 ROR REG2 LSR VYST3 ROR REG2 LSR VYST3 ROR REG2 LSR VYST3 ROR REG2 MOV REG,VYST2 ANDI REG,0b111 ;orizne aby tam byla jen teplota ;zjisti, zda se inverze shoduje CP REG2,VYST1 CPC VYST3,REG BREQ SHODA2 RET SHODA2: ;zjisti kanal SBRC VYST2,3 RJMP KANAL_B MOVW PREVODL,VYST1 ANDI PREVODH,0b111 STS KOPIE_AL,PREVODL STS KOPIE_AH,PREVODH RCALL OBNOV_A ;obnovi displej dle prijate hodnoty SBI PORT2,3 ;zapne indikator prijimaneho signalu LDI STARI_AL,LOW(6000) ;Nastavi max stari udaje (x 10ms) LDI STARI_AH,HIGH(6000) ;(znovu ta sama hodnota) RJMP KANAL_A_KONEC KANAL_B: MOVW PREVODL,VYST1 ANDI PREVODH,0b111 STS KOPIE_BL,PREVODL STS KOPIE_BH,PREVODH RCALL OBNOV_B ;obnovi displej dle prijate hodnoty SBI PORT2,4 ;zapne indikator prijimaneho signalu LDI STARI_BL,LOW(6000) ;Nastavi max stari udaje (x 10ms) LDI STARI_BH,HIGH(6000) ;(znovu ta sama hodnota) KANAL_A_KONEC: RET OBNOV_A: ;obnoveni ;zjisti, zda nenastalo minimum LDS REG2,A_MINH LDS REG,A_MINL CP PREVODL,REG CPC PREVODH,REG2 BRSH A_MIN_NE STS A_MINH,PREVODH STS A_MINL,PREVODL A_MIN_NE: ;zjisti, zda nenastalo maximum LDS REG2,A_MAXH LDS REG,A_MAXL CP REG,PREVODL CPC REG2,PREVODH BRSH A_MAX_NE STS A_MAXH,PREVODH STS A_MAXL,PREVODL A_MAX_NE: ;zobrazi minimalni nebo maximalni hodnotu ZOBR_MINMAX_A: SBRC TLAC_PRED,0 RJMP Z_A_MIN_NE LDS PREVODH,A_MINH LDS PREVODL,A_MINL Z_A_MIN_NE: SBRC TLAC_PRED,1 RJMP Z_A_MAX_NE LDS PREVODH,A_MAXH LDS PREVODL,A_MAXL Z_A_MAX_NE: CPI PREVODH,254 ;Kontrola, zda nechybí přijatá hodnota BRNE A_DOBRY3 RJMP A_NIC A_DOBRY3: CPI PREVODL,LOW(2047) ;Kontrola, zda neni nad rozsahem LDI REG,HIGH(2047) CPC PREVODH,REG BRLO A_DOBRY RJMP A_NAD A_DOBRY: CPI PREVODL,LOW(1) ;Kontrola, zda neni pod rozsahem LDI REG,HIGH(1) CPC PREVODH,REG BRSH A_DOBRY2 RJMP A_POD A_DOBRY2: CLR TERMO1 CLR TERMO2 CLR TERMO3 CLR TERMO4 ;zjisti, jestli je teplota zaporna (u MCP9700 cislo do 499) LDI REG2,HIGH(500) CPI PREVODL,LOW(500) CPC PREVODH,REG2 BRLO ZAPORNA ;kladna vcetne nuly (u MCP9700 500 a vic) SUBI PREVODL,LOW(500) ;odecte od hodnoty 500 SBCI PREVODH,HIGH(500) RJMP KLADNA_KONEC ZAPORNA: LDI REG,LOW(500) ;odecte hodnotu od 500 LDI REG2,HIGH(500) SUB REG,PREVODL SBC REG2,PREVODH MOVW PREVODL,REG LDI REG,10 MOV TERMO4,REG ;na cifre 4 zobrazi minus (kod 10) KLADNA_KONEC: ZNOVU1000: CPI PREVODL,LOW(1000) LDI REG,HIGH(1000) CPC PREVODH,REG ;16-bitova podminka mensi nez 1000 BRLO POD1000 SUBI PREVODL,LOW(1000) ;16-bitove odcitani čísla 1000 od vysledku SBCI PREVODH,HIGH(1000) INC TERMO4 RJMP ZNOVU1000 POD1000: ZNOVU100: CPI PREVODL,LOW(100) LDI REG,HIGH(100) CPC PREVODH,REG ;16-bitova podminka mensi nez 100 BRLO POD100 SUBI PREVODL,LOW(100) ;16-bitove odcitani čísla 100 od vysledku SBCI PREVODH,HIGH(100) INC TERMO3 RJMP ZNOVU100 POD100: ZNOVU10: CPI PREVODL,10 ;8-bitova podminka mensi nez 10 BRLO POD10 SUBI PREVODL,10 ;8-bitove odcitani čísla 10 od vysledku INC TERMO2 RJMP ZNOVU10 POD10: MOV REG,PREVODL RCALL ZOBRAZ MOV TERMO1,REG MOV REG,TERMO2 RCALL ZOBRAZ MOV TERMO2,REG MOV REG,TERMO3 RCALL ZOBRAZ MOV TERMO3,REG MOV REG,TERMO4 CPI REG,0 BREQ POTLAC0 RCALL ZOBRAZ RJMP NENULOVE POTLAC0: LDI REG,0b11111111 NENULOVE: MOV TERMO4,REG RET A_POD: ;co kdyz je vysledek pod rozsahem LDI REG,0b11111111 MOV TERMO4,REG LDI REG,0b11110111 MOV TERMO1,REG ;zobrazi "_" MOV TERMO2,REG MOV TERMO3,REG RET A_NAD: ;co kdyz je vysledek nad rozsahem LDI REG,0b11111111 MOV TERMO4,REG LDI REG,0b11111110 MOV TERMO1,REG ;zobrazi "nad" MOV TERMO2,REG MOV TERMO3,REG RET A_NIC: ;co kdyz nebylo nic prijato LDI REG,0b11111111 MOV TERMO4,REG LDI REG,0b10111111 MOV TERMO1,REG ;zobrazi "-" MOV TERMO2,REG MOV TERMO3,REG RET OBNOV_B: ;obnoveni B ;zjisti, zda nenastalo minimum LDS REG2,B_MINH LDS REG,B_MINL CP PREVODL,REG CPC PREVODH,REG2 BRSH B_MIN_NE STS B_MINH,PREVODH STS B_MINL,PREVODL B_MIN_NE: ;zjisti, zda nenastalo maximum LDS REG2,B_MAXH LDS REG,B_MAXL CP REG,PREVODL CPC REG2,PREVODH BRSH B_MAX_NE STS B_MAXH,PREVODH STS B_MAXL,PREVODL B_MAX_NE: ;zobrazi minimalni nebo maximalni hodnotu ZOBR_MINMAX_B: SBRC TLAC_PRED,0 RJMP Z_B_MIN_NE LDS PREVODH,B_MINH LDS PREVODL,B_MINL Z_B_MIN_NE: SBRC TLAC_PRED,1 RJMP Z_B_MAX_NE LDS PREVODH,B_MAXH LDS PREVODL,B_MAXL Z_B_MAX_NE: CPI PREVODH,254 ;Kontrola, zda nechybí přijatá hodnota BRNE B_DOBRY3 RJMP B_NIC B_DOBRY3: CPI PREVODL,LOW(2047) ;Kontrola, zda neni nad rozsahem LDI REG,HIGH(2047) CPC PREVODH,REG BRLO B_DOBRY RJMP B_NAD B_DOBRY: CPI PREVODL,LOW(1) ;Kontrola, zda neni pod rozsahem LDI REG,HIGH(1) CPC PREVODH,REG BRSH B_DOBRY2 RJMP B_POD B_DOBRY2: CLR TERMO5 CLR TERMO6 CLR TERMO7 CLR TERMO8 ;zjisti, jestli je teplota zaporna (u MCP9700 cislo do 499) LDI REG2,HIGH(500) CPI PREVODL,LOW(500) CPC PREVODH,REG2 BRLO ZAPORNA_B ;kladna vcetne nuly (u MCP9700 500 a vic) SUBI PREVODL,LOW(500) ;odecte od hodnoty 500 SBCI PREVODH,HIGH(500) RJMP KLADNA_KONEC_B ZAPORNA_B: LDI REG,LOW(500) ;odecte hodnotu od 500 LDI REG2,HIGH(500) SUB REG,PREVODL SBC REG2,PREVODH MOVW PREVODL,REG LDI REG,10 MOV TERMO8,REG ;na cifre 4 zobrazi minus (kod 10) KLADNA_KONEC_B: ZNOVU1000B: CPI PREVODL,LOW(1000) LDI REG,HIGH(1000) CPC PREVODH,REG ;16-bitova podminka mensi nez 1000 BRLO POD1000B SUBI PREVODL,LOW(1000) ;16-bitove odcitani čísla 1000 od vysledku SBCI PREVODH,HIGH(1000) INC TERMO8 RJMP ZNOVU1000B POD1000B: ZNOVU100B: CPI PREVODL,LOW(100) LDI REG,HIGH(100) CPC PREVODH,REG ;16-bitova podminka mensi nez 100 BRLO POD100B SUBI PREVODL,LOW(100) ;16-bitove odcitani čísla 100 od vysledku SBCI PREVODH,HIGH(100) INC TERMO7 RJMP ZNOVU100B POD100B: ZNOVU10B: CPI PREVODL,10 ;8-bitova podminka mensi nez 10 BRLO POD10B SUBI PREVODL,10 ;8-bitove odcitani čísla 10 od vysledku INC TERMO6 RJMP ZNOVU10B POD10B: MOV REG,PREVODL RCALL ZOBRAZ MOV TERMO5,REG MOV REG,TERMO6 RCALL ZOBRAZ MOV TERMO6,REG MOV REG,TERMO7 RCALL ZOBRAZ MOV TERMO7,REG MOV REG,TERMO8 CPI REG,0 BREQ POTLAC0B RCALL ZOBRAZ RJMP NENULOVEB POTLAC0B: LDI REG,0b11111111 NENULOVEB: MOV TERMO8,REG RET B_POD: ;co kdyz je vysledek pod rozsahem LDI REG,0b11111111 MOV TERMO8,REG LDI REG,0b11110111 MOV TERMO5,REG ;zobrazi "_" MOV TERMO6,REG MOV TERMO7,REG RET B_NAD: ;co kdyz je vysledek nad rozsahem LDI REG,0b11111111 MOV TERMO8,REG LDI REG,0b11111110 MOV TERMO5,REG ;zobrazi "nad" MOV TERMO6,REG MOV TERMO7,REG RET B_NIC: ;co kdyz nebylo nic prijato LDI REG,0b11111111 MOV TERMO8,REG LDI REG,0b10111111 MOV TERMO5,REG ;zobrazi "-" MOV TERMO6,REG MOV TERMO7,REG RET MULTIPLEX: ;multiplex - posun o cifru LDI REG,217 ;f multiplexu = 100Hz OUT TCNT0,REG DEC MULTREG BRNE MULTHOP LDI MULTREG,8 MULTHOP: ;multiplex OUT PORT3,NULA ;vypne vsechny anody CBI PORT2,5 LDI ZL,LOW(MULT_SKOK-1) ;vetveni, ktera cifra se rozsviti LDI ZH,HIGH(MULT_SKOK-1) ADD ZL,MULTREG ADC ZH,NULA IJMP MULT_SKOK: RJMP MULT1 RJMP MULT2 RJMP MULT3 RJMP MULT4 RJMP MULT5 RJMP MULT6 RJMP MULT7 RJMP MULT8 MULT1: OUT PORT,TERMO1 SBI PORT3,0 RETI MULT2: MOV REG,TERMO2 ANDI REG,0b01111111 ;rozsviti tecku OUT PORT,REG SBI PORT3,1 RETI MULT3: OUT PORT,TERMO3 SBI PORT3,3 RCALL TLACITKA ;vyhodnotit tlacitka RETI MULT4: OUT PORT,TERMO4 SBI PORT3,4 RETI MULT5: OUT PORT,TERMO5 SBI PORT3,5 RETI MULT6: MOV REG,TERMO6 ANDI REG,0b01111111 ;rozsviti tecku OUT PORT,REG SBI PORT3,6 RETI MULT7: OUT PORT,TERMO7 SBI PORT3,7 RETI MULT8: OUT PORT,TERMO8 SBI PORT2,5 RCALL INDIKACE RETI INDIKACE: SBIW STARI_AL,1 BRNE IND_NEVYPR_A CBI PORT2,3 IND_NEVYPR_A: SBIW STARI_BL,1 BRNE IND_NEVYPR_B CBI PORT2,4 IND_NEVYPR_B: RET ; vyhodnoti tlacitka TLACITKA: CLR REG2 IN REG,VSTUPY2 ANDI REG,0b11 CPSE REG,TLAC_PRED SER REG2 MOV TLAC_PRED,REG CPI REG,0b00 BREQ TLAC_RESET CPI REG2,255 BRNE TLAC_KONEC CPI REG,0b11 BRNE TLAC_MINMAX LDS PREVODL,KOPIE_AL LDS PREVODH,KOPIE_AH RCALL ZOBR_MINMAX_A LDS PREVODL,KOPIE_BL LDS PREVODH,KOPIE_BH RCALL ZOBR_MINMAX_B RET TLAC_MINMAX: RCALL ZOBR_MINMAX_A RCALL ZOBR_MINMAX_B TLAC_KONEC: RET TLAC_RESET: CLR REG STS A_MAXL,REG STS A_MAXH,REG STS B_MAXL,REG STS B_MAXH,REG SER REG STS A_MINL,REG STS A_MINH,REG STS B_MINL,REG STS B_MINH,REG LDI REG,0b11111111 MOV TERMO4,REG MOV TERMO8,REG LDI REG,0b10111111 MOV TERMO1,REG MOV TERMO2,REG MOV TERMO3,REG MOV TERMO5,REG MOV TERMO6,REG MOV TERMO7,REG RET ; Prevod BCD na 7segmentu ZOBRAZ: CPI REG,11 BRLO ZOBRAZ_JE_OK LDI REG,11 ZOBRAZ_JE_OK: LDI ZH,HIGH(2*TABULKA) LDI ZL,LOW(2*TABULKA) ADD ZL,REG ADC ZH,NULA LPM REG,Z RET ; tabulka znakove sady TABULKA: .DB 0b11000000,0b11111001 ;0, 1 .DB 0b10100100,0b10110000 ;2, 3 .DB 0b10011001,0b10010010 ;4, 5 .DB 0b10000010,0b11111000 ;6, 7 .DB 0b10000000,0b10010000 ;8, 9 .DB 0b10111111,0b10000110 ;-, E