Servus,
bin noch ein ziehmlicher Neuling im Bereich Mikrocontroller techniik und
wollte jetzt mal eine Spannung über die ADC Eingänge messen.
Hierfür hab ich ein 10k Poti zwischen VCC und GND gehängt und den Abgang
auf den Pin PC0 geklemmt. Ich verwende einen ATMega32.
Hab aus dem Roboternetz und mit Hilfe eines sehr netten Mitglieds von
dort folgenden Code bekommen und woolte jetzt einmal den ADC testen.
Irgendwie klappts aber nicht, hab ich noch irgendwas vergessen?
1
#include<avr/io.h>
2
#include<inttypes.h>
3
4
uint16_treadADC(uint8_tchannel){
5
uint8_ti;
6
uint16_tresult=0;
7
8
// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
Sorry hab irgendwie ganz vergessen zu schreiben was das Programm machen
soll. Also im Endeffekt will ich nur meine ADC Eingänge testen. Bei
überschreiten einer gewissen Spannung soll die LED anfangen zu leuchten
welche ich an Port A.0 klemme.
Im Endeffekt will ich über einen Spannungsteiler mein Labornetzgerät
dran hängen und dessen Spannung über ein LCD ausgeben.
Andi schrieb:> Sorry hab irgendwie ganz vergessen zu schreiben was das Programm machen> soll. Also im Endeffekt will ich nur meine ADC Eingänge testen. Bei> überschreiten einer gewissen Spannung soll die LED anfangen zu leuchten> welche ich an Port A.0 klemme.
Das deckt sich aber nicht mit den Kommentaren in deinem Programm
Zum Programm selber:
Ich müsste das auf einen Mega brennen um es in Aktion zu sehen. Beim
Durchlesen ist mir nichts aufgefallen. Prinzipiell müsste sich IMHO was
tun, wenn die LED am richtigen Pin angeschlossen ist
* Du hast eine Referenzspannung von 2.56V eingestellt.
Dein Poti liefert aber am ADC Pin 0 bis 5V ab.
Das alleine ist kein Problem, nur bist du mit dem Poti dann nach der
Hälfte des Poti Wegs bereits auf ADC Anschlag und ab dort liefert
der ADC nur noch 1023 als Messergebnis.
-> du schenkst schon mal die Hälfte des Wegs her
* Du vergleichst mit 128
Das ist nicht viel, wenn man bedenkt, dass der ADC Bereich von 0 bis
1023 geht.
Zusammen mit der vorhergehenden Entscheidung bedeutet das, dass
du nur einen sehr kleinen Potibereich hast, in dem du die
Auswirkungen des Potidehens an der LED sehen kannst.
Allerdings sehen müsstest du sie. An einem Ende der Potiverstellung
müsste die LED ausgehen.
Aber um sicherzugehen:
Ändere mal die Referenzspannung auf Vcc um
ADMUX = channel | (0<<REFS1) | (1<<REFS0);
damit nutz du den Poti Weg komplett aus.
Weiters: Ändere den Vergleichswert auf 512. Dann liegt die
Umschaltschwelle in der Mitte des Potiwegs und das kannst du nicht mehr
übersehen
Weiters:
miss die Spannung an PC0 (also dem Kanal 0 Eingang des ADC)
miss die Spannung am ARef Pin
am ARef Pin musst du konstant 5V sehen
am PC0 Pin musst du eine Spannung messen können, die sich beim Drehen am
Poti verändert.
Die LED hast du kontrolliert, dass sie auch wirklich funktioniert?
Ändere deinen Programmanfang mal so um:
1
#include<avr/io.h>
2
#include<inttypes.h>
3
#include<util/delay.h>
4
5
6
...
7
8
intmain(void)
9
{
10
11
DDRA=0x01;
12
13
PORTA=0x01;
14
_delay_ms(500);
15
PORTA=0x00;
16
_delay_ms(500);
17
18
//Endlosschleife
19
....
das lässt deine LED bemi Programmstart einmal blinken. Damit hast du die
Funktionskontrolle, ob die LED überhaupt prinzipiell funktioniert.
> Hierfür hab ich ein 10k Poti zwischen VCC und GND gehängt und den> Abgang auf den Pin PC0 geklemmt. Ich verwende einen ATMega32.
Moment!
Der ADC Eingang beim Mega32 ist PA0 und nicht PC0. Siehe Datenblatt
Damit hängt dein Poti am falschen Pin.
Dann kann aber auch deine LED nicht auf PA0 hängen.
Was hast du wie verschaltet?
Erst einmal vielen Dank,
hab das Programm jetzt geändert, klappt leider immer noch nicht. Die LED
leuchtet konstant und geht nicht aus. hat aber kurz geblinkt beim
einschalten.
An AREF hab ich 5,0V gemessen und an Pin C.0 hab ich eine
Spannungsänderung im Bereich von 0-5V je nachdem wie ich das Poti
bewege. Gibt es sonst noch etwas das ich beachten muss? Ist es möglich
das die ADC Ports defekt sind? Oder muss ich bei den Fusebits etwas
ändern?
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
uint16_t readADC(uint8_t channel) {
uint8_t i;
uint16_t result = 0;
// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
// Kanal des Multiplexers waehlen
// Interne Referenzspannung verwenden (also 2,56 V)
ADMUX = channel | (0<<REFS1) | (1<<REFS0);
// Den ADC initialisieren und einen sog. Dummyreadout machen
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));
// Jetzt 3x die analoge Spannung and Kanal channel auslesen
// und dann Durchschnittswert ausrechnen.
for(i=0; i<3; i++) {
// Eine Wandlung
ADCSRA |= (1<<ADSC);
// Auf Ergebnis warten...
while(ADCSRA & (1<<ADSC));
result += ADCW;
}
// ADC wieder deaktivieren
ADCSRA &= ~(1<<ADEN);
result /= 3;
return result;
}
int main(void)
{
DDRA = 0x01;
PORTA = 0x01;
_delay_ms( 500 );
PORTA = 0x00;
_delay_ms( 500 );
//Endlosschleife
while(1)
{
uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin
0,
// also ADC0. In result steht das Ergebnis.
if(result<512)
{
//LED an
PORTA = 0x01;
//Setze PinA.0 auf 1
}
else
{
//LED aus
PORTA = 0x00;
//Setze PinA.0 auf 0
}
} //Endlosschleife bis hier
//an diese Stelle wird das Programm wegen der Endlosschleife nicht mehr
gelangen,
//außer du verlässt die while-Schleife mit einem break;
return 0;
}
Hallo!
Ich hab da auch ein kleines Problem.
Möchte gerne 4 LEDs ansteuern, je höher am ADC die Eingangsspannung,
umso mehr LEDs sollten leuchten.
Es leuchten aber dauernd alle 4 LEDs, selbst wenn am PC0 dauerhaft 0 V
anliegen...
1
// Test des Analog Comparators
2
3
#include<avr/io.h>
4
#define F_CPU 1000000UL // CPU Frequenz
5
#include<util/delay.h> // Warteschleifen
6
7
8
intmain(void)
9
{
10
intresult=0;
11
12
// Ausgänge
13
DDRD=0b00001111;
14
15
// ADC aktivieren und Teilungsfaktor auf 64 stellen
Hallo Christian,
dein Fehler liegt in der if-Bedingung:
> if ( result > 768 || result <= 1024 )> {> // LEDs> PORTD |= (1<<PD0);> PORTD |= (1<<PD1);> PORTD |= (1<<PD2);> PORTD |= (1<<PD3);> }
Jeder ADC-Wert ist <= 1024, damit wird der Abschnitt immer betreten und
alle vier Ausgänge gesetzt. Verknüpfe mal die beiden Intervallgrenzen
mit &&, dann müsste es passen.
Grüße
Andreas
> // Probedurchlauf abwarten> while(ADCSRA & (1<<ADSC));
Da fehlt das Auslesen!
// Probedurchlauf abwarten
while(ADCSRA & (1<<ADSC));
// Ergebnis der Konvertierung auslesen
result = ADCW; // Dummyread
Diese Dummreadaktion würde ich vor die while-Schleife ziehen statt in
die While-Schleife.
> // Referenzspannung von extern> ADMUX &= ~( (1<<REFS0)|(1<<REFS1) );
Spätestens hier stellt sich die Frage nach dem Schaltplan.
> // Auf Abschluss der Konvertierung warten, bis Bit wieder auf Null> while ( ADCSRA & (1<<ADIF) );
Warum hier mit ADIF statt mit ADSC?
Der Schaltplan ist schnell erklärt.
an AREF und AVCC sind +5.00V.
an PC0 ist ein 50k Poti, das zwischen VCC und GND hängt.
hab jetzt die Änderungen mal gemacht, aber immer noch leuchten egal
welche Potistellung alle 4 LED...
hm.
Arbeitest du auch mit einem ATMega 32? der hat doch die ADC Eingänge auf
PORT A, nicht auf PORT C.
Also, Poti auf PA0 hängen!
außerdem sollte dein "auswerten" folgendermaßen aussehen:
Achso, hab ich ganz vergessen zu sagen was da für ein uC im Einsatz ist.
Das ist ein ATMega8L-8PU.
Die Auswert-unds && hab ich geändert...
Aber immer noch keine Reaktion. Alle 4 LEDs dauer-an.
hmmmmm
Christian W. schrieb:> Achso, hab ich ganz vergessen zu sagen was da für ein uC im Einsatz ist.> Das ist ein ATMega8L-8PU.> Die Auswert-unds && hab ich geändert...
Und wie sieht dein Programm jetzt aus?
> Aber immer noch keine Reaktion. Alle 4 LEDs dauer-an.> hmmmmm
Ich frage mich, wozu wir im AVR-GCC-Tutorial so schöne getestete ADC
Funktionen haben, wenn dann jeder erst recht wieder sein eigenes
Süppchen kocht und erst mal auf die Schnauze fällt, weil nichts
funktioniert.
>Aber immer noch keine Reaktion. Alle 4 LEDs dauer-an.
Mal ne ganz blöde Idee;) Das Poti ist falsch angeschlossen.
Schon mal die Spannung an PC0 gemessen? Ist die evtl. immer 5V?
holger schrieb:>>Aber immer noch keine Reaktion. Alle 4 LEDs dauer-an.>> Mal ne ganz blöde Idee;) Das Poti ist falsch angeschlossen.> Schon mal die Spannung an PC0 gemessen? Ist die evtl. immer 5V?
Und gleich danach auch die Spannung am AREF Pin messen.
hier mal eine zusammenfassung.
das programm hab ich als c-datei angehängt.
die || wurden zwischenzeitlich durch && ersetzt, aber habe die falsche
datei hochgeladen.
poti ist richtig angeschlossen, ich messe am PD0 zwischen 0,00 und 4,90
volt, wenn ich am poti drehe
aref ist direkt am 7805, hat also auch die 4,90 v.
Christian W. schrieb:> hier mal eine zusammenfassung.>> das programm hab ich als c-datei angehängt.> die || wurden zwischenzeitlich durch && ersetzt, aber habe die falsche> datei hochgeladen.
Wie jetzt?
Ist das was du zuletzt hochgeladen hast, nun dein letztes Programm oder
nicht?
Denn dort sind die || immer noch drinnen
Bedenke bitte bei allem was du tust: Von dieser Seite des Monitors aus,
sehen wir nur das was du uns zeigst!
leider auch nicht... siehe anhang...
habe grade nochmal alles durchgemessen:
- PD0: 0,00 bei poti zu
- PD0: 2,54 bei poti halb
- PD0: 4,90 bei poti auf
- AREF: 4,90 v
- AVCC: 4,90 v
- VCC: 4,90 v
Christian W. schrieb:> leider auch nicht... siehe anhang...>> habe grade nochmal alles durchgemessen:>> - PD0: 0,00 bei poti zu> - PD0: 2,54 bei poti halb> - PD0: 4,90 bei poti auf
Wieso PD0
Der ADC ist beim Mega8 am Port C
(Tippfehler oder Verdrahtungsfehler?)
hoppla, tippfehler. auf der bestückungsseite der 6. pin rechts von oben,
also PC0.
hab jetzt die interne ref spannung verwendet mit:
ADMUX |= ( (1<<REFS0)|(1<<REFS1) );
geht immer noch nicht...
-grübel-
ja, leds funktionieren alle.
ich bin jetzt endlich dahintergekommen.
je nach potistellung geht jetzt eine led nach der anderen schön an, oder
aus.
vielen dank für die hilfe.
es war ein fehler im avr studio.
ich hab mal unten nach dem compilieren auf die byte-angabe geachtet.
die lag bei 204 byte.
dann hab ich am programm etwas geändert,
lag die immer noch bei 204 byte nach dem compilieren.
dann hab ich einen kompletten programmteil rausgeschmissen, und siehe
da, immer noch 204 byte.
ich hab dann alles geschlossen und ein neues projekt erstellt, und siehe
da, je nachdem ob ich was am quellcode ändere, ändert sich nach dem
compilieren auch die byte-zahl.
ich hab also unwissentlich immer wieder den gleichen hexcode in den
prozessor gejagt, ohne dass es mir aufgefallen ist.
kennt diesen programmfehler schon jemand?
ok habs rausgefunden.
ich hab die c-quelltext-datei auf dem desktop gespeichert, damit ich
diese hier hochladen kann.
beim compilieren hat das avr studio immer die datei auf dem desktop
aktualisiert, was der hex datei im avr-studio-verzeichnis aber wenig
geholfen hat, die blieb dann immer gleich.
nun denn...
danke