Hallo Forum,
ich versuche mich gerade im Umgang mit MC, für einen Maschbauer gar
nicht so einfach. ;-)
Also, ich habe einen ATmega8
(http://www.kramann.info/87_Archiv_Mikrocontroller/02_Programmierer/atmega8.png)
mit zwei Temperatursensoren (KTY) und jeweils einem Spannungsteiler an
PC3 und PC4. Dort kommen bei -20°C 2,4V und bei RT 1,9V an. Nun möchte
ich mit dem ADC die Spannungen auslesen. Referenzspannung sind die
internen 2,56V.
Aus irgend einem Grund erhalte ich allerdings immer für beide Eingänge
den selben Wert (zwischen 452 - 457). Selbst wenn die Sensoren definitiv
unterschiedliche Temperaturen haben. Auch wenn ich die Referenzspannung
auf AVCC lege ändert sich daran nichts. Dann sollte der Wert ja
eigentlich nur halb so groß sein. Z.zt. bekommt die ganze Schaltung
Spannung über den Programmer (4,5V) wenn ich über einen 7805 speise und
die Spannung auf 5V steigt erhalte ich an den Eingängen Werte um 617.
Ich gehe davon aus, dass ich einen Bock im Code habe. Vielleicht hat ja
jemand eine Idee.
Vielen Dank im voraus
Sebastian
1
#include<avr/io.h>
2
#include"lcd.h"
3
#include<stdio.h>
4
#include<util/delay.h>
5
6
7
intmain(void)
8
{
9
// Variablen definieren
10
uint16_ttemp1,temp2,i;
11
uint8_tbuffer1[4];
12
uint8_tbuffer2[4];
13
14
15
//Ausgänge definieren
16
DDRD|=(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
17
18
//ACD einrichten
19
ADCSRA|=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);// Frequenzvorteiler auf 8
20
ADMUX|=(1<<REFS0)|(1<<REFS1);//Interne 2,56 Volt als Referenzspannung
21
22
//LCD aktivieren
23
lcd_init(LCD_DISP_ON);
24
25
26
//Endlose Schleife
27
for(;;)
28
{
29
30
PORTD=0;//LEDs aus
31
32
33
//1. Messung
34
ADMUX|=PC3;//Kanal für Messung wählen
35
ADCSRA|=(1<<ADSC);//Messung starten
36
while(ADCSRA&(1<<ADSC)){}//warten bis Messung bestätigt
37
temp1=ADCW;//Ergebnis abholen
38
39
//2. Messung
40
ADMUX|=PC4;//gleiches Vorgehen
41
ADCSRA|=(1<<ADSC);
42
while(ADCSRA&(1<<ADSC)){}
43
temp2=ADCW;
44
45
46
//Übergabe an LCD
47
lcd_home();
48
49
sprintf(buffer1,"a%d",temp1);
50
lcd_puts(buffer1);
51
52
sprintf(buffer2,"b%d",temp2);
53
lcd_puts(buffer2);
54
55
56
// zusäztliche Visualisierung an LEDs
57
if(temp1>temp2){PORTD|=(1<<PD5);}
58
elseif(temp1<temp2){PORTD|=(1<<PD7);}
59
elseif(temp1==temp2){PORTD|=(1<<PD5)|(1<<PD7);}
60
61
62
//Warten und neuen Schleifendurchlauf durch LED anzeigen
Den Code habe ich mir jetzt nicht angeguckt.
Aber du kannst diesen ganz einfach testen wenn du mit einem
Potentiometer an die ADC eingänge gehst.
Ich habe das Gefühl du kennst dich ganz gut aus, trotzdem nochmal:
Potentiometer hat 3 Pins. die beiden äußeren kommen an Spannung und
Ground
der Pin in der Mitte an den ADC Eingang.
Jetzt kannst du die Spannung am ADC über das Poti einstellen.
Bitte stell die elektrische Schaltung auch mal rein,
also wie der Spannungsteiler an dem KTY angeschlossen ist.
Hallo,
@Tilo
Im Moment habe ich den einen Sensor unter meinem Laptop und den anderen
frei im Raum. An PC3 sind es 1,84V und an PC4 1,78V.
@Roman
die Schaltung schaut so aus:
5V---KTY1----R1---GND
|
PC3
@Marco
Das verstehe ich noch nicht so ganz. Versuche mich aber daran...
Mit der |= (oder-gleich) setzt du nur Bits in ADMUX. Du setzt einmalig
die Ref-Bits. Danach oderst du 0x03 hinzu (PC3), danach 0x04 (PC4). Dass
heißt, du wählst kontinuierlich ADC7 aus.
Ist zwar eine Auswertungssache, aber Du solltest die Spannung über dem
KTY messen und nicht über dem "Vor"widerstand. Das erklärt auch, warum
Deine gemessene Spannung mit der steigender Temperatur fällt.
Und wie Marco schon geschrieben hatte, mußt Du zum Wählen des
ADC-Eingangskanals die MUX-bits in ADMUX nehmen und nicht die "normalen"
Port-bits.
Moin,
vielen Dank für die Hilfe. Es läuft :-) Ich habe es zwar noch nicht so
ganz verstanden weshalb, aber das kommt hoffentlich noch.
Ich habe durch eure Beispiele das Tutorial zum ADC besser nachvollziehen
können und habe meinen Code entsprechend umgebaut. Nun wird der ADC für
jede Messung neu eingerichtet und das funktioniert. Was ich noch nicht
verstehe, ist weshalb ich dem kompletten Register ADMUX die Kanalnummer
gebe (ADMUX=3;)?!?
Gruß
Sebastian
1
#include<avr/io.h>
2
#include"lcd.h"
3
#include<stdio.h>
4
#include<util/delay.h>
5
6
7
intmain(void)
8
{
9
// Variablen definieren
10
uint16_ttemp1,temp2,i;
11
uint8_tbuffer1[4];
12
uint8_tbuffer2[4];
13
14
15
//Ausgänge definieren
16
DDRD|=(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
17
18
//LCD aktivieren
19
lcd_init(LCD_DISP_ON);
20
21
22
//Endlose Schleife
23
for(;;)
24
{
25
26
PORTD=0;//LEDs aus
27
28
29
//1. Messung
30
ADMUX=3;//Kanal für Messung wählen
31
//ACD einrichten
32
ADCSRA|=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);// Frequenzvorteiler auf 8
33
ADMUX|=(1<<REFS0)|(1<<REFS1);//Interne 2,56 Volt als Referenzspannung
34
ADCSRA|=(1<<ADSC);//Messung starten
35
while(ADCSRA&(1<<ADSC)){}//warten bis Messung bestätigt
36
temp1=ADCW;//Ergebnis abholen
37
ADCSRA&=~(1<<ADEN);// ADC deaktivieren
38
39
//2. Messung
40
ADMUX=4;//gleiches Vorgehen
41
//ACD einrichten
42
ADCSRA|=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);// Frequenzvorteiler auf 8
43
ADMUX|=(1<<REFS0)|(1<<REFS1);//Interne 2,56 Volt als Referenzspannung
44
ADCSRA|=(1<<ADSC);
45
while(ADCSRA&(1<<ADSC)){}
46
temp2=ADCW;
47
ADCSRA&=~(1<<ADEN);// ADC deaktivieren
48
49
50
//Übergabe an LCD
51
lcd_home();
52
53
sprintf(buffer1,"a%d",temp1);
54
lcd_puts(buffer1);
55
56
sprintf(buffer2,"b%d",temp2);
57
lcd_puts(buffer2);
58
59
60
// zusäztliche Visualisierung an LEDs
61
if(temp1>temp2){PORTD|=(1<<PD5);}
62
elseif(temp1<temp2){PORTD|=(1<<PD7);}
63
elseif(temp1==temp2){PORTD|=(1<<PD5)|(1<<PD7);}
64
65
66
//Warten und neuen Schleifendurchlauf durch LED anzeigen
Sebastian S. wrote:
> Was ich noch nicht> verstehe, ist weshalb ich dem kompletten Register ADMUX die Kanalnummer> gebe (ADMUX=3;)?!?
Das verstehe ich auch nicht, weil Du damit jedes Mal die
Referenzspannungsauswahl löschst und sie zwei Zeilen weiter jeweils
wieder setzen musst. Übersichtlicher und ohne Änderung der
Referenzspannung wäre es z.B. mit
1
ADMUX=(ADMUX&0xF0)|channel;
Dabei bleiben die oberen 4 Bits unberührt. channel wäre hier dann die
Kanalnummer.