Hallo, seit einigen Wochen schaue ich mir hier eure Beiträge an. Nun bin ich zur Zeit dabei das Tut durchzuarbeiten und hänge gerade an dem ADC des Atmega32. Der wird mit 16Mhz betrieben und der Vorteiler entsprechend auf 128 gesetzt. Der Smartprog2 dient mir hierbei als Brenner. Jetzt hab ich das Problem das ich gerne ein Programm hätte, mit dem ich die Werte des ADCL Registers direkt auf einen Port ausgeben möchte. Anbei habe ich einen Anhang über den Versuch einen Vorhandenen Quellcode zu nutzen. Der Quellcode im Tut liest ja nur einen Wert aus und Speichert ihn in der Variablen "result". Meine Kenntnisse in C sind nicht gerade gut, so viel sei gesagt ;) Danke schonmal für eure Hilfe.
es passiert rein gar nichts. Die Pins 0-3 von PortB leuchten, vorher Pin 4-7. Ich habe vergessen zu erwähnen das ich lediglich ein Poti messen will. Auch am Poti drehen bringt nichts.
1 | // Jetzt 4x die analoge Spannung and Kanal channel auslesen
|
2 | // und dann Durchschnittswert ausrechnen.
|
3 | for(i=0; i<4; i++) { |
4 | // Eine Wandlung
|
5 | ADCSRA |= (1<<ADSC); |
6 | // Die Wandlung abwarten
|
7 | while(ADCSRA & (1<<ADSC)); |
8 | |
9 | resulthigh = ADCW; |
10 | }
|
11 | // ADC wieder deaktivieren
|
12 | ADCSRA = (0<<ADEN); |
13 | resulthigh /= 4; |
Funktioniert nicht, weil bei resulthigh = ADCW; die addition fehlt. Der Code mist 4x und überschreibt das letzte Ergebnis immer mit dem neuen. Danach teilt er das durch 4. Dabei kommt dann etwas zwischen 0 und 255 raus, Was ja deutlich kleiner als 700 ist. Mach mal resulthigh += ADCW; draus, damit der aufsummiert. Ausserdem musst du vor den 4 Messungen noch resulthigh auf 0 Setzen, da darin ja bereits der Dummy read gespeichert ist. Dann sollte das gehen. wenn nicht, Prüfe mal bitte ob der ADC im 8 Bit mode Arbeitet. Wenn du den ADC wert Binär auf einem Port sehen willst mach in main() sowas wie PORTB = resulthigh / 4; (Durch 4 da der AD 0..1023 misst, dein Port aber nur 0..255 anzeigen kann)
hallo, danke erstmal an die schnelle Hilfe. Habe ehrlich gesagt nicht damit gerechnet. Werde mich heute nachmittag erst da rangeben können weil es ein Projekt für die Ausbildung sein soll
Hallo mal wieder, bin heute noch dazu gekommen den Vorschlag von Tim durchzugehen, allerdings ohne erfolg. Das Programm habe ich angepasst, nochmal nachgeschaut ob auch alles richtig verkabelt ist, allerdings tut sich rein gar nichts wenn ich das Poti ändere. Aber ich habe es doch richtig verstanden das das Prog immer in einer Endlosschleife Werte vom ADC ließt und dann an die Variable übergibt. Vielleicht noch jemand eine andere Idee? Habs auch schon mit nem anderen ATMEGA32 getestet ohne Erfolg. Den Code habe ich nochmal angehangen
Hier setzt Du den Kanal: > ADMUX = channel; > //AREF als Spannungsquelle des ADC ...und hier löschst Du ADMUX komplett! > ADMUX = (0<<REFS0) | (0<<REFS1); > ADMUX = (0<<ADLAR); //ergebnis rechtsb�ndig ausrichten Das kann man auch einfach "ADMUX = 0;" schreiben. Überlege bitte mal, was "0 << IRGENDWAS" ergibt... OK, in Deinem Fall ist dieser Klops fast egal, weil sowieso Kanal 0 gewandelt wird, aber das solltest Du in Zukunft anders machen. Gleiches gilt natürlich für die Zeile "ADCSRA = (0 << ADEN);". Es gibt unendlich viele Möglichkeiten, eine Null zu schreiben, aber es gibt in den meisten Fällen keinen Grund, nicht die kürzeste und einfachste zu nehmen.
Das hier
> DDRA = 0xff;
...schaltet den kompletten Port A als Ausgang. Da beim ATMega32 aber
die Analog-Eingänge an Port A liegen, ist das sehr wenig sinnvoll...
Gast wrote:
> Ist das "return (0);" nicht böse zur while Schleife?
Richtig, das return hat in der while-Schleife nichts zu suchen!
@johannes So hatte ich das aus dem Tut herauskopiert. Anscheinend läuft es auch mit diesen Einstellungen. Das man "0" auch anders schreiben kann vor allem in registern ist mir bewusst ;) Hatte es irgendwann mal getestet und ist dann leider auch so hängen geblieben. Danke für den Tip. Die Sache mit den Eingängen schalten wird es wohl sein, leider habe ich die sachen nicht hier. @gast return(0) wird in dieser Funktion nie erreicht. Man kann es genausogut weglassen, ändert aber beim µC gar nichts. Zumindest habe ich nix festgestellt. Danke euch vielmals. Werde mich morgen wieder melden wenn ich die Sachen ausprobiert habe.
Hi das return(0) gehört aber nach der schließenden Klammer vom while (1), bzw. es gehört zum int main(void) und wird deshalb nie erreicht, weil du die while (1) Schleife nicht verläßt. So stehts auch im Tut. Gruß MISZOU
Dominik wrote: > @johannes > > So hatte ich das aus dem Tut herauskopiert. Anscheinend läuft es auch > mit diesen Einstellungen. Was läuft? Das Tutorial auf dieser Seite ist für einen ATMega8 geschrieben. Bei dem liegen die Analog-Eingänge an Port C. Beim ATMega32 sind sie an Port A, wie ein Blick ins Datenblatt auch Dir offenbaren wird. > @gast > return(0) wird in dieser Funktion nie erreicht. Doch, in Deinem Fall wird es erreicht! Es steht in der while-Schleife und wird nach der if-Abfrage erreicht...
Johannes M. wrote: > Doch, in Deinem Fall wird es erreicht! Es steht in der while-Schleife > und wird nach der if-Abfrage erreicht... Und ich möchte hinzufügen: Eine vernnftige und konsistente Einrückstrategie hätte das auch klar und deutlich gezeigt. Wieder mal ein Fall, indem eine saubere Codeformatierung Wunder wirken kann.
Ich danke euch vielmals für die Hilfe. Das Programm funktioniert nun einwandfrei. Anbei möchte ich nochmals anmerken das ich wirklich blutiger Anfänger bin. Den Code hänge ich später noch an.
So hier im Anhang befindet sich wie versprochen ein kleines Programm, mit dem der ADC in 50er Schritten jeweils eine LED weiter schaltet. Vielen Dank nochmals für eure Hilfe
Hallo Dominik, um die ganzen if Abfragen zu vereinfachen kannst Du auch modulo rechnen.
1 | while(1) |
2 | {
|
3 | PORTD = (readADC(0) % 50) + 1 |
4 | }
|
Rainer I. wrote:
> um die ganzen if Abfragen zu vereinfachen kannst Du auch modulo rechnen.
Wieso Modulo ? Du weißt, was Modulo macht? Hier muss, wenn überhaupt,
dann eine normale Division her. Der Rest der Division interessiert
hier nicht.
Sorry, hast Recht. Hab mich vertan.
1 | while(1) |
2 | {
|
3 | PORTD = (readADC(0) / 50) + 1 |
4 | }
|
Mit dieser Zeile geht vergleicht er immer "result" in 50er Schritten und addiert dann in Binärform eine LED weiter?
Dominik wrote: > Mit dieser Zeile geht vergleicht er immer "result" in 50er Schritten und > addiert dann in Binärform eine LED weiter? Genau! Er will schließlich, dass schon bei 0 < result < 50 eine LED leuchtet. Da käme bei der Division aber 0 raus, deshalb muss das Divisionsergebnis um eins erhöht werden.
Hallo Habe es gerade ausprobiert. Die Version von Johannes Funktioniert super.
Dominik wrote:
> Die Version von Johannes Funktioniert super.
Welche Version von mir?
Dominik wrote: > while(1) > { > PORTD = (readADC(0) / 50) + 1 > } > Naja, geschrieben hat es Rainer, nur die Korrektur kam von mir...
ich habe hierzu mal eine frage: wenn ich AREF mit VCC verbinde und ADMUX = 0 setze funktioniert mein programm nicht mehr, setze ich ADMUX = (1<<REFS0) funktioniert es. woran liegt das? muss ich AREF überhaupt mit VCC verbinden? VCC = 5 V bei einem ATMEGA168
Gast wrote: > wenn ich AREF mit VCC verbinde und ADMUX = 0 setze funktioniert mein > programm nicht mehr, setze ich ADMUX = (1<<REFS0) funktioniert es. woran > liegt das? muss ich AREF überhaupt mit VCC verbinden? Das musst Du nicht nur nicht tun, das solltest Du sogar besser sein lassen! AREF ist ausschließlich zum Anschließen einer Referenzspannung, die nicht vom Controller intern zur Verfügung gestellt werden kann. AVCC kann aber intern ausgewählt werden.
gut danke erstmal. also löte ich das wieder ab und lasse AREF frei oder muss ich den irgendwie beschalten? ich werde dann VCC und AVCC mit 5V beschalten und dann ADMUX = 0 setzen. an meinen ADC eingängen hängt ein 10 kohm poti mit max 5V dran. gibts daran was zu verändern? ich will werte von 0 - kleiner 5V einlesen. achso: ich hatte mal einen schaltplan gesehen, wo AREF mit VCC über eine induktivität (10µH?) miteinander verbunden war. was spricht den eigentlich dagegen?
Gast wrote: > gut danke erstmal. also löte ich das wieder ab und lasse AREF frei oder > muss ich den irgendwie beschalten? An AREF normalerweise 100 nF gegen GND. > ich werde dann VCC und AVCC mit 5V > beschalten und dann ADMUX = 0 setzen. an meinen ADC eingängen hängt ein > 10 kohm poti mit max 5V dran. gibts daran was zu verändern? ich will > werte von 0 - kleiner 5V einlesen. Wenn das Poti auch an AVCC hängt, ist das kein Problem. > achso: ich hatte mal einen schaltplan gesehen, wo AREF mit VCC über eine > induktivität (10µH?) miteinander verbunden war. was spricht den > eigentlich dagegen? Wo hast Du das denn gesehen? Normalerweise wird AVCC mit VCC über einen LC-Tiefpass verbunden. AREF sollte mit einem 100nF-Kondensator nach GND beschaltet werden, sonst nichts, außer Du willst eine externe Referenzquelle verwenden. Gegen eine Verbindung von AREF und AVCC spricht (neben der o.g. Sinnlosigkeit) auch, dass man ja vielleicht auch mal eine andere Referenzquelle auswählen möchte, was dann nicht mehr geht.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.