PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Dieses Mal: ADC-Probleme



Spongebob85
22.08.2007, 21:43
Moin Izaseba und die anderen :-)
Ich hab mal wieder ein Problem (was auch sonst).
Ich hab mir jetzt endlich mal den ADC vorgenommen.
Wenn ich brennen will, kommen 2 Fehlermeldungen:
main.c:19: error: called object is not a function
main.c:32:4: warning: no newline at end of file

und hier ist mein Code:


#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL

int main(void)
{
DDRC |= (1<<PC0);
uint8_t x;

ADCSRA = (1<<ADEN); //Damit ist der Converter gestartet
ADCSRA = (1<<ADSC); //hiermit wird die Messung initialisiert und gestartet
ADCSRA = (1<<ADATE); //hier wird auf freilaufmodus geschaltet da im SFIOR-Register kein Auslöser
//(Trigger) eingestellt ist die Daten werden von jetzt an im ADC-Data-
//Register gespeichert
ADCSRA = ((1<<ADPS0) | (1<<ADPS1)) //Hier wird dem ADC Prescaler ein teilungsfaktor von 8
//gegeben, das bedeutet es ist dem ADC eine frequenz von
//1.000.000 durch 8 also 125kHz im Tutorial steht das der
//ADC eine Frequenz von 50 bis 200 kHz gegeben haben soll
ADMUX = PA0; //hier is C:19

while(1)
{
x = ADCW; //hier wird das ADC-Register ausgelesen

if (x >= 128) //wenn der gemessene Wert die 128 erreicht oder überschreitet soll die LED
//an PC0 leuchten also wenn die Spannung die hälfte von 0V zu AREF
//(hier 2,5V) überschreitet
{
PORTC |= (1<<PC0);
}
}
} //hier ist c:23:4


Ich möchte eigentlich erreichen, das der ADC eingang die ganze Zeit ausgelesen wird und es soll eine LED eingeschaltet werden sobald die Spannung 2,5V übersteigt bzw. erreicht.
Bis bald,
MfG Jan

uwegw
22.08.2007, 21:48
Der übliche Tippfehler: Semikolon fehlt nach ADCSRA = ((1<<ADPS0) | (1<<ADPS1))

(generell sollte man bei allen Fehlermeldungen, die man nicht versteht, erst einmal rund um die beanstandete Stelle nach Tippfehlen suchen sowie Klammern und Semikolons prüfen.)

Spongebob85
22.08.2007, 22:26
:oops: Oh, das ist mir jetzt ein bisschen peinlich. :oops:
Ich hab das jetzt geändert, aber wenn ich an PA0 die Spannung erhöhe, tut sich nix. Bin bis auf 5V gegangen. Hab an AREF und AVCC 5V gelegt (einfach von VCC gebrückt), soll ja nicht besonders genau sein, will ja nur mal die funktion sehen, is das den von der Grundstruktur und so richtig?
Gruß Jan

izaseba
22.08.2007, 23:28
Hallo Jan,
irgendwie fühle ich mich schuld, weil ich Dir irgendwann mal erzählt habe Du solltest an der einen oder anderen Stelle den oder | Operator weglassen 8-[ 8-[
Sollte aber heißen nicht immer weglassen!
Ich habe jetzt keine Lust hier wieder ein C Grundkurs zu machen, weil mir die Augen zufallen, ich kopiere einfach nur die wichtigsten Zeilen aus Deinem Programm, und Du überlegst was da faul ist O:)


ADCSRA = (1<<ADEN); //Damit ist der Converter gestartet
ADCSRA = (1<<ADSC); //hiermit wird die Messung initialisiert und gestartet
ADCSRA = (1<<ADATE); //hier wird auf freilaufmodus geschaltet da im SFIOR-Register kein Auslöser
//(Trigger) eingestellt ist die Daten werden von jetzt an im ADC-Data-
//Register gespeichert
ADCSRA = ((1<<ADPS0) | (1<<ADPS1)) //Hier wird dem ADC Prescaler ein teilungsfaktor von 8
//gegeben, das bedeutet es ist dem ADC eine frequenz von
//1.000.000 durch 8 also 125kHz im Tutorial steht das der
//ADC eine Frequenz von 50 bis 200 kHz gegeben haben soll
ADMUX = PA0; //hier is C:19

Die letzte Zeile bei Admux, bin mir jetzt nicht sicher, was da für die 2.56V Ref gesetzt werden muß.
PA0 könnte durch ein Zufall passen, die Bits heißen da aber anders

Gruß Sebastian

Spongebob85
22.08.2007, 23:55
Ne, bist nicht schuld dran, war wohl vorhin bloß ein bisschen hektisch und überstürtzt. Mit dem ADMUX wollte ich nicht die interne Referenzspannung einschalten, sondern festlegen das der PA0 der genutzte Analogeingang ist, oder macht man das anders? Das ist in dem Tutorial über WinAVR so komisch beschrieben.
MfG Jan

Spongebob85
23.08.2007, 12:13
Moin!!!
Ich hab das jetzt geändert und zusätzlich noch einen else zweig gemacht. Also so:


#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL

int main(void)
{
DDRC |= (1<<PC0);
uint8_t x;

ADCSRA |= (1<<ADEN); //Damit ist der Converter gestartet
ADCSRA |= (1<<ADSC); //hiermit wird die Messung initialisiert und gestartet
ADCSRA |= (1<<ADATE); //hier wird auf freilaufmodus geschaltet da im SFIOR-Register kein Auslöser
//(Trigger) eingestellt ist die Daten werden von jetzt an im ADC-Data-
//Register gespeichert
ADCSRA |= ((1<<ADPS0) | (1<<ADPS1)); //Hier wird dem ADC Prescaler ein teilungsfaktor von 8
//gegeben, das bedeutet es ist dem ADC eine frequenz von
//1.000.000 durch 8 also 125kHz im Tutorial steht das der
//ADC eine Frequenz von 50 bis 200 kHz gegeben haben soll
ADMUX |= (1<<REFS0);

ADMUX = PA0;

while(1)
{
x = ADCW; //hier wird das ADC-Register ausgelesen

if (x >= 255) //wenn der gemessene Wert die 128 erreicht oder überschreitet soll die LED
//an PC0 leuchten also wenn die Spannung die hälfte von 0V zu AREF
//(hier 2,5V) überschreitet
{
PORTC |= (1<<PC0);
}
else
{
PORTC &= ~(1<<PC0);
}
}
}


Irgendwie ist es egal ob ich if (x >=10) oder if (x >= 200) eingebe.
sobald ich die spannung auf ca. 1V aufdrehe, geht die LED an, aber sie geht auch nicht wieder aus wenn ich die Spannung wieder senke.

Der ADC is ja ganzschön kompliziert.

MfG Jan

radbruch
23.08.2007, 14:18
Hallo

Ich bin auch noch ADC-Anfänger, aber so würde ich das nicht machen:


ADCSRA |= (1<<ADEN); //Damit ist der Converter gestartet
ADCSRA |= (1<<ADSC); //hiermit wird die Messung initialisiert und gestartet

Bei der ersten Zuweisung sollte man nur = verwenden um alle alten Bits im Controllregister zu löschen. Auf dieser Basis kann man dann alles weitere verodern. Oder Zuweisung mit = als Einzeiler.

ADSC würde ich als letztes setzen wenn alles andere erledigt ist. SFIOR würde ich zur Sicherheit extra auf free-runnig setzen.



ADMUX |= (1<<REFS0);

ADMUX = PA0;
Setzt erst zusätzlich das REFS0-Bit und löscht dann ADMUX komplett mit = PA0 ( PA0 entspricht 0!)

So wäre besser:


ADMUX = (1<<REFS0) | (0<<REFS1); // Spannungsreferenz AVCC

ADMUX |= (0<<ADLAR) // zusätzlich Ergebniss rechtsbündig
ADMUX |= PA0; // zusätzlich Kanal wählen
Bei dieser Spannungsreferenz muss an AREF ein Kondensator gegen GND geschaltet werden (10nF beim RP6-AtMega32). Genauer wäre vermutlich die Verwendung der internen 2,56V-Referenz, allerdings braucht man dann auch einen Kondensator. Und einen Spannungsteiler für die 5V-Eingangsspannung. Die Eingangsspannung darf nie größer als die Referenz sein!


uint8_t x;
X sollte ein 16-Bit-Wert sein.


Der ADC is ja ganzschön kompliziert.
Reine Übungssache. Ich hoffe, ich habe das meiste gefunden. ADC macht Spass (https://www.roboternetz.de/phpBB2/viewtopic.php?t=33228)!
Bei mir war übrigends dies hier die Initialzündung: A V R -Tutorial (http://www.izaseba.roboterbastler.de/index.php?popup=Tutorial)

Gruß

mic

izaseba
23.08.2007, 15:57
Hallo Radbruch, danke, daß Du hier zur Hilfe eilst ;-)

Bei der ersten Zuweisung sollte man nur = verwenden um alle alten Bits im Controllregister zu löschen. Auf dieser Basis kann man dann alles weitere verodern. Oder Zuweisung mit = als Einzeiler.
Jep, das habe ich schon dem Spongebob85, leider hat er es falsch verstanden und alle | weggelassen, jetzt weißt es hoffich doch bescheid.



ADMUX = PA0;
Das ist unsinn und funktioniert nur durch einen Zufall.
Die Bits in ADMUX heißen u.a. MUX* und ergeben eine Maske für den Kanal, und nicht direkt die Pinnummer(sehe Dattenblatt)
Außerdem beschreiben REFS0 und REFS1 die Referenzspannung,(das hast Du schon gesagt)
Warum willst Du ADLAR setzen ? :-k
das ist interessant wenn einem 8 Bit ausreichen, dann kann man ja ADCL unter den Tisch fallen lassen und ADCH nehmen, aber bei 10 Bit stehen die Bits schon an der richtigen Stelle O:)
Ob Freilauf, oder nicht, muß man je nach Anwendung entscheiden.

ADC ist aber nicht so richtig kompliziert, es gibt schlimmere Sachen

Gruß Sebastian

radbruch
23.08.2007, 17:07
Hallo

Naja, er hat's eben genau nach Anleitung gemacht: "Die = durch |= ersetzen" *gg*

Das mit der Datenausrichtung war eh Quatsch. Nach


ADMUX = (1<<REFS0) | (0<<REFS1);
ist das ADLAR-Bit eh nicht gesetzt, denn Default ist ja "rechtsbündig".

Gruß

mic

Spongebob85
23.08.2007, 19:34
Das mit den = und den |= hab ich jetzt denke ich verstanden.
Tut mir leid wenn ich eich bisschen bratzig rüberkomme, aber wartet mal erst ab wenn ich irgendwas mit zeiten und interrups machen will. Das hab ich nämlich als nächstes vor
:shock: Naja, ich werde mal das Programm ändern und mich dann wieder melden,
dankeschön erstmal für alles.

Gruß Jan

Spongebob85
23.08.2007, 20:02
So, mein Code sieht jetzt so aus:


#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL

int main(void)
{
DDRC = (1<<PC0);
uint16_t x;

SFIOR = ((0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0));

ADCSRA = ((1<<ADEN) | (1<<ADATE) | (1<<ADPS0) | (1<<ADPS1));

ADMUX = (1<<REFS0);
ADMUX |= PA0;

ADCSRA |= (1<<ADSC); //hiermit wird die Messung initialisiert und gestartet

while(1)
{
x = ADCW; //hier wird das ADC-Register ausgelesen

if (x >= 800) //wenn der gemessene Wert die 128 erreicht oder überschreitet soll die LED
//an PC0 leuchten also wenn die Spannung die hälfte von 0V zu AREF
//(hier 2,5V) überschreitet
{
PORTC |= (1<<PC0);
}
else
{
PORTC &= ~(1<<PC0);
}
}
}

Jetzt klappt das auch schon besser, aber wenn ich "if (x<=500)" schreibe geht die Lampe bei etwa 4,2V an. x ist doch aber 16 bit groß.
das müsste doch jetzt auf 0xffff verteilt sein, oder? Ich versteh das nicht.

Gruß Jan

izaseba
23.08.2007, 20:36
](*,) ](*,)
Das ist alles Käse

Zuerst(und zum letztem, ich habe schon 2 mal drauf hingewiesen)


ADMUX |= PA0;
ES IST EIN ZUFALL,DAß DIESES KLAPPT!!!!!!! ](*,)
Was willst Du damit erreichen ?
ADC0 abfragen ?
dazu gibt es im ADMUX Register 5 Bits MUX4...0(Seite 215 M32 Dattenblatt)
Ende der Durchsage, in DB nachsachauen und (hoffentlich) verstehen.

Als nächstes Du läßt den ADC in Freeruning Modus laufen (habe so aus M32 DB rausgelesen,sorry, den benutze ich garnicht, egal)
DAS berechtigt Dich aber nicht dazu einfach mal nach Lust und Laune
x = ADCW;

zu schreiben!
Nein, so eine Wandlung dauert schon ein paar Takte und man muß solange warten
bis sie auch fertig ist, erst dann darf man sich das Ergebnis abholen !!!
WOHER weißt man aber, daß eine Wandlung fertig ist ?


while ( ADCSRA & (1<<ADSC) ) {
; // auf Abschluss der Konvertierung warten
}

habe ich von dort (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ADC_.28Analog_Digital_Converter.29) kopiert
puh, (schweiß wegwisch)....ich hoffe geholfen zu haben :-)

Gruß Sebastian

P.S. nein, ich habe gute Laune, manchmal muß man eben einen Schlag auf den Hinterkopf geben ;-)

radbruch
24.08.2007, 01:30
Hallo


Nein, so eine Wandlung dauert schon ein paar Takte und man muß solange warten bis sie auch fertig ist, erst dann darf man sich das Ergebnis abholen !!!
WOHER weißt man aber, daß eine Wandlung fertig ist ?

Das dachte ich bisher auch, inzwischen bin ich aber nicht mehr sicher, ob es wirklich nur mit handshake funktioniert. Ich habe eher den Verdacht, der ADC wartet bis man die Daten gelesen hat. Für das Low-Byte steht es auch so im Datenblatt:


When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently,
if the result is left adjusted and no more than 8-bit precision is required, it is
sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.(Aus der Beschreibung des Datenregisters S. 217)

Bei meinen Versuchen (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=33228) lese ich ohne Handshake im free-running-Modus vom linksbüdigen Ergebniss nur das High-Byte aus, nach meiner Schätzung schneller als der ADC wandeln kann (Schneller geht's wohl kaum: while (ADCH > 20); ). Wenn ich den prescaler ändere (ich takte mit /2!), ändert sich auch die Datenleserate. Ich bin aber nicht wirklich sicher, weil ich das erst einmal gesehen habe und nicht näher untersucht habe.

In iom32.h wird PA0 so definiert:

/* PA7-PA0 = ADC7-ADC0 */
/* PORTA */
#define PA7 7
#define PA6 6
#define PA5 5
#define PA4 4
#define PA3 3
#define PA2 2
#define PA1 1
#define PA0 0

Also kann man auch PAx direkt in ADMUX.MUX0-4 schreiben.

Gruß

mic

fluchtpunkt
24.08.2007, 12:05
Also kann man auch PAx direkt in ADMUX.MUX0-4 schreiben.
Du kannst natuerlich auch TOIE0 oder was weiss ich schreiben, nur fuehrt das leider die ganze #define-Orgie ad absurdum. Denn wer sagt das beim Mega64231 das ganze genauso definiert ist? Portabilitaet ade.
Viel Spass auch beim Verstehen von Code, wenn man erstmal nachschlagen muss wie denn nun PA0 definiert ist, was man bei MUX0 direkt im Datenblatt beim richtigen Thema sehen kann...


Das dachte ich bisher auch, inzwischen bin ich aber nicht mehr sicher, ob es wirklich nur mit handshake funktioniert. Ich habe eher den Verdacht, der ADC wartet bis man die Daten gelesen hat. Für das Low-Byte steht es auch so im Datenblatt:
Das hast du falsch verstanden. Wenn du ADCL gelesen hast dann wartet der ADC solange mit dem Eintragen eines neuen Wertes bis du auch ADCH gelesen hast. Damit wird verhindert das der ADC das H-Byte aendert wenn du schon das L hast aber das H noch nicht, das wuerde falsche Werte bringen.
Dies ist quasi wie die cli() sei() Sache wenn man 16bit Werte verarbeitet und man nichts im L-Byte haben will was nicht zum H-Byte passt.

izaseba
24.08.2007, 13:35
Radbruch, ich muß leider protestieren, Du verbreitest hier ziemlich viel Unsinn =;

In iom32.h wird PA0 so definiert: Zitat:
/* PA7-PA0 = ADC7-ADC0 */
/* PORTA */
#define PA7 7
#define PA6 6
#define PA5 5
#define PA4 4
#define PA3 3
#define PA2 2
#define PA1 1
#define PA0 0

Schön, und ? hier die ADC Multiplexer Belegung aus dem Dattenblatt:
MUX4...0
00000 ->ADC0
00001 -> ADC1
00010 -> ADC2
00011 -> ADC3
00100 -> ADC4
00101 -> ADC5
00110 -> ADC6
00111-> ADC7

Darfst selber überlegen, bis wann es gut geht, und warum ich sagte, daß es durch ein Zufall klappt ;-)
Und was ist, wenn ich Deine ADCroutine in meinem M8 einsetzen möchte, oder einem Tiny?

Was die Sache mit warten auf das Ergebnis angeht, lese was fluchpunkt gesagt hat, oder lese Appnotes von Atmel, bevor der Wandler nicht signalisiert, daß es fertig ist, hat mal ADC* nicht auszulesen, und bevor man das Ergebnis nicht abgeholt hat, nachdem der Wandler fertig ist werden ADC* nicht aktualisiert ;-)

Gruß Sebastian
P.S. Du darfst auch einen Interrupt benutzen, um ADC auszulesen, der wird auch angesprungen, wenn der Wandler fertig ist

radbruch
24.08.2007, 14:38
Na, das weiß man doch:


/* PA7-PA0 = ADC7-ADC0 */
Mal im Ernst: Ich will hier keine Glaubenskriege auslösen. C ist tückisch und jeder mag programmieren, wie er will. Ich versuche nur zu verstehen, wie so ein AVR tickt.

Gruß

mic

izaseba
24.08.2007, 14:53
Ne.ne kriege wollen wir nicht, wir wollen es nur richtig machen und vor allem wollen wir, daß Leute, die in ein paar Monaten diesen Beitrag finden auch alles richtig machen

Gruß Sebastian

Spongebob85
25.08.2007, 12:43
Moin.
Ich hab es immer noch nicht hinbekommen. Ich hab jetzt einen Kondensator mit 100nF zwischen AREF und GND geschaltet und im Programm alles mögliche gemacht:


#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL

int main(void)
{
DDRC = (1<<PC0);
uint16_t x;

SFIOR = ((0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0));

ADCSRA = ((1<<ADEN) | (1<<ADATE) | (1<<ADPS0) | (1<<ADPS1));

ADMUX = (1<<REFS0);
ADMUX = ((0<<MUX0) | (0<<MUX1) | (0<<MUX2) | (0<<MUX3) | (0<<MUX4)); //damit ist ADC0-Eingang
//gewählt

ADCSRA |= (1<<ADSC); //hiermit wird die Messung initialisiert und gestartet

while(1)
{
while (ADCSRA & (1<<ADSC))
{
;
}

x = ADCL;
x += (ADCH<<8);

if (x >= 8000)
{
PORTC |= (1<<PC0);
}
else
{
PORTC &= ~(1<<PC0);
}
}
}


Ich werde mich heute auf jeden Fall noch mal ransetzen und ganz in ruhe versuchen das mal im Single Convention Mode zu programieren.
Das ergebnis wird doch in 16 bit dargestellt sein, wobei 8000 doch ca. 2,5V bedeuten, wenn ich an AREF 5V Anlege, oder?

MfG Jan

Hubert.G
25.08.2007, 13:16
Mit 10 Bit und in deinem Fall 512 wirst du dich begnügen müssen.

Spongebob85
25.08.2007, 22:50
Aber 10 bit sind doch 1024. Warum 512?
Ich dachte es gibt ein More Significant Byte und ein Low Significant Byte also 2 Byte also 16 Bit. Warum hab ich denn plötzlich nur noch 10, bzw. 9?
Oder versteh ich jetzt was völlig falsch?

radbruch
25.08.2007, 23:10
Der ADC wandelt den Wert mit 10Bit. Die kann man dann links- oder rechtsbündig als 16Bit-Wert auslesen, es sind aber immer nur 10 davon wirklich wertig.

Spongebob85
25.08.2007, 23:35
Jetzt verstehe ich das auch mit links oder rechtsbündig. endweder steht da dann z.B. 0000001111111111 oder 1111111111000000 wobei die Nullen keinen wert besitzen. Ich lese mir grade im datenblatt alles über den ADC durch. Komme immer besser damit klar.
Danke erstmal für die nette hilfe.

MfG Jan

Hubert.G
26.08.2007, 11:04
Genau so ist es. Der Wert von AREF wird durch 1024 geteilt, wenn AREF 5V sind und am Eingang liegen 2,5V an, dann bekommst du als Ergebnis 512 .
AREF sollte daher gleich dem größten zu messenden Wert sein, dann hat man die beste Auflösung. Die Frage ist nur ob man sie tatsächlich immer braucht.
Hubert

fluchtpunkt
26.08.2007, 11:13
ADMUX = (1<<REFS0);
ADMUX = ((0<<MUX0) | (0<<MUX1) | (0<<MUX2) | (0<<MUX3) | (0<<MUX4)); //damit ist ADC0-Eingang

...und REFS0 wieder ausgeschaltet. Das ganze Register ADMUX ist wieder 0. Falls das nicht nur ein Tippfehler war solltest du dich nochmal dringend mit Bitoperationen auseinandersetzen.
Verodern mit 0 kann man sich uebrigens sparen.

[quote]More Significant Byte
Most...

radbruch
26.08.2007, 12:31
Hallo


Verodern mit 0 kann man sich uebrigens sparen.
Da der Kompiler die Veroderungen eh als berechnete Konstante ablegt ist es egal, wie man es formuliert. Bei (Dummy-)-Nullen im Grundgerüst für verschiedene Einstellungen kann man die jeweiligen Bits setzen ohne zuvor lange im Datenblatt zu stöbern und läuft keine Gefahr, irgendwelche wichtigen Bits zu vergessen. Als Beispiel mein "Grundgerüst" in der Einstellung für maximale Samplerate:


// ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR) | 4;
// setze free running triggern
SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// kein interupt, Wandler einschalten, prescaler /2
ADCSRA = (0<<ADIE) | (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
// Autotriggern bedeutet jetzt free running aktivieren, altes Flag löschen
ADCSRA |= (1<<ADATE) | (1<<ADIF);
// Initialisierung starten
ADCSRA |= (1<<ADSC);
// und noch die wohl eher unnötige Initiallesung
while (!(ADCSRA & (1<<ADIF)));
ADCSRA |= (1<<ADIF);


Gruß

mic

izaseba
26.08.2007, 12:47
Radbruch, Du hast den Prescaller auf 2 stehen, oder hab ich da was falsch gelesen?
Bei welchem Systemtakt 8 Mhz ? Das funktioniert ?
Dir ist klar, daß laut Dattenblatt der ADC mit maximal 200 kHz laufen soll ?

Gruß Sebastian

P.S. Atmel schreibt zwar, wenn man eine Genauigkeit kleiner 10 Bit braucht kann man den Takt höher setzen, leider schreiben die nicht, wo die Grenze liegt, aber 4 MHz ist schon nicht schlecht...

radbruch
26.08.2007, 13:15
Hallo


Radbruch, Du hast den Prescaller auf 2 stehen, oder hab ich da was falsch gelesen?
Ja, prescaler /2 bei 8MHz-ATMega, du hast richtig gelesen. Noch habe ich keine Bestätigung durch Nachbauer:

Kamera am RP6 (https://www.roboternetz.de/phpBB2/viewtopic.php?t=33228)

Hier noch mein Thread zur maximalen Samplerate:

https://www.roboternetz.de/phpBB2/viewtopic.php?t=33070

Gruß

mic

izaseba
26.08.2007, 13:25
Das dachte ich mir schon ;-)
Allerdings wäre ein Hinweis nicht schlecht, daß Du nur 4 Bits brauchst, sonst gibt es bald fragen, wie: "Ich habe den ADC so eingestellt, wie url=... beschrieben, allerding kommt nur Müll raus... hilfe ich bin Anfänger"
Weißt Du was ich meine ?

radbruch
26.08.2007, 14:04
Ich rechne nur mit den oberen 4 Bits weiter, um Speicher und Rechenpower zu sparen. Es werden aber trotzdem 8 Bit ausgelesen und die sind alle gültig.

Spongebob85
27.08.2007, 13:50
Moin!!!
Mein Prog funktioniert jetzt. Hier der Code:


#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL

int main(void)
{
uint16_t result;
DDRC = (1<<PC0);

ADMUX = 0x00; //AREF, resultat rechtsbündig, ADC-Eingang ADC0
ADCSRA = ((1<<ADEN) | (1<<ADPS1) | (1<<ADPS0)); //ADC eingeschaltet, Teilungsfaktor 8

while(1)
{
ADCSRA |= (1<<ADSC);
while (ADCSRA & (1<<ADSC))
{
;
}
result = ADCL;
result += (ADCH<<8);

if (result >= 512) //LED geht ziemlich genau bei 2,5V an!!!
{
PORTC |= (1<<PC0);
}
else
PORTC &= ~(1<<PC0);
}
}

Jetzt stellt sich mir nur noch so die Frage, was das mit dem Autotrigger bedeutet. Das hab ich im Datenblatt nicht so ganz verstanden.
Ich hab ja den 5.Bit in ADCSRA nicht gesetzt und auch das SFIOR register ganz außen vor gelassen. Laut der Tabelle im Datenblatt müsste jetzt FreeRunning Mode eingeschaltet sein. Hab ja alles für Single convention vorbereitet.
Warum klappt das dann trotzdem?
Was hat das mit dem Autotrigger auf sich?

MfG Jan