Hallo zusammen, Ich habe ein Problem beim Abspeichern von Messwerten. Ich habe ein Array definiert und möchte in einer ForNext Schleife die Werte des Analog/Digitalwandlers einlesen und in dem Array speichern if (c[1] == 50) { PORTD |= (1<<PD3); for (j=0;j<250;j++) { c[j] = ADCH; } } Wenn ich die Werte dann auslese sind alle 250 Messwerte gleich (51) obwohl sich die Spannung beim Messen geändert hat. Aufgrund der If-Anweisung fange ich erst ab Wert50 an zu speichern. Funktioniert das Einlesen mittels For Next Schleife nicht? Untenstehend noch das komplette Programm. Danke für Eure HIlfe. Gruß Holger #define PROZESSORTAKT 3680000 #include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> #include "rs232.h" /* ==== INTERRUPT HANDLER: ADC Conversion Complete === */ SIGNAL (ADC_vect) { // unsigned char c; unsigned char c[250]; char temp[5]; int j,i; PORTD |= (1<<PD2); //Pull up von PD2 einschalten DDRD &= ~ (1<<PD2); // PD2 als Eingang DDRD = (1<<PD3)| (1<<PD4); // Pin D3 und D4 als Ausgang // ADC Resultat einlesen ======================= c[1] = ADCH; /* Nur ADCH lesen, weil 8-Bit Modus */ if (c[1] == 50) { PORTD |= (1<<PD3); for (j=0;j<250;j++) { c[j] = ADCH; } } // ADC Resultat auf RS232 ausgeben ============/ if (!(PIND & (1<<PIND2))) { PORTD |= (1<<PD4); for (i=0;i<250;i++) { itoa(c[i], temp, 10); /* In einen String konvertieren ... */ uart_putchar('\n'); uart_putstring(temp); } } } int main(void) { /* RS232 einschalten ...*/ setup_uart(); uart_putline("[ EasyADC -- www.avrbuch.de ]"); // Alle Interrupts erlauben sei(); // ADC, 8-Bit im Free Running Mode mit Interrupt // Referenzspannung: VCC // Takt: Systemtakt / 2 (4 MHz bei 8Mhz Quarz) ADMUX = (1<<REFS0) | (1<<ADLAR); ADCSRA = (1<<ADEN) | (1<<ADFR) | (1<<ADIE); // ADC starten! ADCSRA |= (1<<ADSC); // Endlosschleife while (1) ; return 0; }
Was willst du wirklich machen? Sicher nicht das komplette Programm im SIGNAL (ADC_vect) laufen lassen... Ich könnte mir vorstellen: 250 ADC Werte sollen so schnell wie möglich in einen Puffer eingelesen werden. Wenn der Puffer voll ist, sollen die Werte mit RS232 ausgegeben werden. In der Ausgabezeit werden keine neuen Messwerte ermittelt. Nach der Ausgabe werden die nächsten 250 Werte genommen.
Holgie schrieb: > Hallo zusammen, > Ich habe ein Problem beim Abspeichern von Messwerten. Ich habe ein Array > definiert und möchte in einer ForNext Schleife die Werte des > Analog/Digitalwandlers einlesen und in dem Array speichern > if (c[1] == 50) > { > PORTD |= (1<<PD3); > for (j=0;j<250;j++) > { > c[j] = ADCH; > } > } > Wenn ich die Werte dann auslese sind alle 250 Messwerte gleich (51) Yep. Genau das hast du programmiert. > obwohl sich die Spannung beim Messen geändert hat. Das ist aber dem ADCH egal. Einmal ADC starten -> ein Messwert Willst du den nächsten Messwert, musst du den ADC erbeut sampeln lassen. Insbesondere solltest du beachten, dass du hier mitten in einer ISR steckst. Damit teilt dir der ADC mit, dass er den nächsten Messwert fertig hat. Und in deiner Schleife speicherst du diesen einen Messwert quer über dein Array. Logisch haben dann alle Elemente im Array denselben Wert. Ehe du dich da mit dem ISR verfranst: Wie wäre es, wenn du erst mal ganz einfach die ADC Routine aus dem Tutorial verwendest? Damit bist du ein klein wenig näher an deiner for-Schleifen Denkweise. In einer ISR muss man nämlich anders vorgehen. Das ist ungefähr so, wie wenn du in einem Raum sitzt und ab und an schaut dein Kumpel bei der Tür rein und ruft dir eine Zahl zu (den ADC Messwert) und du musst auf diese eine Zahl reagieren. (Dein Code macht das Äquivalent zu: Du schreibst diese Zahl 250 mal auf, erklärst das zum Ergebnis und wunderst dich, dass alle 250 Ergebnisse gleich sind) In dieser Situation würdest du anders vorgehen. Wenn dein Kumpel dir eine Zahl zuruft und wieder verschwindet, dann schreibst du diese eine Zahl am Ende einer Tabelle dazu. Du zählst mit, wieviele Zahlen dir dein Kumpel bisher genannt hat und wenn es 250 waren, dann erklärst du die Tabelle für vollständig und verlautbarst das Ergebnis.
Schönen guten Abend zusammen, ich wollte mich noch für die tollen Antworten besonders von Hr. Buchegger bedanken. Damit hab ich es nun geschafft und gerade mein großes Erfolgserlebniss gehabt. So macht die Sache echt Spass. Viele Grüße und macht weiter so!! Gruß HOlger Untenstehend noch das auf dem Atmega 8 funktionierende Programm. define PROZESSORTAKT 3680000 #include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> #include "rs232.h" unsigned char c[500]; char temp[5]; int j,i; /* ==== INTERRUPT HANDLER: ADC Conversion Complete === */ // SIGNAL (ADC_vect) // { // } // ADC Resultat einlesen ======================= ISR(ADC_vect) { // user code here c[j] = ADCH; /* Nur ADCH lesen, weil 8-Bit Modus */ if (j<500) { j++; } } int main(void) { PORTD |= (1<<PD2); //Pull up von PD2 einschalten DDRD &= ~ (1<<PD2); // PD2 als Eingang DDRD = (1<<PD3)| (1<<PD4); // Pin D3 und D4 als Ausgang /* RS232 einschalten ...*/ setup_uart(); uart_putline("[ EasyADC -- www.avrbuch.de ]"); // Alle Interrupts erlauben sei(); // ADC, 8-Bit im Free Running Mode mit Interrupt // Referenzspannung: VCC // Takt: Systemtakt / 2 (4 MHz bei 8Mhz Quarz) ADMUX = (1<<REFS0) | (1<<ADLAR); ADCSRA = (1<<ADEN) | (1<<ADFR) | (1<<ADIE) | (1<<ADPS2)| (1<<ADPS1)| (1<<ADPS0); // ADC starten! ADCSRA |= (1<<ADSC); // Endlosschleife while (1) // ADC Resultat auf RS232 ausgeben ============/ if (!(PIND & (1<<PIND2))) { PORTD |= (1<<PD4); for (i=0;i<500;i++) { itoa(c[i], temp, 10); /* In einen String konvertieren ... */ uart_putchar('\n'); uart_putchar ('\r'); uart_putstring(temp); } j = 0; } }
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.