Forum: Mikrocontroller und Digitale Elektronik ADC mit Thermowiederstand


von ADC (Gast)


Lesenswert?

Hallo Leute
Ich will mit meinem ATMega8 die Temperatur messen! Dazu hab ich einen 
Wiederstand, der je nach Temperatur seinen Wiederstand ändert! Jetzt 
weis ich aber nicht ob ich denn richtig angeschlossen habe!? hab den 
Wiederstand sowohl mal an GND als auch VCC angeschlossen und dann gegen 
PC0... Der hat ungefähr 1,5 Ohm bei raumtemperatur! Als Aref hab ich 
intern 2,5... V eingestellt!
Das hier ist mein Code:
1
.include "m8def.inc"
2
3
4
main:
5
  ;Stack initialisieren
6
  ldi r16, LOW(RAMEND)
7
  out SPL, r16
8
  ldi r16, HIGH(RAMEND)
9
  out SPH, r16
10
  
11
  ;Display initialisieren
12
  rcall lcd_init
13
  rcall lcd_clear
14
  
15
  ;ADC
16
  ldi r16, (1<<REFS0) | (1<<REFS1) | (1<<ADLAR) 
17
  out ADMUX, r16
18
19
  ldi r16, (1<<ADEN) | (1<<ADSC) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2)
20
  out ADCSRA, r16
21
22
  wait:
23
  sbic ADCSRA, ADSC
24
  rjmp wait
25
  
26
  ;Wert auslesen
27
  in r17, ADCL
28
  in r16, ADCH
29
30
  ;Auf LCD ausgeben
31
  sbrs r16, 0
32
  ldi r20, 0x30
33
  sbrc r16, 0
34
  ldi r20, 0x31
35
  rcall lcd_data
36
37
  sbrs r16, 1
38
  ldi r20, 0x30
39
  sbrc r16, 0
40
  ldi r20, 0x31
41
  rcall lcd_data
42
43
  sbrs r16, 2
44
  ldi r20, 0x30
45
  sbrc r16, 0
46
  ldi r20, 0x31
47
  rcall lcd_data
48
49
  sbrs r16, 3
50
  ldi r20, 0x30
51
  sbrc r16, 0
52
  ldi r20, 0x31
53
  rcall lcd_data
54
55
  sbrs r16, 4
56
  ldi r20, 0x30
57
  sbrc r16, 0
58
  ldi r20, 0x31
59
  rcall lcd_data
60
61
  sbrs r16, 5
62
  ldi r20, 0x30
63
  sbrc r16, 0
64
  ldi r20, 0x31
65
  rcall lcd_data
66
67
  sbrs r16, 6
68
  ldi r20, 0x30
69
  sbrc r16, 0
70
  ldi r20, 0x31
71
  rcall lcd_data
72
73
  sbrs r16, 7
74
  ldi r20, 0x30
75
  sbrc r16, 0
76
  ldi r20, 0x31
77
  rcall lcd_data
78
79
loop: 
80
  rjmp loop
81
82
.include "lcd_functions.asm"
Ist an dem Code was falsch? Und warum liegt an meinem Wiederstand keine 
Spannung an egal ob ich diesen gegen masse oder vcc schalte!?

von Andreas (Gast)


Lesenswert?

1.:
Das wird WIDERSTAND geschrieben!

2.:
Du musst einen Spannungsteiler mit einem zweiten WIDERSTAND aufbauen, 
sonst wird das nix.

von spess53 (Gast)


Lesenswert?

Hi

>Ist an dem Code was falsch? Und warum liegt an meinem Wiederstand keine
>Spannung an egal ob ich diesen gegen masse oder vcc schalte!?

Wo soll die Spannung herkommen? Eine Spannung kannst du nur messen, wenn 
ein Strom durch den Widerstand fließt.

>Der hat ungefähr 1,5 Ohm bei raumtemperatur!

Nicht sehr geeignet.

MfG Spess

von magnetus (Gast)


Lesenswert?

ADC schrieb:
> Dazu hab ich einen Wiederstand, der je nach Temperatur seinen
> Wiederstand ändert!

> Der hat ungefähr 1,5 Ohm bei raumtemperatur!

Bist du dir sicher dasses sich um einen temperaturabhängigen Widerstand 
(NTC bzw. PTC) und nicht um ein Thermoelement handelt?

Gruß,
Magnetus

von ADC (Gast)


Lesenswert?

oh ja natürlich Widerstand...
Hab mich verschrieben! Der hat 1,5 KOhm! Das müsste ein Widerstand sein! 
Wenn ich ihn ans multimeter anstecke und ihn dann erwärme verringert 
sich sein widerstand...
Ich muss ihn also gegen Vcc stecken oder?

von magnetus (Gast)


Lesenswert?

ADC schrieb:
> Ich muss ihn also gegen Vcc stecken oder?

Ob gegen GND oder VCC (genauer gesagt VREF) ist egal. Damit legst du 
eigentlich nur fest, ob die gemessene Spannung mit zunehmender 
Temperatur kleiner oder größer wird. Du musst halt nur mit Hilfe eines 
weiteren Widerstands einen Spannungsteiler aufbauen.

Gruß,
Magnetus

von Ohforf S. (ohforf)


Lesenswert?

Wichtig ist auch, dass nicht zuviel Strom durch den NTC fliesst, sonst 
erwärmt der sich selbst.

von ADC (Gast)


Lesenswert?

durch denn Widerstand fliesen gerade mal 3,5mA... hab mal so ne 
spannungsteilerschaltung gebaut und jetzt kann ich auch ne Spannung 
messen! ca. 3V abhängig von der Temperatur... Diese schaltung sieht so 
aus:
                                > 1kOhm Widerstand----VCC(5V)
Masse(0V)----Thermowiderstand <
                                > PB0
Verständlich?
jedoch zeigt mir das Display immer nur zwei verschiedene Werte an:
10000000 und 00000000 (<--- nicht abhängig von der Temperatur glaub ich)
Was läuft da falsch?

von magnetus (Gast)


Lesenswert?

ADC schrieb:
> Was läuft da falsch?

Du hast einen Fehler im Programm.

von spess53 (Gast)


Lesenswert?

Hi

>ca. 3V abhängig von der Temperatur... Diese schaltung sieht so aus:....

Du hast nach eigenen Angaben 2,5V Referenzspannung. Also kannst du nur 
Spannungen <=2,5V Messen. Nimm statt dem 1K mal 2k.

MfG Spess

von ADC (Gast)


Lesenswert?

Ich hab jetzt mal die Referenzspannung hoch auf 5 V und 2 kOhm 
Widerstand genommen aber es kommen immer noch nur diese beiden Werte!?
@magnetus: Ja die Frage ist WO?

von Otto (Gast)


Lesenswert?

Wie sieht denn das Unterprogramm lcd_data aus ?

von ADC (Gast)


Lesenswert?

Hier ist die Datei "lcd_functions.inc"
1
// MAKROS
2
.equ LCD_PORT = PORTB
3
.equ LCD_DDR = DDRB
4
.equ PIN_E = 5
5
.equ PIN_RS = 4
6
.equ TAKT = 16000000
7
8
delay5ms:   /// Für 16 mhz ca. 5,02 ms
9
  ldi r16, (TAKT/1000)*(5/1000)  //1000 Rechenoperationen
10
                  //pro Schleifendurchlauf
11
  delay5ms_loop1: 
12
    ldi r17, 249
13
14
    delay5ms_loop2: 
15
      dec r17
16
      nop
17
    brne delay5ms_loop2
18
19
    dec r16        
20
  brne delay5ms_loop1      
21
  ret
22
23
delay50us:
24
  ldi r16, (TAKT/10)*(50/1000000)   //10 Rechenoperationen
25
                    //pro Schleifendurchlauf
26
  delay100us_loop:
27
    nop
28
    nop
29
    nop
30
    nop
31
    nop
32
    nop
33
    nop
34
    dec r16
35
    brne delay100us_loop
36
  ret
37
38
enable:
39
  sbi LCD_PORT, PIN_E
40
  ldi r16, 0x04
41
  enable_loop: 
42
    dec r16
43
    brne enable_loop
44
  cbi LCD_PORT, PIN_E
45
  ret
46
47
lcd_init:
48
  ldi r16, 0xFF
49
  out LCD_DDR, r16
50
  rcall delay5ms
51
  rcall delay5ms
52
  rcall delay5ms
53
  ldi r16, 0b00000011    // $3
54
  out LCD_PORT, r16      // in PORTD ausgeben
55
  rcall enable      // Enable Bit setzen 1. mal
56
  rcall delay5ms      // min. 4,1 ms warten
57
  rcall enable      // Enable Bit setzen 2. mal
58
  rcall delay5ms      // min. 4,1 ms warten
59
  rcall enable      // Enable Bit setzen 3. mal
60
  rcall delay5ms      // min. 4,1 ms warten
61
  ldi r16, 0b00000010    // auf 4-Bit Modus umstellen
62
  out LCD_PORT, r16      
63
  rcall enable
64
  rcall delay5ms
65
66
  ldi r20, 0b00101000    // 4-Bit Modus, 2-Zeilig, 5*7 Pixel
67
  rcall lcd_command
68
  ldi r20, 0b00001111    // Display/Curser(-blinken) ein
69
  rcall lcd_command
70
  ldi r20, 0b00010100
71
72
  ret
73
74
lcd_command:         // Befehl in r20
75
  mov r21, r20
76
  swap r20
77
  andi r20, 0b00001111
78
79
  out LCD_PORT, r20
80
  rcall enable
81
82
  andi r21, 0b00001111
83
  out LCD_PORT, r21
84
  rcall enable
85
  
86
  rcall delay50us
87
  ret
88
89
lcd_data:
90
  mov r21, r20    
91
  swap r20
92
  andi r20, 0b00001111
93
  sbr r20, (1<<PIN_RS)    // RS auf Daten umstellen (1)
94
95
  out LCD_PORT, r20
96
  rcall enable
97
98
  andi r21, 0b00001111
99
  sbr r21, (1<<PIN_RS)    // RS auf Daten umstellen (1)
100
  out LCD_PORT, r21
101
  rcall enable
102
103
  rcall delay50us
104
  rcall delay50us
105
  ret
106
107
lcd_clear:
108
  ldi r20, 0b00000001
109
  rcall lcd_command
110
  rcall delay5ms
111
  ret
112
113
lcd_print_array:
114
  ldi ZL, LOW(text*2)
115
  ldi ZH, HIGH(text*2)
116
  ldi r16, 0
117
  wdh:
118
    lpm r20, Z+
119
    cp  r20, r16
120
    breq ende
121
    rcall lcd_data
122
  rcall wdh  
123
124
  ende:
125
  ret
Hab jetzt auch schon den Verdacht, dass es daran liegen könnte!?

von Otto (Gast)


Lesenswert?

R20 enthält das anzuzeigende Zeichen:


lcd_data:
  mov r21, r20


Hier lädst Du mehrfach eine ASCII "1" nach R20 und gibst diese aus:

  ldi r20, 0x31
  rcall lcd_data


und dann führst Du eine Endlosschleife aus.

Welche Funktion erwartest Du von Deinem Programm ?

von spess53 (Gast)


Lesenswert?

Hi

>Hab jetzt auch schon den Verdacht, dass es daran liegen könnte!?

Nicht wahrscheinlich. Nach dem Programm in deinem 1.Post machst du nur 
eine Messung. Nach einer Umschaltung der Referenzspannung (in deiner 
Initialisierung) ist die erste Messung fehlerbehaftet. Füge mal eine 
Dummymessung ein.

MfG Spess

von ADC (Gast)


Lesenswert?

Also ich hab in meinem Hauptprogramm noch einen Fehler entdeckt: ich hab 
immer geschrieben:
1
  sbrs r16, 7
2
  ldi r20, 0x30
3
  sbrc r16, 0         <-------
4
  ldi r20, 0x31
5
  rcall lcd_data
1
sbrc r16, 7
In der markierten zeile müsste anstelle der 0 eine 7 stehen(hab ich 
jetzt nur als Beispiel herangezogen! In den 6 anderen Fällen hab ichs 
jetzt auch geändert...
ich will von denn ganzen Code, dass er mir ein Byte in ASCII Zeichen 
(also '0' und '1') umwandelt und Bit für Bit jeweils als Byte auf dem 
Display ausgibt!
ja genau r20 ist für das aktuelle Byte vorgesehen, das als nächstes 
gesendet werden soll! aber ich überprüfe ja immer zuvor ob an der 
aktuellen Stelle im Byte eine 1 oder 0 steht!? je nach dem wird dann 
0x30 ('0') oder 0x31 ('31') geschrieben...
Könnt ihr mir folgen?

von Otto (Gast)


Lesenswert?

ja - ok - hättest Du dazu schreiben sollen....

Wie spess schon schrieb, taugt die erste Messung nichts.

Ausserdem gibst Du mit R16 ja nur ADCH und nicht ADCL aus.

von spess53 (Gast)


Lesenswert?

Hi

Noch was:

Du gibst meines Achtens die Bits in der falschen Reihenfolge aus.

Deine Bitabfragen kannst du dir sparen:
1
                   ldi r18,8
2
                   ldi r19,0
3
4
adc_out:           ldi r20,'0'
5
                   lsr r16
6
                   adc r20,r19
7
                   rcall lcd_data
8
                   dec r18
9
                   brne adc_out

gibt die Bits von r16 in der Reihenfolge '76543210' aus.

>Ausserdem gibst Du mit R16 ja nur ADCH und nicht ADCL aus.

ADLAR ist gesetzt.

MfG Spess

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.