; **********************************************************************
; Thermoschalter für Heiz- oder Kühlbetrieb
; Platine: thermostat_mit_tiny13_und_relais.cdr
; PB2: relais über BC548 (NPN 40V - 0,1A)
; PB3: NTC-Widerstand in Reihe mit 10k -> 2,66V Mittenspannung
;      bei Raumtemperatur
; PB4: Poti an GND..+5V gibt Schaltschwelle vor
; PB1: Jumper nicht gesetzt -> Heizen (1)
;	   Jumper gesetzt -> Kühlen	(0)
; **********************************************************************
; Autor:    Jürgen Grzesina, KRS Neumarkt/OPf
; Lizenz:   General Public License (GPL)
; Garantie: keinerlei Garantie für Funktion und/oder Anwendbarkeit
; Haftung:  keinerlei Haftung für körperliche Schäden oder Sachschäden,
;           die durch Anwendung der Schaltung und des Programms entstehen
; HINWEIS:  An der Schaltung kann eine Spannung von 250V anliegen
;           Das bedeutet LEBENSGEFAHR bei unsachgemäßem Umgang
;		    Für den Einsatz ist auf isolierten Einbau ist zu achten!       
; **********************************************************************
; Programmversion 0.1
; Stand: 2013-10-25
; **********************************************************************
;
.nolist
.include "tn13def.inc"
.list

.def vorgabe = r17
.def NTC 	 = r18

.equ jumper = 1
.equ relais = 2
.equ sensor = 3
.equ poti 	= 4
.equ port 	= portb
.equ input	= pinb
.equ ddr  	= ddrb


.equ hysterese = 2		; Schaltschwelle für Kühlung deaktivieren
						; Heizung aktivieren

.equ XTAL = 4800000/8 	; ChkSel = 0b10 und SUT = 0b10 (14CK + 64 ms)
.equ takt = Xtal

; .eseg					; Werte für das EEPROM
						; werden wir vorerst nicht nutzen

.dseg
.org 0x60				; SRAM beginnt hinter den Registern
;flags: .byte 1			; Programmmerker
kuehlung: .byte 1		; kühlen = 0
						; heizen = 1



.cseg					; jetzt erzeugen wir Code für den Flash-Bereich
.org 0x0000
	rjmp start
; rjmp EXT_INT0 		; IRQ0 Handler
; rjmp PCINT0 			; PCINT0 Handler
; rjmp TIM0_OVF 		; Timer0 Overflow Handler
; rjmp EE_RDY 			; EEPROM Ready Handler
; rjmp ANA_COMP 		; Analog Comparator Handler
.org 0x0006
 rjmp TIM0_COMPA 		; Timer0 CompareA Handler
; rjmp TIM0_COMPB 		; Timer0 CompareB Handler
; rjmp WATCHDOG 		; Watchdog Interrupt Handler
; rjmp ADCH 			; ADC Conversion Handler


.org 0x000a				; hinter allen IRQ-Vektoren
start:
	ldi r16, low(ramend)
	out spl, r16

init:
	ldi r16, (1<<relais) 				; Pin als Ausgang schalten und
	out ddr, r16						; PB1 ist Eingang, 
	ldi r16, (1<<jumper)				; Pullup einschalten für PB1
	out port, r16						; relais aus

	clr r16								; Auf kühlen stellen
	sbic input, jumper					; Jumper-Bit einlesen, Bit=0, kühlen
	ldi r16, 1							; Jumper ist abgezogen, Bit ist eins, heizen
	sts kuehlung,r16					; Funktion abspeichern
	
	; Temperaturmessung vorbereiten
	ldi r16, (1<<adc2d) | (1<<adc3d)	; ADC2:3 an Bit PB4:3, sind nicht digital
	out didr0, r16
	ldi r16, 0x00
	out adcsrb, r16						; kein Triggering 
										; ADate = 0 in ADCSRA -> ADC im Singlemode
	cli									; keine IRQs, wir machen alles 
										; in der Jobschleife

loop:
	ldi r16, (1<<adlar) | (1<<mux1)	
										; Result leftadjusted, ADC2=PB4=input
	out admux, r16
	ldi r16, (1<<aden) | (1<<adif) | (1<<adps1)
	out adcsra, r16						; ADC ein, AD-IRQ-Flag löschen, 
										; Vorteiler = 4 -> ca. 4,8MHz:8:4=150kHz
	in r16, adcsra
	sbr r16, (1<<adsc)
	out adcsra, r16						; starte eine Wandlung
warte_auf_poti_fertig:	
	in r16, adcsra						; poti einlesen
	andi r16, 1<<adsc					; adcs-Bit maskieren
	brne warte_auf_poti_fertig
	;
	in vorgabe, adch					; Analogwert einlesen
										; Potivorgabe merken


	ldi r16, (1<<adlar) | (1<<mux1) | (1<<mux0)
										; Result leftadjusted, ADC3=PB3=input
	out admux, r16
	ldi r16, (1<<aden) | (1<<adif) | (1<<adps1)
	out adcsra, r16						; ADC ein, AD-IRQ-Flag löschen, 
										; Vorteiler = 4 -> ca. 4,8MHz:8:4=150kHz
	in r16, adcsra
	sbr r16, (1<<adsc)
	out adcsra, r16						; starte eine Wandlung
warte_auf_NTC_fertig:	
	in r16, adcsra						; poti einlesen
	andi r16, 1<<adsc					; adcs-Bit maskieren
	brne warte_auf_NTC_fertig
	;
	in NTC, adch						; Analogwert einlesen
										; NTC-Wert merken

	clr r16								; Auf kühlen stellen
	sbic input, jumper					; Jumper-Bit einlesen, Bit=0, kühlen
	ldi r16, 1							; Jumper ist abgezogen, Bit ist eins, heizen
	sts kuehlung,r16					; Funktion abspeichern

	lds r16, kuehlung
	tst r16
	brne heizen

kuehlen:
	; wenn der NTC-Widerstand sinkt mit steigender Temperatur 
	; Der NTC liegt gegen Masse, die Spannung an ADC3/PB2 sinkt, wenn die 
	; Temperatur steigt. Das Poti gibt die Schaltschwelle an, ab deren 
	; Unterschreitung das Relais eingeschaltet werden muss, damit der
	; Kompressor/Peltierkonverter arbeiten kann.
	; Ein Senken der Spannung am Potieingang ADC3/PB4 bedeutet daher auch 
	; dass das Relais bei bei einer höheren Temperatur einschaltet.
	; Die Potispannung wird gesenkt, beim Drehen der Spindel 
	; im Gegen-Uhrzeigersinn. 
	; Im Uhrzeigersinn drehen -> niedrigere Schaltschwelle

	cp NTC, vorgabe						; NTC-wert < Potiwert?
	brlo relais_ein						; Kühlung aktivieren
	ldi r16, hysterese					; Wenn einige Zeit gekühlt wurde,
	add r17, r16						; steigt die Spannung an PB2
	cp NTC, vorgabe						; Wenn die Hystereseschwelle 
										; überschritten wird, kann man
 	brsh relais_aus						; die Kühlung wieder ausschalten
	rjmp loop							; Hystereseschwelle noch nicht 
										; erreicht? Warten, gar nix machen
 
heizen:
	; wenn der NTC-Widerstand sinkt mit steigender Temperatur 
	; Der NTC liegt gegen Masse, die Spannung an ADC3/PB2 sinkt, wenn die 
	; Temperatur steigt. Das Poti gibt die Schaltschwelle an, ab deren 
	; Unterschreitung das Relais ausgeschaltet werden muss, damit die
	; Heizwendel deaktiviert wird.
	; Ein Senken der Spannung am Potieingang ADC3/PB4 bedeutet daher auch 
	; dass das Relais bei bei einer höheren Temperatur abschaltet.
	; Die Potispannung wird gesenkt, beim Drehen der Spindel 
	; im Gegen-Uhrzeigersinn. 
	; Im Uhrzeigersinn drehen -> niedrigere Schaltschwelle

	cp NTC, vorgabe						; NTC-wert < Potiwert?
	brsh relais_ein 					; Heizung aktivieren
	ldi r16, hysterese					; Wenn die Temperatur gestiegen ist,
	sub vorgabe, r16					; sinkt die Spannung an PB2
	cp NTC, vorgabe						; Wenn die Hystereseschwelle 
										; unterschritten wird, muss man
 	brlo relais_aus						; die Heizung wieder 
										; ausschalten
	rjmp loop							; Hystereseschwelle noch nicht 
										; erreicht? Warten, gar nix machen
relais_aus:
	in r16, port
	cbr r16, (1<<relais)
	out port, r16						; relais ausschalten
	rjmp loop

relais_ein:
	in r16, port
	sbr r16, (1<<relais) 
	out port, r16						; relais ausschalten
	rjmp loop

; ****************************************************************************

tim0_compa:								; wird jetzt noch nicht benötigt
	reti

.exit
