; Bezdrátový teploměr - JEDNOKANÁ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=R3 ;pocitadlo bitu (impulzu) .DEF ZPET1=R4 ;vrati na displej aktualni hodnotu po uvolneni tlacitka .DEF ZPET2=R5 ; .DEF TLAC_PRED=R6 ;pamatuje si stav tlacitek .DEF NULA=R7 ;NULA :) .DEF STAV_PRED=R8 ;registr stavu vstupu pred tim .DEF VYST3=R9 ;registr vystupu 3 .DEF VYST1=R10 ;registr vystupu .DEF VYST2=R11 ;registr vystupu 2 .DEF TERMO1=R12 .DEF TERMO2=R13 .DEF TERMO3=R14 .DEF TERMO4=R15 .DEF REG=R16 .DEF REG2=R17 .DEF KOPIE1=R18 ;kopie vystupu .DEF KOPIE2=R19 ;kopie vystupu 2 .DEF KOPIE3=R20 ;kopie vystupu 3 .DEF MULTREG=R21 .DEF PREVODL=R22 .DEF PREVODH=R23 .DEF CAS=R24 .DEF CAS2=R25 .DEF CAS_P=R26 ;cas pulzu .DEF STAV=R27 ;registr stavu vstupu .DEF STARI=R28 .DEF STARI2=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 TERMO_MAXL=0x0060 .EQU TERMO_MAXH=0x0061 .EQU TERMO_MINL=0x0062 .EQU TERMO_MINH=0x0063 .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,0b001000 OUT SMER2,REG LDI REG,0b110111 OUT PORT2,REG ;nastaví port D LDI REG,0b00011011 OUT SMER3,REG LDI REG,0b11100000 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 CLR STARI2 CLR PREVODL CLR PREVODH LDI REG,0b11 MOV TLAC_PRED,REG SER REG MOV STAV_PRED,REG LDI REG,0b10111111 MOV TERMO1,REG MOV TERMO2,REG MOV TERMO3,REG MOV TERMO4,REG CLR REG STS TERMO_MAXL,REG STS TERMO_MAXH,REG SER REG STS TERMO_MINL,REG STS TERMO_MINH,REG LDI REG,254 MOV ZPET1,REG MOV ZPET2,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: MOVW KOPIE1,VYST1 MOV KOPIE3,VYST3 ;zjisti, zda je to spravny kanal IN REG2,VSTUPY2 ANDI REG2,0b00000100 MOV REG,KOPIE2 ANDI REG,0b00001000 LSR REG CP REG2,REG BREQ SHODA RET SHODA: ;spocita paritni bit (REG) MOVW REG,KOPIE1 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,KOPIE2 SWAP REG2 ANDI REG2,1 ;zjisti, zda paritni bit sedi CP REG2,REG BREQ SHODA2 RET SHODA2: ;vytvori inverzi inverze MOV REG,KOPIE2 MOV REG2,KOPIE3 COM REG COM REG2 LSR REG2 ROR REG LSR REG2 ROR REG LSR REG2 ROR REG LSR REG2 ROR REG LSR REG2 ROR REG ANDI KOPIE2,0b111 ;orizne aby tam byla jen teplota ;zjisti, zda inverze sedi CP REG,KOPIE1 CPC REG2,KOPIE2 BREQ SHODA3 RET SHODA3: MOVW ZPET1,KOPIE1 MOVW PREVODL,KOPIE1 RCALL OBNOV ;obnovi displej dle prijate hodnoty SBI PORT2,3 ;zapne indikator prijimaneho signalu LDI STARI,LOW(6000) ;Nastavi max stari udaje (x 10ms) LDI STARI2,HIGH(6000) ;(znovu ta sama hodnota) RET OBNOV: ;obnoveni ;zjisti, zda nenastalo minimum LDS REG2,TERMO_MINH LDS REG,TERMO_MINL CP PREVODL,REG CPC PREVODH,REG2 BRSH TERMO_MIN_NE STS TERMO_MINH,PREVODH STS TERMO_MINL,PREVODL TERMO_MIN_NE: ;zjisti, zda nenastalo maximum LDS REG2,TERMO_MAXH LDS REG,TERMO_MAXL CP REG,PREVODL CPC REG2,PREVODH BRSH TERMO_MAX_NE STS TERMO_MAXH,PREVODH STS TERMO_MAXL,PREVODL TERMO_MAX_NE: ;zobrazi minimalni nebo maximalni hodnotu ZOBR_MINMAX: SBRC TLAC_PRED,0 RJMP Z_TERMO_MIN_NE LDS PREVODH,TERMO_MINH LDS PREVODL,TERMO_MINL Z_TERMO_MIN_NE: SBRC TLAC_PRED,1 RJMP Z_TERMO_MAX_NE LDS PREVODH,TERMO_MAXH LDS PREVODL,TERMO_MAXL Z_TERMO_MAX_NE: CPI PREVODH,254 ;Kontrola, zda nechybí přijatá hodnota BRNE TERMO_DOBRY3 RJMP TERMO_NIC TERMO_DOBRY3: CPI PREVODL,LOW(2047) ;Kontrola, zda neni nad rozsahem LDI REG,HIGH(2047) CPC PREVODH,REG BRLO TERMO_DOBRY RJMP TERMO_NAD TERMO_DOBRY: CPI PREVODL,LOW(1) ;Kontrola, zda neni pod rozsahem LDI REG,HIGH(1) CPC PREVODH,REG BRSH TERMO_DOBRY2 RJMP TERMO_POD TERMO_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 12) 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 TERMO_POD: ;co kdyz je vysledek pod rozsahem LDI REG,0b11110111 MOV TERMO1,REG ;zobrazi "_" MOV TERMO2,REG MOV TERMO3,REG MOV TERMO4,REG RET TERMO_NAD: ;co kdyz je vysledek nad rozsahem LDI REG,0b11111110 MOV TERMO1,REG ;zobrazi "nad" MOV TERMO2,REG MOV TERMO3,REG MOV TERMO4,REG RET TERMO_NIC: ;co kdyz nebylo nic prijato LDI REG,0b10111111 MOV TERMO1,REG ;zobrazi "-" MOV TERMO2,REG MOV TERMO3,REG MOV TERMO4,REG RET MULTIPLEX: ;multiplex - posun o cifru LDI REG,178 ;f multiplexu = 100Hz OUT TCNT0,REG DEC MULTREG BRNE MULTHOP LDI MULTREG,4 MULTHOP: RCALL MULT RETI MULT: ;multiplex LDI REG,0b11100000 ;vypne vsechny anody OUT PORT3,REG 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 MULT4: OUT PORT,TERMO1 SBI PORT3,0 RET MULT3: MOV REG,TERMO2 ANDI REG,0b01111111 OUT PORT,REG SBI PORT3,1 RET MULT2: OUT PORT,TERMO3 SBI PORT3,3 RCALL TLACITKA ;vyhodnotit tlacitka RET MULT1: OUT PORT,TERMO4 SBI PORT3,4 RCALL INDIKACE RET INDIKACE: SUBI STARI,1 SBCI STARI2,0 BRNE IND_NEVYPR CBI PORT2,3 IND_NEVYPR: 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 MOVW PREVODL,ZPET1 TLAC_MINMAX: RCALL ZOBR_MINMAX TLAC_KONEC: RET TLAC_RESET: CLR REG STS TERMO_MAXL,REG STS TERMO_MAXH,REG SER REG STS TERMO_MINL,REG STS TERMO_MINH,REG LDI REG,0b10111111 MOV TERMO1,REG MOV TERMO2,REG MOV TERMO3,REG MOV TERMO4,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