Forum: Mikrocontroller und Digitale Elektronik Temperaturschalter mit atmega8 (Assembler)


von Stefan (Gast)


Lesenswert?

Hallo, ich will einen Kühlschrank auf 40°C temperieren. Mit einem NTC 
und einem Widerstand wird ein Pegel erzeugt, den der Atmega8 umwandelt. 
Mit dem folgenden Programm soll der Atmega8 die Heizung über 40°C 
ausschalten und unter 40°C einschalten. Nur irgendwie bekomme ich unter 
40°C ein Rechtecksignal auf meiner Platine (im Simulator nicht). 
Schonmal Danke im Vorraus.
1
  ldi    r16,  0xFF
2
  out    DDRD,  r16
3
  sbi    DDRB,  0
4
5
  ldi    r16,  (1<<REFS0) | (0<<REFS1)
6
  out    ADMUX,  r16
7
8
  ldi    r16,  (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0)
9
  out    ADCSRA, r16
10
11
  ldi    r18,  LOW(400)
12
  ldi    r19,  HIGH(400)
13
 Main:
14
15
; neuen ADC-Wert lesen
16
    sbi     ADCSRA, ADSC        ; den ADC starten
17
 
18
wait_adc:
19
  sbic    ADCSRA, ADSC    ; ADC fertig -> Bit wird gelöscht
20
    rjmp    wait_adc
21
22
; ADC einlesen:
23
        in      adlow, ADCL
24
        in      adhigh, ADCH
25
26
; Auswertung:
27
  cp    adlow,  r18
28
  cpc    adhigh,  r19
29
  brsh  Heizung_Ein
30
  brlo  Heizung_Aus
31
    rjmp    Main
32
 
33
34
Heizung_Ein:
35
  ldi    r16,  0x00
36
  out    portd,  r16
37
  rjmp  Main
38
Heizung_Aus:
39
  ldi    r16,  0xff
40
  out    portd,  r16
41
  rjmp  Main

von Falk B. (falk)


Lesenswert?

@  Stefan (Gast)

>Hallo, ich will einen Kühlschrank auf 40°C temperieren.

Ist das dann noch ein KÜHLschranl?

>Mit dem folgenden Programm soll der Atmega8 die Heizung über 40°C
>ausschalten und unter 40°C einschalten. Nur irgendwie bekomme ich unter
>40°C ein Rechtecksignal auf meiner Platine (im Simulator nicht).
>Schonmal Danke im Vorraus.

Das klappt so nicht. Wenn die Schaltschwellen nach oben und unten gleich 
ist,  dann "flattert" dein Ausgang beim Übergang. Was di brauchst ist 
eine Hysterese, sprich verschiedene Schaltschwellen für An und 
ausschalten. Z.B. bei 41 Grad ausschalten und bei 39 wieder einschalten. 
Siehe Schmitt-Trigger.

MFG
Falk

von Stefan (Gast)


Lesenswert?

>Wenn die Schaltschwellen nach oben und unten gleich
>ist,  dann "flattert" dein Ausgang beim Übergang.

Stimmt ja, wenn ich ziemlich genau bei 40°C liege. Zum testen habe ich 
den NTC auf ca 60°C erwärmt und auf 25°C abgekühlt. Somit dürfte es 
wenn, nur im Übergang "flattern". Ich habe aber bei 25°C immer noch ein 
Rechtecksignal obwohl dies doch nicht sein dürfte oder?

von Falk B. (falk)


Lesenswert?

@ Uhu Uhuhu (uhu)

>Kann es sein, daß eine Ausgabe eines 1-Bits auf Portd das Bit toggelt?

Nöö, das macht bestenfalls PIND. Aber nicht beim MEGA8.

MFg
Falk

von Uhu U. (uhu)


Lesenswert?

Stimmt.

Ist der Controllertyp richtig eingestell?

von Stefan (Gast)


Lesenswert?

ich mein schon

.include "m8def.inc"

von Uhu U. (uhu)


Lesenswert?

Dann sieh dir mal den Maschinencode im Dump-Fenster an und suche die 
I/O-Registeradresse, auf die der Befehl "out    portd,  r16" schreibt 
und vergleiche sie mit der Adresse des Portd des Atmega8.

von Stefan (Gast)


Lesenswert?

aus m8def.inc
.equ  PORTD  =$12


73:         out    portd,  r16
+00000024:   BB02        OUT     0x12,R16         Out to I/O location

sie stimmen überein oder habe ich dich falsch verstanden?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Willst Du in der Tat den ganzen PortD setzen oder löschen? Normal macht 
man das doch nur mit einem Pin. In dem Fall kann man auch z.B.

sbi PortD, 0  ;Pin setzen
oder
cbi PortD, 0  ;Pin löschen

schreiben.

von Stefan (Gast)


Lesenswert?

Nur leider ändert es nicht's an meinem Rechtecksignal. Ich glaube dass 
ich den A/D-Wandler falsch benutze, den der A/D-Wandler muss doch das 
Signal zum Ein oder Ausschalten geben. Wenn ich den Port direkt auf 0 
oder 1 setze, dann funktioniert es ja. Es "flattert auch nicht". Das 
Problem tritt erst auf, wenn ich den A/D-Wandler zwischen schalte.

von Uhu U. (uhu)


Lesenswert?

Stefan wrote:
> aus m8def.inc
> .equ  PORTD  =$12
>
>
> 73:         out    portd,  r16
> +00000024:   BB02        OUT     0x12,R16         Out to I/O location
>
> sie stimmen überein oder habe ich dich falsch verstanden?

Wenn du wirklich wissen willst, was im Code steht, solltest du nicht in 
irgend welchen Listings nachsehen, sondern direkt in dem, was im 
Flashmemory deines Controllers steht, denn das wird ausgeführt und nicht 
unbedingt das, was man denkt ;-)

Wenn dir das zu kompliziert ist, kannst du ja mal folgenden Befehl 
schreiben:

   out   $12,R16

Das Rechtecksignal erweckt bei mir den Eindruck, daß du statt PortD PinD 
erwischst und der Simulator automatisch die richtige Einstellung 
übernimmt, die Hardware sich aber nicht weiter darum kümmert...


@ Travel Rec.

Das ist zwar richtig, aber behebt wohl kaum das Problem...

von Jens (Gast)


Lesenswert?

Ich habe das ganze mal gelöst, aber ich denke dass dein Problem 
irgendwie der ADC ist, du bildest ja keinen Mittelwert oder?
Irgendwelche Störeinflüsse beim Messen, die einzelne Werte komplett 
ungültig machen würden?
Wenn du dann noch die Schleife endlos durchlaufen lässt und den Wert 
sozusagen alle paar ms updatest, dann kanns natürlich sein dasses öfters 
flattert, jenachdem was dein ADC grad an Störungsmüll auffängt.



Ich denke das müsste gehn...
temperatur 1 würde deinem ADC-Mittelwert entsprechen, welchen du 
ausrechnen solltest
1
eHeizung:
2
       
3
       lds temp, temperatur1
4
5
       Sbis portb, PB0 ;skip if PB0=1(Heizung an)
6
       subi temp, 10
7
     
8
9
       sbic portb, PB0 ;skip if PB0=0
10
       subi temp, -10
11
       
12
13
14
     cp t1, temp
15
     brsh uAus  ;same or higher
16
     brlo uAn   ;lower
17
18
19
       
20
uAus:
21
     cbi Portb, PB0 ;clear bit
22
     ret
23
24
25
uAn:
26
     sbi Portb, PB0 ; set bit
27
     ret
28
29
30
.ESEG
31
Temperatur0:  .db     160
32
33
.DSEG                
34
Temperatur1:  .BYTE  1

Gruß Jens

von Stefan (Gast)


Lesenswert?

ich hab den Befehl mal eingegeben (das andere ist mir zu kompliziert)

Ich hab mal was ausprobiert:
wenn ich eine Led anschließe, dann flackert diese
wenn ich eine Led mit Widerstand (470ohm), dann flackert diese nicht
wenn ich mit einer Led und dem Widerstand einen Transisor schalte, der 
eine weitere LED schaltet dann flackern beide
ich weiß nicht ob das weiterhilft

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Dumme Frage: Hast Du alle Masse- und Vcc-Anschlüsse angeschlossen, also 
auch Avcc? Blockkondensatoren an allen Betriebsspannungsanschlüssen? 
ARef mit Kondensator nach Masse beschaltet?

von Uhu U. (uhu)


Lesenswert?

Was passiert, wenn du die ADC-Befehle auskommentierst und stattdessen 
adlow/adhigh mit einem Wert unter 400 lädst?

Poste mal die Schaltung und das komplette Programm.

von Stefan (Gast)


Lesenswert?

>Hast Du alle Masse- und Vcc-Anschlüsse angeschlossen, also
>auch Avcc?
ja

>ARef mit Kondensator nach Masse beschaltet?
ja

>Blockkondensatoren an allen Betriebsspannungsanschlüssen?
wie ist das gemeint? Ich habe Vcc mit meiner Spannungsquelle verbunden 
und über einen 47ohm Widerstand mit AVcc verbunden (statt Spule hieß es 
irgendwo im internet)
AVcc habe ich über einen Folienkondensator mit Masse verbunden.
Im Anhang ist der Eagle Schaltplan

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Der Schaltplan

von Stefan (Gast)


Lesenswert?

1
.NOLIST                     ; List-Output unterdrücken
2
 .INCLUDE "m8def.inc"      ; das gibt es für jeden Controllertyp
3
 .LIST                      ; List-Output wieder aufdrehen
4
  .def adlow=r20
5
  .def adhigh=r21
6
.CSEG                      ; was nun folgt, gehört in den FLASH-Speicher
7
8
 ;------------------------------------------------------
9
 ;     Start Adresse 0000
10
 ;------------------------------------------------------
11
.org 0x000
12
.org 0x00E
13
  rjmp   INIT           ; Reset Handler
14
 ;------------------------------------------------------
15
 ;     ISR VECTORS
16
 ;------------------------------------------------------
17
.org ACIaddr
18
19
INIT:  
20
 ;------------------------------------------------------
21
 ;     INITIALIZE
22
 ;------------------------------------------------------  
23
  ldi    r16,  0xFF
24
  out    DDRD,  r16
25
  sbi    DDRB,  0
26
27
  ldi    r16,  (1<<REFS0) | (0<<REFS1)
28
  out    ADMUX,  r16
29
30
  ldi    r16,  (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0)
31
  out    ADCSRA, r16
32
33
  ldi    r18,  LOW(400)
34
  ldi    r19,  HIGH(400)
35
 ;------------------------------------------------------
36
 ;   HAUPTSCHLEIFE
37
 ;------------------------------------------------------
38
 Main:
39
40
; neuen ADC-Wert lesen
41
 
42
    sbi     ADCSRA, ADSC        ; den ADC starten
43
 
44
wait_adc:
45
  sbic    ADCSRA, ADSC        ; wenn der ADC fertig ist, wird dieses Bit gelöscht
46
    rjmp    wait_adc
47
48
; ADC einlesen:
49
 
50
    in      adlow, ADCL         ; immer zuerst LOW Byte lesen
51
    in      adhigh, ADCH        ; danach das mittlerweile gesperrte High Byte
52
53
  cp    adlow,  r18
54
   cpc    adhigh,  r19
55
  brsh  Heizung_Ein
56
  brlo  Heizung_Aus
57
    rjmp    Main
58
 
59
60
Heizung_Ein:
61
  ldi    r16,  0x00
62
  out    $12,  r16
63
  rjmp  Main
64
Heizung_Aus:
65
  ldi    r16,  0xf0
66
  out    $12,  r16
67
  rjmp  Main

von Uhu U. (uhu)


Lesenswert?

Meinst du nicht, daß der Siebkondensator vor dem Regler etwas mickrig 
ausgefallen ist?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Kann mir den Schaltplan leider nich ´reinziehen, da mein Eagle zu alt 
ist. Könntest Du bitte ein PNG-Bild des Plans exportieren und posten?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Noch ´ne Idee: Watchdog aktiv?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

>.org 0x000
>.org 0x00E
>  rjmp   INIT           ; Reset Handler
> ;------------------------------------------------------
> ;     ISR VECTORS
> ;------------------------------------------------------
>.org ACIaddr

>INIT:

Das ist murks. Wenn Du schon Vektoren verwendest, dann lege eine 
komplette Vektoren-Tabelle an und lasse die nicht verwendeten Vektoren 
nach RESET springen. Bei RESET läuft dann das eigentliche Programm los. 
Die Tabelle beginnt dann mit .org 0x0000 und nach dem letzen Vektor 
folgt dann die RESET-Marke. Das erspart weitere .org Direktiven und 
fragmentiert die spätere *.hex-Datei nicht unnötig.

von Uhu U. (uhu)


Lesenswert?

@ Travel Rec.:

Der Siebkondensator vor dem Spannungsregler ist 10 µF groß und davor 
kommt noch ein Brückengleichrichter...

Da er keine Interrupts freigibt, kann er auf die Vektortabelle ganz 
verzichten - der rjmp INIT am Anfang ist zwar überflüssig, aber er tut 
nicht weh.

von Stefan (Gast)


Lesenswert?

Ich habe etwas neues festgestellt:
Wenn ich die Spannungsversorgung über mein STK500 laufen lasse flimmert 
die Led nicht.
Wenn ich die Spannungsversorgung über mein Netzteil laufen lasse 
flimmert die Led.

Kann das an dem Siebkondensator liegen, ich verstehe das Prinzip nicht

von Stefan (Gast)


Lesenswert?

Was ist ein Watchdog? Ich hab ihn noch nie verwendet.

von YS-500 (Gast)


Lesenswert?

>Was ist ein Watchdog?
Den gibt es in jedem Tierheim.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

>Kann das an dem Siebkondensator liegen, ich verstehe das Prinzip nicht

Wenn das Netzteil schwach auf der Brust ist und der Siebelko nicht 
wenigstens 470µF hat, bricht bei jeder Halbwelle der 
Eingangswechselspannung die Spannung ein. Das kann dazu führen, daß der 
Controller jedes Mal einen RESET ausführt.

von txg (Gast)


Lesenswert?

wird der atmel noch für weitere funktionen eingesetzt? ansonsten ist das 
meines erachtens overkill, ein temperaturschalter mit hysterese lässt 
sich auch wunderbar mit einem simplen opv und ein paar widerständen 
zusammenfrickeln.

mfg,
lukas

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Keine Frage. Und?

von Uhu U. (uhu)


Lesenswert?

Lernen ist immer Overkill :-)

von txg (Gast)


Lesenswert?

...ich wollte ja nur eine einfachere alternative aufzeigen. dass diese 
dem threadersteller bewusst ist kann ich ja nicht riechen.

mfg,
lukas

von Uhu U. (uhu)


Lesenswert?

txg wrote:
> ...ich wollte ja nur eine einfachere alternative aufzeigen. dass diese
> dem threadersteller bewusst ist kann ich ja nicht riechen.

Riechen nicht - sich denken tuts völlig. Schließlich hat jeder mal 
klein angefangen.

von Stefan (Gast)


Lesenswert?

Danke für die Antworten. Ich such mal nen Kondensator der hinkommt. 
Wenns fertig ist meld ich mich nochmal;)

von Stefan (Gast)


Lesenswert?

;D es war der blöde Kondensator

Vielen Dank uhu und travelrec, wünsch euch frohe Weihnachten ;)

von Uhu U. (uhu)


Lesenswert?

Stefan wrote:
> Was ist ein Watchdog? Ich hab ihn noch nie verwendet.

Das ist sowas wie das Toter-Mann-Pedal bei der Bahn: Ein Timer, der 
innerhalb einer vorgegebenen Zeit zurückgesetzt werden muß. Passiert das 
nicht, erzeugt der Watchdog einen Reset.

von Peter D. (peda)


Lesenswert?

Stefan wrote:
> Ich hab mal was ausprobiert:
> wenn ich eine Led anschließe, dann flackert diese

Die LED zieht Deine VCC runter (wenn sie schwach genug ist) und der MC 
geht in Reset.
Bei starker VCC geht entweder die LED, der MC oder beide flöten.


> wenn ich eine Led mit Widerstand (470ohm), dann flackert diese nicht

Boa ey, kaum macht mans richtig, funktionierts sogar.

LEDs betreibt man grundsätzlich immer mit Widerstand!


Peter

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Nich so streng, Peter ;-) Jetzt hatter ja erstmal ´ne funktionierende 
Spannungsquelle.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.