Hallo als erstes will ich sagen das ich ein Neuling auf diesem Gebiet bin und das das ADC Auslesen/Ausgeben mein erstes "größeres" Projekt ist. Ich verwende ein Net-IO Board mit einem Atmega32 (16Mhz). Ich habe es am Anfang nmit Beispielen von dieser Seite hier probiert und es hat alles einwandfrei geklappt. Dann habe ich es ein wenig erweitert und "verbessert" durch Interrupts, Timer und auslesen aller Kanäle. Und da ist dann auch schon das Problem. Die Uart-Ausgabe funktioniert da ich diese vorher ohne die Interrupts schon getestet habe. Die Ausgabe von Hallo vor der Hauptschleife zeigt mir auch das die Ausgabe soweit funktioniert, aber nach dem Hallo kommt nichts mehr. Also nun weiß ich nicht obs am Timer liegt oder and den Interrupts oder ob ein Zähler nicht funktioniert. Kann jmd vielleicht das Problem sehn? Gruß
also ich hab noch ein paar kleine änderungen reingemacht zb ADMUX=.. über die main schleife und in den ADC interrupt unter k-- dann den ADC interrupt enable in die ADC init als ADCSRA |= (1<<ADIE)
Timerinterrupt geändert in TIMSK |= (1<<TOIE0); interrupts sind angesprungen .. ausgabe war aber kurz und wirrwar
ich werde noch einige optimierungen durchführen und mich nochma melden wenns dann immernoch nicht funktioniert ;) hab selber grad noch einige fehler gefunden
> Also nun weiß ich nicht obs am Timer liegt oder and den > Interrupts oder ob ein Zähler nicht funktioniert. Klarer Fall von: zu viele Änderungen auf einmal gemacht ohne zwischendurch ausgiebig zu testen.
Karl ich denke da hast du recht ich hat versucht soviele zusätze wiemöglich mit einzubauen ich habe die ganze sache nocheinmal überdacht, überarbeitet und verkürzt Interrupts funktionieren Ausgabe funktioniert(es wird das richtige ausgegeben) Timer is denke ich jetzt das Problem ich habe versucht den Timer so zu takten das ich jede sec eine conversion des ADC habe und diese ausgegeben wird aber egal was ich einstelle, er schießt mir die werte in super geschwindigkeit entgegen habe ich vielleicht etwas flasch gerechnet oder einen falschen PIN gesetzt? am anfang wollte ich es mit millisekunden machen also im Timerinterrupt nach oben zählen und bei 1000 ADC_ON machen (OCR0 = 250-1) da aber die geschwindigkeit sich nciht geändert hat habe ich es direkt mit sekunden veruscht aber leider auch das keine veränderung
1 | OCR0 = 250000-1; |
Und wie soll der Wert in 8 Bit passen?
1 | char mystring[4]; |
2 | ...
|
3 | mystring[4] = '\0'; |
Du schreibst hier hinter das Array.
hatte das mit der 250000 schon geändert und wieder die milli gemacht .. hmm ok dann mach ich das Array 5 lang
Für meinen Geschmack immer noch zu kompliziert > Ich habe es am Anfang nmit Beispielen von dieser Seite hier probiert > und es hat alles einwandfrei geklappt. Dann fang nochmal auf dieser Ebene an. Bring diese Beispiele noch einmal zum Laufen (vergewissere dich auch dass sie das sicher tun) und dann fängst du an sie zu modifizieren. Aber immer nur eine kleine Änderung nach der anderen. Nach jeder Änderung vergewisserst du dich, dass das was du geändert hast auch wirklich noch funktioniert! > ADMUX = 0; Wie ist der AREF Pin auf dem Net-IO beschaltet? Du wählst hier "externe Referenzspannung" aus. Ist das wirklich das, was du willst?
AREF Jumper ist auf intern .. ich nehm also die 5V als Referenz da das Ziel ist 3,3V zu messen also ok der reihe nach: uart initialisieren ausgabe initialisieren Test der Ausagbe mit printf ... funktioniert ADC initialisieren .. ADMUX auf AREF 5V .. Frequenzvorteiler auf 128 .. Start ADC .. ADC Interrupt erlauben .. eine Single Conversion .. Freerunning Mode .. An ADC2 auslesen (Hardware Check .. ja liegt an) Timer initialisieren .. Prescaler /64 .. Timer0 Start .. CTC starten .. OCR0 Register initialisieren (nachrechnen .. 16MHz .. 16000000/64 = 250000 .. 1s=250000 Takte .. 1ms=250 Takte .. Interrupt nach 250 Takten .. stimmt) .. Interrupt starten .. Timer in anderen Programm getestet .. alles funktioniert Globale Interrupts erlauben Interrupt Routinen prüfen .. ISR(TIMER0_COMP_vect) .. stimmt .. milli hochzählen bis 1000 .. milli=uint=65.535 .. stimmt .. if abfrage .. milli zuruecksetzen .. if abfrage zur sicherheit .. Aufruf Makro (dasgleiche wie bei ADC_Init) .. wenn ADC aus dann Ausgabe starten .. ADCW-Wert wird übergeben als uint16_t adcval .. umrechnen .. in String schreiben .. String ausgeben .. Freerunning bis ADC Interrupt ausgelöst wird .. ISR(ADC_vect) .. sollte stimmen .. Makro aufruf (ADC stoppt) .. hm sollte auch stimmen MAIN loop .. nichts so hat ich dann hier und da was verändert und es funktioniert ;) hm ich weiß das die Ausgabe nicht ganz optimal da vielleicht ein wenig viel für einen interrupt .. aber davon mal abgesehen finde ich keinen Fehler ich meine es ist ja nicht wirklich kompliziert aber nun möchte ich die 4 ADC Pins am Net-IO Board auslesen (4-7 am Atmega 32) .. darum auch das k bei der Kanalausgabe und ich möchte 5 mal den Wert eines Kanals lesen(Mittelwert) und dann erst ausgeben(wegen genauigkeit) .. hier steh ich total aufm Schlauch .. keine Ahnung wo ich das Einbauen soll bei dem Kanal wollte ich es so machen das ich nach der Ausgabe das k hochzähle .. desweiteren muss k1-k4 mit einem Befehl zum ADMUX verbunden werden .. zb if k=1 dann a=5 und dann das a in den ADMUX schmeißen .. aber wo und wie ich das genau mache weiß ich nicht .. hat jmd eine Idee oder einen genialen besseren Vorschlag? ;) Gruss
1 | if(ADCSRA==0) |
2 | {
|
3 | adc_ausgabe(ADCW); |
4 | k++; |
5 | if(k==8) |
6 | {
|
7 | k=4; |
8 | }
|
9 | ADMUX = (ADMUX & ~(0x1f))|(k & 0x1F); |
10 | ADC_ON; |
11 | }
|
ich hab das mit dem Kanal jetzt so probiert .. aber das is immermehr in dem Interrupt .. soll ich da eine flag setzen und das ganze im main loop machen lassen oder is das noch ok für die performance? .. bei der Kanal ausgabe habe ich einfach den Wert Minus 3 damit der richtige Kanal dasteht
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.