Forum: Compiler & IDEs komme einfach nicht weiter.


von Axel L. (lemmi4711)


Lesenswert?

Hallo, Leute.
Ih beschäftige mich zwar schon länger mit 'C', soweit es mir meine 
Arbeit erlaubt....
Aber ich komme hier einfach nicht weiter, liegt wahrscheinlich an einer 
Klenigkeit. Mit Atmel-µC's ist dies mein erstes Projekt, bisher waren 
dies PIC's.

Könnt Ihr mir helfen?

Das Problem ist, daß das Programm nach dem zweiten Aufruf der Schleife 
zur Anzeigenwiederholung nicht mehr weiterarbeitet. In der Simulation in 
AVR-Studio sieht es so aus, als würde das Progamm in einer 
Endlosschleife stecken...

Der Abschnitt Anzeige (a) soll die drei Stellen auf einer 7-Segment 
Anzeige per globale Variable definieren (z1, z2, z3). Danach sollen 
diese drei Variablen in den Abschnitten 'Zahl1 (z1)', u.s.w. 
nacheinander auf den Ports ausgegeben werden.

Ach ja, die Binärangabe der Port nutze ich nur der besseren 
Übersichtlichkeit wegen. Hex ist mir zu kryptisch!

Ich nutze AVR-Studio in der aktuellen Version.


//*******************************************
//                                          *
// Programm zum Test der 3x7Seg. Anzeige    *
// zur Definiton einer Temperaturanzeige    *
//                                          *
//   -         PD1                          *
//  | |    PD0     PD3                      *
//   -  ->     PD2                          *
//  | |    PB0     PD5                      *
//   -         PD7                          *
//                                          *
//                                          *
//  Gemeinsame Kathode 1: PB1 (Zahl1)       *
//  Gemeinsame Kathode 2: PD6 (Zahl2)       *
//  Gemeinsame Kathode 3: PD4 (Zahl3)       *
//                                          *
//*******************************************


#include <avr/io.h>

uint16_t i;
static int z1;
static int z2;
static int z3;
static uint16_t a;

void Anzeige (uint16_t a);
void Zahl1 (int z1);
void Zahl2 (int z2);
void Zahl3 (int z3);

int main (void)
{
 TCCR0 = 0b00000101;           // Timer0 -> CPU/1024
 DDRB  = 0b111111;             // Port B als Ausgang
 DDRD  = 0b11111111;           // Port D als Ausgang
 PORTB = 0b000010;             // Port B -> alles ausschalten
 PORTD = 0b01010000;           // Port D -> alles ausschalten

start:
 for (a=1024; a>0; a--)
 {
  Anzeige (a);                 // Unterprogramm zur Definition der
                               // Variablen z1, z2, z3
  for (i=2000; i>0; i--)       // Anzeige in der Schleife wiederh.
  {
   Zahl1 (z1);                 // Unterprogramm zur Ausgabe an den Ports
   Zahl2 (z2);                 // Unterprogramm zur Ausgabe an den Ports
   Zahl3 (z3);                 // Unterprogramm zur Ausgabe an den Ports
  }
 }
 goto start;
 return (0);
}

void Anzeige (uint16_t a)
{
  if (a > 1021)
  {
   z1=10;                      // Anzeige: -
   z2= 4;                      // Anzeige: 4
   z3= 0;                      // Anzeige: 0
   return;
  }
  if (a > 1016 || a <= 1020)
  {
   z1=10;                      // Anzeige: -
   z2= 3;                      // Anzeige: 3
   z3= 9;                      // Anzeige: 9
   return;
  }
  if (a > 1010 || a <= 1015)
  {
   z1=10;                      // Anzeige: -
   z2= 3;                      // Anzeige: 3
   z3= 8;                      // Anzeige: 8
   return;
  }
  //u.s.w. bis 120°C
}

void Zahl1 (int z1)
{
 switch (z1)
 {
  case 0:
  PORTB = 0b000001;        // 0 auf GK1
  PORTD = 0b11111011;
  break;

  case 1:
  PORTB = 0b000000;        // 1 auf GK1
  PORTD = 0b01111000;
  break;

  case 2:
  PORTB = 0b000001;        // 2 auf GK1
  PORTD = 0b11011110;
  break;

  //u.s.w.
 }
}

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Von wo nach wo ist denn die "Endlosschleife"? Du weisst schon, dass die 
gleichen drei Zahlen 2000 mal ausgegeben werden, oder?

von Axel L. (lemmi4711)


Lesenswert?

Daß die Anzeige 2000 mal ausgegeben werden soll, ist schon ok...


 for (a=1024; a>0; a--)
 {
  Anzeige (a);                 // Unterprogramm zur Definition der
                               // Variablen z1, z2, z3
  for (i=2000; i>0; i--)       // Anzeige in der Schleife wiederh.
  {
   Zahl1 (z1);                 // Unterprogramm zur Ausgabe an den Ports
   Zahl2 (z2);                 // Unterprogramm zur Ausgabe an den Ports
   Zahl3 (z3);                 // Unterprogramm zur Ausgabe an den Ports
  }
 }
 goto start;
 return (0);
}

void Anzeige (uint16_t a)
{
  if (a > 1021)                  <- Diese Schleife arbeitet der µC
                                     korrekt ab... (Anzeige: -40)
  {
   z1=10;                      // Anzeige: -
   z2= 4;                      // Anzeige: 4
   z3= 0;                      // Anzeige: 0
   return;
  }
  if (a > 1016 || a <= 1020)     <- Nach kurzer Zeit zeigt der µC die 
-39
                                    an, dann bleibt's so...
  {
   z1=10;                      // Anzeige: -
   z2= 3;                      // Anzeige: 3
   z3= 9;                      // Anzeige: 9
   return;
  }
  if (a > 1010 || a <= 1015)    <- hierher kommt der µC gar nicht!
  {
   z1=10;                      // Anzeige: -
   z2= 3;                      // Anzeige: 3
   z3= 8;                      // Anzeige: 8
   return;
  }

von Karl H. (kbuchegg)


Lesenswert?

Axel Lemke wrote:

>   if (a > 1016 || a <= 1020)     <- Nach kurzer Zeit zeigt der µC die
> -39
>                                     an, dann bleibt's so...

Na überleg mal.
Nimm die Zahl 1000 für a
  1000 ist zwar nicht größer als 1016   ABER
  1000 ist kleiner oder gleich 1020

Was ist mit 500 für a?
  auch 500 ist nicht größer als 1016   ABER
  500 ist auf jeden Fall kleiner oder gleich 1020

und da du die beiden Vergleiche miteinander Oder
verknüfst, genügt es wenn einer der beiden Vergleiche
wahr ist.
d.h. diese Abfrage ist für alle Zahlen kleiner 1021
IMMER wahr.


PS: Du hast dir da ja mächtig viel Arbeit gemacht.
Du weist schon, dass ein µC auch wunderbar rechnen
kann? Du weist schon, die Sache mit Plus und Minus,
Multiplizieren und Dividieren.

von Axel L. (lemmi4711)


Lesenswert?

Danke, nu ist es mir klar...


Habe die ODER Verknüpfung gegen UND ausgetauscht - und nun 
funktionierts...

Daß ich mir so viel Schreibarbeit gemacht habe, hat damit zu tun, daß 
der von mir vorgesehene Temperatursensor (lag in der Schublade rum...) 
leider nicht linear ist... Dann klappt das mit dem Rechnen nicht so 
einfach.

Nun kann ich weitermachen...

Nochmals, DANKE!

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.