Hallo,
ich bin am verzweifeln, probiere nun schon Wochen einen Atmege8
Analogeingang zu Programmieren aber er will nicht so richtig.
Wenn ich ganz ehrlich bin es tut sich eigentlich gar nichts.
Hier mein C-Code
#define F_CPU 1e8
#include <util/delay.h> // Include Datei für die Verzögerungsfunktion
#include <avr/io.h>
int main (void)
{
int sample,value; // Varieblen defination
DDRB = 0xFF; // PORTB als Ausgabeport
ADMUX = (0<<REFS1 |(0<<REFS0)); // Exterme Referenzspannung
ADMUX = (0<<MUX0 | (0<<MUX1 | (0<<MUX2 |(0<<MUX3)))); //Kanal0,Pin PC0
while (1)
{
sample=0; // setzt den Sampelwert auf 0
ADCSRA |= (1<<ADSC); // ADC einschalten
value = ADCW;
if (value<0)
PORTB=0x04;
}
}
Hoffe es kann mir einer weiter Helfen
Schon mal Danke im vorraus.
Hallo,
habe das jetzt schon ein paar mal durchgelesen ausprobiert und komme
trotzdem nicht weiter.
Ich weiß einfach nicht weiter.
Wäre nett wenn mir noch einer ein paar Tipps oder Programm
Verbesserungen sagen bzw. was falsch ist.
Den ADC aktivieren kann man mit ADEN =1. Ich weiß aber nicht, wie das in
"C" formuliert werden muss.
Das sehe ich nicht im Programm. Eventuell liegt es daran.
MfG Paul
> #define F_CPU 1e8
Du lässt den Mega8 mit 100 Mhz laufen?
> while (1)> {> sample=0; // setzt den Sampelwert auf 0
Wozu benötigst du die Variable "sample"? Ich vermute, dass du hier nicht
den kompletten Code geposted hast.
> ADCSRA |= (1<<ADSC); // ADC einschalten
Vielleicht solltest du den ADC auch enablen (ADEN).
> value = ADCW;
Bevor du versuchst das Wandlungsergebnis auszulesen musst du erst einmal
das Ende der Wandlung abwarten.
> if (value<0)
Die Variable "value" ist ein Integer (ohne Vorzeichen). Diese Variable
kann also niemals kleiner 0 sein.
> PORTB=0x04;
Somit wird diese Anweisung auch nie ausgeführt werden.
Knoddelpusch schrieb:> Hallo,>> habe das jetzt schon ein paar mal durchgelesen ausprobiert und komme> trotzdem nicht weiter.
Hast du offensichtlich nicht. Denn im Beispiel-Code, den du quasi 1:1
hättest übernehmen können, steht doch:
1
ADCSRA|=(1<<ADEN);// ADC aktivieren
2
...
3
ADCSRA|=(1<<ADSC);// eine ADC-Wandlung
das hätte dich zumindest mal kurz zum nachdenken bringen müssen. Denn
ADEN hast du gar nicht verwendet und hinter "ADCSRA |= (1<<ADSC);" steht
irgendwie ein Kommentar das bei dir anders aussieht. Und im Datenblatt
hättest du auch gesehen, dass das so nicht ganz richtig sein kann.
Hallo,
Sind 100 Mhz zu viel?
Habe jetzt alles noch mal nach geschaut und habe diverse abänderungen
gemacht.
Ich habe hier jetzt noch ein mal das überarbeitete Programm.
#define F_CPU 1e8
#include <util/delay.h> // Include Datei für die Verzögerungsfunktion
#include <avr/io.h>
int main (void)
{
int value; // Varieblen defination
DDRB = 0xFF; // PORTB als Ausgabeport
ADMUX = (0<<REFS1 |(0<<REFS0)); // Exterme Referenzspannung
ADMUX = (0<<MUX0 | (0<<MUX1 | (0<<MUX2 |(0<<MUX3)))); // Kanal 0, Pin
PC0
while (1)
{
ADCSRA = ADEN; // ADC einschalten
ADCSRA |= (1<<ADSC); // eine AD-Wandlung
while (ADCSRA & (1<<ADSC) ) {}
// auf Abschluss der Konvertierung warten
value = ADCW;
if (value>0)
PORTB=0x04;
}
}
Bekomme es aber immer noch nicht zu laufen.
Den Frequenzvorteiler brauch man ja bei dem Programm nicht oder?
Möchte eine Eingangsspannung von 2,5 V abfragen bzw. wenn eine Spannung
am Eingang liegt soll eine Lampe angehen.
Knoddelpusch schrieb:> #define F_CPU 1e8
Bitte tu dir den Gefallen und arbeite erstmal da Tuttorial durch.
Und solange du nicht sattelfest in der Materie bist, würde ich dir
raten, die Beispiele 1 zu 1 aus dem Tutorial kopieren und testen, BEVOR
du sie veränderst.
Knoddelpusch schrieb:> Sind 100 Mhz zu viel?
Dein ATmega8 wird bestimmt nicht mit 100 MHz laufen.
> #define F_CPU 1e8
Warum immer noch?
> #include <util/delay.h> // Include Datei für die Verzögerungsfunktion
Wozu bindest du krampfhaft die Delay-Lib ein, wenn du sie nicht benutzt?
> while (1)> {> ADCSRA = ADEN; // ADC einschalten
Das "ADCSRA = ADEN;" setzt du noch VOR den Endlos Loop.
> if (value>0)> PORTB=0x04;> Möchte eine Eingangsspannung von 2,5 V abfragen bzw. wenn eine Spannung> am Eingang liegt soll eine Lampe angehen.
Das Wandlungsergebnis auf >0 zu prüfen ist dann ziemlicher Quatsch. Wie
groß ist die von dir extern zur Verfügung gestellte Referenzspannung?
> Bekomme es aber immer noch nicht zu laufen.
Wundert mich nicht.
> Den Frequenzvorteiler brauch man ja bei dem Programm nicht oder?
Der ADC-Takt sollte für die volle 10 Bit Auflösung <= 200 kHz sein. Wenn
du den Prescaler mit "0" fütterst, teilt dieser durch 2. Das bedeutet,
dass dein Prozessortakt nicht größer als 400 kHz sein darf.
--> Mit welchem Takt versorgst du den Controller?
> Das "ADCSRA = ADEN;" setzt du noch VOR den Endlos Loop.
Die Position wäre ja egal, er kann den ADC ja beliebig of einschalten.
Allerdings funktioniert das so nicht, da es
ADCSRA = (1<<ADEN);
sein sollte, da ADEN nur die Bitnummer ist.
Den ADC kann man auch übertakten, wenn man möchte, die Genauigkeit geht
halt flöten.
Allerdings verstehe ich den TO nicht. Er könnte einfach mal das Beispiel
aus dem Tutorial kopieren und ausprobieren. Danach kann er es ja von mir
aus ändern und zwischendurch austesten, ob es noch läuft.
Allgemein denke ich aber, dass da massiv Grundlagen in Form der
vorhergegangenen Tutorialkapiteln fehlt.
:-)
Hallo,
auch ich habe ein Problem mit dem Programm...
Unter dem AVR Studio 4 bricht er mit dem fehler ab, dass adcw nicht
definiert ist... im avr studio 6 kommt folgende fehlermeldung:
------ Build started: Project: Batterieprüfer, Configuration: Debug AVR
------
Build started.
Project "Batterieprüfer.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition;
('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "D:\Programme\Atmel\Atmel Studio
6.0\Vs\Compiler.targets" from project
"C:\Users\Steven\Desktop\Batterieprüfer\Batterieprüfer\Batterieprüfer.cp
roj" (target "Build" depends on it):
Using "RunCompilerTask" task from assembly "D:\Programme\Atmel\Atmel
Studio 6.0\Vs\Compiler.Task.dll".
Task "RunCompilerTask"
D:\Programme\Atmel\Atmel Studio 6.0\make\make.exe all
make: *** No rule to make target `Batteriepr├╝fer.o', needed by
`Batteriepr├╝fer.elf'. Stop.
Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "Batterieprüfer.cproj" --
FAILED.
Done building project "Batterieprüfer.cproj" -- FAILED.
Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped
==========
Ideen?
Vermeide bei
- Dateinamen
- Verzeichnisse
- Make Targets
- Variablen
- Funktionen
- Definitionen
Leerzeichen, Sonderzeichen und alle Zeichen, die nicht im 7Bit US-ASCII
Zeichensatz enthalten sind.
Also beschränke Dich auf 0-9, A_Z, a-z und _.
Steven S. schrieb:> ja, und auf deutsch?
das bisschen nachdenken war wohl zu anstrengen.
keine minute nach dem hinweis schon die frage - gratuliere.
wie naiv zu erwarten, du würdest zu
Steven S. schrieb:> habe das jetzt soweit umgebastelt... aber irgendwie gibt er mir als> ergebnis immer 0 aus... Habe ein Stk 500 und einen AtMega16
noch eine fehlermeldung posten. nein, die müssen wir schon erraten...
http://www.zeit.de/wissen/2009-9/vorurteile-namen-grundschullehrer
du darfst dich hier gleich einreihen...
Steven S. schrieb:> habe das jetzt soweit umgebastelt... aber irgendwie gibt er mir als> ergebnis immer 0 aus... Habe ein Stk 500 und einen AtMega16
Ich habe mir der Einfachheit halber jetzt nur mal deine main()
angesehen.
Deine Abfrage
> if (Ergebnis<100)> {> PORTB|=(0<<PB0);> }
setzt dir den Portpin auf 1 sobald auch nur ein einziges
Wandlungsergebnis kleiner als 100 ist. Der Portpin wird jedoch niemals
wieder auf 0 gesetzt wenn die Wandlung ein Ergebnis >= 100 liefert!
Versuche es mal mit
if (Ergebnis<100)
{
PORTB|=(0<<PB0);
}
else
{
PORTB&= ~(0<<PB0);
}
Magnus M. schrieb:> Deine Abfrage>>> if (Ergebnis<100)>> {>> PORTB|=(0<<PB0);>> }>> setzt dir den Portpin auf 1
Nope.
Das setzt überhaupt nichts auf 1.
An den Port kann er 0 zuweisen bis er schwarz wird. Der Pin wird niemals
1 (bzw. 0, was wohl die eigentliche Absicht gewesen sein dürfte). Egal
was vom ADC kommt.
@Frager
Womit wir wieder beim Punkt angelangt wären:
Lies das Tutorial von Anfang an!
Es ist sinnlos, sich mit komplizierteren Projekten zu befassen, solange
du nicht die allerersten, einfachsten Grundlagen sicher im Griff hast.
Einen Pin gezielt auf 0 oder 1 zu setzen ist etwas, das DARF dir keine
Probleme mehr verursachen!
Bitmanipulation
Karl Heinz Buchegger schrieb:> Magnus M. schrieb:>>> Deine Abfrage>>>>> if (Ergebnis<100)>>> {>>> PORTB|=(0<<PB0);>>> }>>>> setzt dir den Portpin auf 1>> Nope.>> Das setzt überhaupt nichts auf 1.
Oh shit.... ich hatte doch glatt die "0<<" übersehen... Wie auch immer:
selbst wenn dort "1<<" gestanden hätte, wäre es murks gewesen.
wenn du eine Wandlung startest, musst du schon auch abwarten bis die
Wandlung fertig ist.
Gut, bei dir spielt das jetzt keine große Rolle, weil dann eben das
Ergebnis der aktuell gestarteten Wandlung im nächsten Durchlauf zur
Verfügung steht (und dann die nächste Wandlung schon wieder läuft). Aber
spätestens dann, wenn du mehrere Wandlungen auf bunt gemixten
ADC-Eingängen brauchst, gibt das Ergebnis-Salat.
Wenn schon dann machs lieber so rum ...
1
Wert=ADCW;// Ergebnis der letzten Wandlung holen ...
2
ADCSRA|=(1<<ADSC);// und gleich die nächste Wandlung starten ...
3
// dann kann der ADC Wandler arbeiten, während
4
// das Ergebnis der letzten Wandlung ausgewertet
5
// wird
... denn dann ist auch klar, dass diese Parallelverarbeitung
beabsichtigt ist.
aber ganz ehrlich: um ein paar LED zu schalten, spielen die paar
ADC-Takte Verzögerung, die man mit 'Wandlung starten - Ergebnis abwarten
- Ergebnis holen' hat nicht wirklich die große Rolle.