Hallo zusammen, ich benötige nochmals Eure Hilfe. Ich möchte gerne das Programm zum AnalogDigitalwandler dahingehend abändern dass ich den Prescaler hardwaremäßig einstellen kann. Dafür habe ich direkt nach dem while(1) die Abfrage If, else if, else if eingefügt. Danach funktioniert plötzlich die nächste If-Abfrage "ADC-Result auf RS232 ausgeben" nicht mehr (LED an PB2 bleibt dunkel). Wenn ich die If-Abfrage "Prescaler einstellen" herausnehme funktioniert es wieder.(LED an PB2 leuchtet) Was kann ich falsch gemacht haben. Ich komme einfach nicht darauf. Gruß Holger #define PROZESSORTAKT 3680000 #include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> #include "rs232.h" // Variablendeklaration unsigned char c[500]; //Messwertspeicher char temp[5]; int j,i,x,y,z; // j,i für Schleifen, x,y,z für Prescalerauswahl ISR(ADC_vect) { c[j] = ADCH; /* Nur ADCH lesen, weil 8-Bit Modus */ if (j<500) // 500 Messwerte einlesen { j++; } } int main(void) { PORTD |= (1<<PD2)| (1<<PD3)| (1<<PD4)| (1<<PD5); //Pull up einschalten DDRD &= ~ (1<<PD2)| (1<<PD3)|(1<<PD4)| (1<<PD5); // PDX als Eingang DDRB = (1<<PB0) | (1<<PB1)| (1<<PB2); // PBX als Ausgang /* RS232 einschalten ...*/ setup_uart(); uart_putline("[ RS232 eingeschaltet]"); // Alle Interrupts erlauben sei(); // ADC, 8-Bit im Free Running Mode mit Interrupt // Referenzspannung: VCC ADMUX = (1<<REFS0) | (1<<ADLAR); // Auswahl Referenzspannung, Ergebniss left adjust ADCSRA = (1<<ADEN) | (1<<ADFR) | (1<<ADIE); // ADC Enable, Free running mode, Interrupt enabled // Endlosschleife while (1) // Prescaler hardwaremäßig einstellen if ((!(PIND & (1<<PIND3))) && (x==0)) { ADCSRA |= (1<<ADPS2)| (0<<ADPS1) | (0<<ADPS0); // Prescaler 16 // ADC starten! ADCSRA |= (1<<ADSC); PORTB |= (1<<PB0); x=1; y=0; z=0; } else if ((!(PIND & (1<<PIND4))) && (y==0)) // Prescaler 4 { ADCSRA |= (0<<ADPS2)| (1<<ADPS1) | (0<<ADPS0); // ADC starten! ADCSRA |= (1<<ADSC); PORTB |= (1<<PB1); x=0; y=1; z=0; } else if ((!(PIND & (1<<PIND5))) && (z==0)) // Prescaler 2 { ADCSRA |= (0<<ADPS2)| (0<<ADPS1) | (1<<ADPS0); // ADC starten! ADCSRA |= (1<<ADSC); x=0; y=0; z=1; } // ADC Resultat auf RS232 ausgeben ============/ if (!(PIND & (1<<PIND2))) { PORTB |= (1<<PB2); 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; }
Holgie schrieb:
> Was kann ich falsch gemacht haben. Ich komme einfach nicht darauf.
Du hast dich mit deinem bescheuerten, nicht vorhandenen Einrückstil
selbst ausgetrickst.
geh dein Programm durch.
Du fängst am linken Rand an.
Immer wenn du auf eine { stösst, werden die nachfolgenden Zeilen um 2
Zeichen eingerückt. Und nur dann!
Immer wenn du auf eine } stößt, werden die nachfolgenden Zeilen,
inklusive der } Zeile wieder um 2 Leerzeichen wieder nach links
ausgerückt. Und nur dann!
Jeweils die öffnende { und die schliessende } müssen in derselben Spalte
untereinander stehen. Wenn du den Cursor auf die schliessende } stellst
und mit Cursor Up nach oben gehst, muss es eine Zeile geben, in der die
zugehörige öffnende { steht und die genau in dieser Spalte beginnt.
Ganz zum Schluss, muss die letzte }, die die Funktion beendet, wieder am
linken Rand angekommen sein. Tut sie das nicht, stimmt irgendwo etwas
nicht. Unbedingt: Nicht auf sich beruhen lassen, sondern den
Einrückfehler suchen. Oft genug stellt sich nämlich dann heraus, dass
mit den { } was nicht simmt, bzw. ein notwendiges { }-Parr vergessen
wurde.
Bei Anweisungen, die einen abhängigen Teil haben können, gibt es 2
Möglichkeiten:
Steht dahinter nur eine einzige Anweisung, so wird diese und nur diese
um 2 Zeichen eingerückt. Die darauffaolgende Anweisung kommt wieder um 2
Zeichen nach links.
Ist der abhängige Teil selbst ein { } Block, so kommt die { Klammer
unter den Beginn der bestimmenden Anweisung, der Blockinhalt wird
eingerückt und die } kommt wieder um 2 Zeichen raus. Allerdings gibt es
da mehrere verschiedene Stile. Welchen du nimmst, ist im Grunde egal. Du
musst nur konsequent sein und es soll einfach sein, die Konsistenz der {
} zu überblicken und zu kontrollieren. Am einfachsten ist das, wenn man
die { und } nicht optisch versteckt, sondern sie hervorstechen lässt.
Der Einrückstil mit den abgesetzten Blockinhalten gewährleistet das:
1 | if( i == 0 ) |
2 | j = 5; |
3 | |
4 | if( k == 8 ) |
5 | {
|
6 | l = 89; |
7 | j = 9; |
8 | }
|
9 | |
10 | if( l == 8 ) |
11 | {
|
12 | if( m == 9 ) |
13 | {
|
14 | while( p == 8 ) |
15 | j = 4; |
16 | }
|
17 | n = 5; |
18 | }
|
Anstelle der ersten Variante, kann man auch generell immer alles in { } einschliessen, selbst wenn es sich nur um 1 abhängige Anweisung handelt. Dann läuft man nicht Gefahr, dass man bei einer Erweiterung die notwendigen { } vergisst. (und genau das ist dir zum Verhängnis geworden). Ist die abhängige Anweisung von der Art 'wenns mal etwas länger wird' aber eigentlich selbst nur eine einzige Anweisung, dann sollte man die Klammern aus Übersichtszwecken auf jeden Fall setzen. Ein optisch sauberes, sauber eingerücktes Programm ist keineswegs Selbstzweck! Es hilft Fehler zu vermeiden, bzw. Fehler zu suchen, wie du gerade am eigenen Leib erfahren hast. Sowas ...
1 | }
|
2 | j = 0; |
3 | }
|
... (das ist das Ende von deinem main()) geht gar nicht!
1 | // Endlosschleife
|
2 | while (1) |
Da gehört eine Klammer hin, sonst wird nur der Prescaler-Kram unendlich oft ausgeführt, der Rest danach. Und mit "nach unendlich langer Zeit" ist das immer so'n Problem ...
Und BTW So ...
1 | ADCSRA |= (1<<ADPS2)| (0<<ADPS1) | (0<<ADPS0); //Prescaler 16 |
kann man keine Bits auf 0 setzen.
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.