www.mikrocontroller.net

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


Autor: Holgie (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
             }

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
  if( i == 0 )
    j = 5;

  if( k == 8 )
  {
    l = 89;
    j = 9;
  }

  if( l == 8 )
  {
    if( m == 9 )
    {
      while( p == 8 )
        j = 4;
    }
    n = 5;
  }

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 ...
                }
        j = 0;
             }
... (das ist das Ende von deinem main()) geht gar nicht!

Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
// Endlosschleife
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 ...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und BTW

So ...
              ADCSRA |= (1<<ADPS2)| (0<<ADPS1) | (0<<ADPS0); //Prescaler 16

kann man keine Bits auf 0 setzen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.