Forum: Compiler & IDEs Problem nach dem Einfügen einer If-Abfrage, Prescaler hardwaremäßig einstellen


von Holgie (Gast)


Lesenswert?

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;
             }

von Karl H. (kbuchegg)


Lesenswert?

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!

von David (Gast)


Lesenswert?

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 ...

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.