Temperaturschalter mit atmega8 (Assembler)

Gast #1087480
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
#1087493
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
Gast #1087558
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?
Gast #1088062
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.
#1088067
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...
Gast #1088091
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
Gast #1088111
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
Gast #1088154
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
Gast #1088163
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
(Firma: TravelRec.) Persönliche Seite #1088188
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.
#1088194
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.
Gast #1088211
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
Gast #1088276
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
#1088410
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.
#1088485
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren