Hallo, ich würde gerne einen ATmega8 in C-Sprache so porgrammieren, dass ich eine Spannung in den AD- Wandler einlese und diese anhand von LED´s anzeigen lassen will! Ich habe ein Programm geschrieben, welches aber nicht funktioniert. Könnte mir bitte jmd helfen? MfG Martin #include <avr/io.h> void main(void) { int b; DDRC = 0x00; DDRD = 0xFF; ADCSRA = 0xE6; while(1) { b = ADCW; if(b>51 && b<58) PORTD = 0x01; if(b>59 && b<64) PORTD = 0x03; if(b>65 && b<71) PORTD = 0x07; if(b>72 && b<77) PORTD = 0x0F; if(b>78 && b<83) PORTD = 0x1F; if(b>84 && b<90) PORTD = 0x3F; if(b>91 && b<96) PORTD = 0x7F; if(b>97 && b<102) PORTD = 0xFF; } }
Vielleicht liest du dir das hier mal durch: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ADC_.28Analog_Digital_Converter.29 Oliver
lies mal das datenblatt vom atmega8 durch, dann findest du auch noch ein Beispiel...
Der Fehler liegt darin, dass du zwar den ADC ständig auslesen willst, aber nach einer fertigen Wandlung wird der ADC ja angehalten und du musst ihn wieder starten!
1 | while(1) |
2 | {
|
3 | |
4 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung |
5 | while ( ADCSRA & (1<<ADSC) ) { |
6 | ; // auf Abschluss der Konvertierung warten |
7 | |
8 | b = ADCW; |
9 | |
10 | ...
|
11 | |
12 | }
|
13 | }
|
damit sollte es funktionieren, sofern der Rest richtig initialisiert wurde.
echt? ich hab ihn ja eig im free runing mode, deswegen denk ich dass er eig ständig läuft! martin
> Ich habe ein Programm geschrieben, welches aber nicht funktioniert.
Denkst du daß "nicht funktioniert" eine sinnvolle Feherbeschreibung ist?
Wie sieht der Testaufbau aus? Was passiert genau? Was hättest du
erwartet? Ist ein Hardware-Fehler auszuschließen?
ja des kann man jetzt auslegen wie man will, aber da das prgramm einen fehler enthält funktioniert es für mich nicht! die hardware stimmt und der grundaufbau vom programm auch! der fehler liegt eindeutig an der programmierung des AD- wandlers, aber ich weiß halt nicht woran! hab mir das datenblatt durchgelesen und schon diverse seiten und deshalb scuh ich hier hilfe! mfg martin
Martin schrieb: > ja des kann man jetzt auslegen wie man will, aber da das prgramm einen > fehler enthält funktioniert es für mich nicht! es ist immer hilfreich, nicht zu sagen, was nicht funktioniert, das macht das Helfen immer so einfach... > die hardware stimmt und > der grundaufbau vom programm auch! das sagen sie immer... > der fehler liegt eindeutig an der > programmierung des AD- wandlers, aber ich weiß halt nicht woran! hab mir > das datenblatt durchgelesen und schon diverse seiten und deshalb scuh > ich hier hilfe! und behälst alle grundlegenden Infos für dich, sehr schlau... und sowas
1 | ADCSRA = 0xE6; |
macht man nicht!
Justus Skorps schrieb: > und sowas > >
1 | > ADCSRA = 0xE6; |
2 | >
|
> > macht man nicht! Genauer gesagt hält es mich (und wahrscheinlich viele andere ebenso) davon ab, auch nur einen Gedanken an Hilfe zu verschwenden. Wenn du es absichtlich möglichst kryptisch schreibst, dann sieh zu wie du alleine zurecht kommst. Das C-Motto "Es war schwer zu schreiben, es soll auch schwer zu lesen sein" ist längst allgemein ad acta gelegt worden :-)
Im Datenblatt vom Mega16 steht zb (funktioniert beim Mega8 genau gleich. Das 16er hab ich aber gerade im anderen Fenster offen) > Using the ADC Interrupt Flag as a trigger source makes > the ADC start a new conversion as soon as the ongoing conversion > has finished. The ADC then operates in Free Running mode, > constantly sampling and updating the ADC Data Register. The > first conversion must be started by writing a logical one to > the ADSC bit in ADCSRA. Da ich aber kein Interesse daran habe, dein 0xE6 auseinanderzudröseln, kann ich auch nicht sagen, ob du ADSC setzt oder nicht.
und sowas > >> ADCSRA = 0xE6; > > > macht man nicht! wie macht man es dann? is doch egal ob ich des schreib oder: ADCSRA = 0b11100110 mfg martin
ja gut macht sinn, so ist es leichter zu verstehen! ;-) martin
Martin schrieb: > und sowas >> >>> ADCSRA = 0xE6; >> > >> >> macht man nicht! > > > wie macht man es dann? So ADCSRA = ( 1 << ADEN ) | // Enable ( 1 << ADSC ) | // Start Conversion ( 1 << ADATE ) | // Auto Trigger Enable ( 1 << ADPS2 ) | // Prescaler 64 ( 1 << ADPS0 ); und dann hat man auch ein paar Schlüsselwörter, mit denen man im Datenblatt suchen kann. Zb. steht im Dtaenblatt bei ADATE • Bit 5 – ADATE: ADC Auto Trigger Enable When this bit is written to one, Auto Triggering of the ADC is enabled. The ADC will start a conversion on a positive edge of the selected trigger signal. Wo machst du letzteres, bzw. wie stellst du sicher, dass so ein Trigger Signal kommt?
Martin schrieb: > und sowas >> >>> ADCSRA = 0xE6; >> > >> >> macht man nicht! > > > wie macht man es dann? > > is doch egal ob ich des schreib oder: > > ADCSRA = 0b11100110 > > mfg martin Die Kollegen wollen darauf hinaus, dass es selbsterklärend ist wenn man ADCSRA = (1 << Bitname) schreibt. Michael
Ja das ist egal es ist beides Mist. Schau doch mal ins TUT http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Analoge_Ein-_und_Ausgabe Da sind Beispiele wie man leserlich programmiert und sogar so ziemlich "out of the Box" funktionieren.
Was passiert eigentlich, wenn du * zuerst den ADC fertig konfigurierst * und erst dann mittels ADSC die erste Konvertierung startest
1 | ADCSRA = ( 1 << ADEN ) | // Enable |
2 | ( 1 << ADATE ) | // Auto Trigger Enable |
3 | ( 1 << ADPS2 ) | // Prescaler 64 |
4 | ( 1 << ADPS0 ); |
5 | |
6 | |
7 | ADCSRA |= ( 1 << ADSC ) | // und los gehts! |
Auch vermisse ich die Einstellung der Referenzspannung. Machst du nichts, dann hast du: AREF, Internal Vref turned off Daher die Frage: Wie sieht deine ARef Beschaltung aus?
Karl heinz Buchegger schrieb: > > Zb. steht im Dtaenblatt bei ADATE > > • Bit 5 – ADATE: ADC Auto Trigger Enable uhm, also in meinem Datenblatt zum Mega8 gibt es kein ADATE...
hmm warum nicht den ADC Complete ISR nutzen ^^ immer wenn der wert fetrig ist kommt ein interrupt dann kann man auch schnell die LED setzen und fertig
Justus Skorps schrieb: > Karl heinz Buchegger schrieb: > >> >> Zb. steht im Dtaenblatt bei ADATE >> >> • Bit 5 – ADATE: ADC Auto Trigger Enable > > > uhm, also in meinem Datenblatt zum Mega8 gibt es kein ADATE... Kram, kram, kram Tatsächlich. Ds heißt beim Mega8 anders als im Mega16 OK. Dann nenn es ADFR (Funktioniert auch ein wenig anders. Hätte doch wohl das Mega8 DB raussuchen sollen) Ich würd es aber trotzdem mit der Variante: "Zuerst fertig konfigurieren, dann starten" versuchen.
1 | ADCSRA = ( 1 << ADEN ) | // Enable |
2 | ( 1 << ADFR ) | // Free running |
3 | ( 1 << ADPS2 ) | // Prescaler 64 |
4 | ( 1 << ADPS0 ); |
5 | |
6 | |
7 | ADCSRA |= ( 1 << ADSC ) | // und los gehts! |
Und die Frage nach der Referenzspannung bleibt natürlich auch noch
Karl heinz Buchegger schrieb: > Tatsächlich. Ds heißt beim Mega8 anders als im Mega16 > OK. Dann nenn es ADFR > > (Funktioniert auch ein wenig anders. Hätte doch wohl das Mega8 DB > raussuchen sollen) wenn es nur ein anderer Name gewesen wäre hätte ich schon nicht gemeckert ;c) > Und die Frage nach der Referenzspannung bleibt natürlich auch noch aber sein Hardware-Aufbau ist doch garantiert richtig und ein Geheimnis...
> ja des kann man jetzt auslegen wie man will, aber da das prgramm einen > fehler enthält funktioniert es für mich nicht! Was ich damit ausdrücken wollte, war, daß "funktioniert nicht" keine auch nur annähernd ausreichende Beschreibung des Verhaltens ist. Was mir auffällt ist, daß nur in einem recht kleinen Bereich von 5% bis 10% der AREF-Spannung überhaupt irgendwelche Ausgänge high-Pegel bekommen. Ob das so gehört, weiß ich nicht, da du es ja partout nicht verraten willst. Ohne zu wissen, welche Spannungen du an den Eingang anlegst, was an AREF angelegt ist und welche Ausgaben du darauf erwartest, glaube ich dir deshalb nicht einfach so, daß da kein Fehler sein kann. > die hardware stimmt und der grundaufbau vom programm auch! Hmm, und da bist du dir absolut 100%ig sicher?
>> die hardware stimmt und der grundaufbau vom programm auch! >Hmm, und da bist du dir absolut 100%ig sicher? Ist doch klar: Der ATMega ist kaputt. Was anderes kann es ja gar nicht mehr sein, wo doch alles 100% in Ordnung ist, (ausser, daß es nicht funktioniert) Das Programm ist es nämlich auch nicht. Das sollte das tun, was du da hingeschrieben hast. Oliver
Spaetestens, wenn man mit sowas wie den AD-Wandlern spielen will, sollte man sich vieleicht erst eine gescheite Ausgabemoeglichkeit beschaffen (egal ob seriell oder Display).
>Ist doch klar: Der ATMega ist kaputt.
Nachtrag: Das wäre nicht der erste Mega, der sich mit VCC an AREF nach
einer unbeabsichtigt aktivierten internen Spannungsreferenz sehr seltsam
verhält.
Oliver
hallo, die AREF liegt bei meiner Hardware an der VCC. Die VCC beträgt natürlich 5 Volt. Und ich möchte gerne, dass 8 LED´s eine Spannung zwischen 1 und 2 Volt an einem Balken anzeigen! Die LED´s werden über ULN2803 Treiber angesteuert! mfg martin
OK. Dann würde ich jetzt erstmal vorschlagen, die ADC Funktion aus dem gcc-Tutorial zu nehmen. Die ist getestet und funktioniert. Von der den Wert auslesen lassen und den Wert ohne Modifikation direkt an den Port zuweisen. Wenn du dann an der Messpannung drehst (Poti?) muss sich das LED-Bild verändern. Wenn es das nicht tut hast du ein Hardwareproblem (oder den ADC bereits geschrotter, ohne Not hängt man den ARef nicht an Vcc)
> Die VCC beträgt natürlich 5 Volt. So natürlich ist das nicht. > Und ich möchte gerne, dass 8 LED´s eine Spannung zwischen 1 und 2 Volt > an einem Balken anzeigen! Dein Balken wird sich nicht verändern, solange deine Spannung über 0,5V liegt. Vielleicht ist dir entgangen, daß der ADC 10 Bit Auflösung hat. Deine Werte würden stimmen, wenn er 8 Bit hätte.
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.