Forum: Mikrocontroller und Digitale Elektronik Alarmsteuerung


von Mike E. (mike2342)


Angehängte Dateien:

Lesenswert?

Hallo Leute

Ich habe folgendes Problem ich muss eine Alarmsteuerung programmieren 
und im Avr ausführen doch das Programm hat einen Fehler:

Hier mal die Angabe damit ihr versteht wie es aussehen soll. Angabe vom 
Lehrer.

Es gibt:

a) Eingänge
   Störmeldung:  Sto  //steigende Flanke bedeutet Störung
   Taste:        Ta   //-----------//---- Taste gedrückt

b) Ausgänge:
   Sirene     S=0    // bedeutet Sirene ist an
   Lampe      L=0    // bedeutet Lampe ist an

c) Zustände:
   B     // Betrieb
   A     // Alarm
   W     // Wartung


Hier ist das Programm:

#include <avr/stdio.h>
#include <avr/interupt.h>
#include <util/delay.h>
#define F_CPU 12000000UL // definiere Frequenz

#define B 0 // definiere Pin
#define A 1 // definiere Pin
#define W 2 // definiere Pin
#define STO 2 // definiere Pin
#define Ta 3   // definiere Pin
#define S 0  // definiere Pin
#define L 1   // definiere Pin

volatile uint8_t eingang; // gilt für alle Funktionen
volatile uint8_t zustand; // gilt für alle Funktionen

int main() // Hauptfunktion
{
  uint8_t ausgang[3];


 while(1) // endlosschleife
 {
  switch(zustand)
  {
    case B;
  if(eingang&(1<<STO) == (1 << STO))
  {
  zustand=A;
        }
   break;

  case A;
  if(eingang&(1<<Ta) == (1 << Ta))
  {
  zustand=W;
  }
  break;

  case W;
  if(eingang& (1<<Ta) | (1 << STO) == (1 <<Ta))
  {
  zustand=B;
  }
  break;
  }

  PORTC |= ausgang[zustand];

    ausgang[0] |= (1<<L) | (1 << S);
    ausgang[1] &=~((1<<L) | (1<<S));
    ausgang[2] = ausgang[2] &~ ((1<<S) | (1<<L));

Das Programm funktioniert leider nicht ich suche den Fehler aber finde 
ihn nicht. Ich bin nicht so gut aber es haut einfach nicht hin.
Ich hoffe ihr hab ideen. Die Angabe ist vom Lehrer.

von Feldinhalt (Gast)


Lesenswert?

Argh, hab wohl gerade beim Tippen die "Schnellabschalteschließfunktion" 
von FF gefunden. Also zum Zweiten:

Mike E. schrieb:
> Ich habe folgendes Problem ich muss eine Alarmsteuerung programmieren
Kein Problem.

> und im Avr ausführen doch das Programm hat einen Fehler:
Das Programm ist unvollständig, gehört in [c ]-Tags oder sollte als 
separate Datei angehängt werden (Endung .c).

> volatile uint8_t eingang; // gilt für alle Funktionen
> volatile uint8_t zustand; // gilt für alle Funktionen
> uint8_t ausgang[3];
Wozu dieser ganze Zirkus?

>     ausgang[0] |= (1<<L) | (1 << S);
>     ausgang[1] &=~((1<<L) | (1<<S));
>     ausgang[2] = ausgang[2] &~ ((1<<S) | (1<<L));
Sehr kunstvoll aber irgendwie unübersichtlich und vor allem komplett 
unnötig.

Was du brauchst ist ein klassischer Zustandsautomat, eigentlich mehr 
eine VHDL-Aufgabe. (Lothar wo bist du? ;-))

Wir machen hier nicht deine Hausaufgaben, aber ein paar Tipps gibts 
natürlich.
1
typedef enum {z_standby, z_alarm, ... } zustand_t;
2
3
....
4
5
int main(void)
6
{
7
  zustand_t zustand; //DEUTLICH besser als ein uint8_t, der könnte nämlich ungewünschte Werte annehmen.
8
  
9
  ....
10
11
  while(1)
12
  {
13
    //Erstmal die Übergangsbedingungen zwischen den Zuständen prüfen
14
    switch(zustand)
15
    {
16
      case z_standby:
17
        if(...)
18
          zustand=....;
19
        break;
20
      case z_....
21
      ....
22
    }
23
    //Jetzt die Ausgänge anpassen
24
    switch(zustand)
25
    {
26
       case z_standby:
27
         //Ausgänge passend setzen
28
         break;
29
       ...
30
    }
31
    ...
32
  }
33
}
So ungefähr würde ich das machen. Man kann alles in einen switch packen, 
wird dann u.U. aber unübersichtlich.

von Feldinhalt (Gast)


Lesenswert?

Ach übrigens:
1
#define B 0 // definiere Pin
2
#define A 1 // definiere Pin
3
#define W 2 // definiere Pin
4
#define STO 2 // definiere Pin
5
#define Ta 3   // definiere Pin
6
#define S 0  // definiere Pin
7
#define L 1   // definiere Pin
definiert erstmal keine Pins sondern nur Textbausteine für den 
Präprozessor. Wenn man 100 Zeilen später auf ein einzelndes 'B' stößt 
weiß keiner mehr was gemeint war.

Soll heissen: Man sollte nur kommentieren wenn es wirklich nötig ist, 
auch wenn Lehrer gerne das Gegenteil behaupten. Auch sollte man nicht 
schreiben was man macht ("setze PORTB0 auf '1'" ist vollkommen 
sinnlos, das sieht man) sondern wieso man es macht oder wie genau. 
Im Idealfall erklärt sich der Code von selbst und die einzigen 
Kommentare sind der Name vom Autor usw. Dazu tragen auch klare 
Variablennamen und Präprozessormakros bei.
1
#define SIRENE 0
2
#define TASTER 5
3
4
#define PORT_SIRENE PORTB
5
#define PIN_TASTER PINC
6
7
...
8
9
if(PIN_TASTER & (1<<TASTER))
10
  PORT_SIRENE|=(1<<SIRENE);

Alles klar?

von Karl H. (kbuchegg)


Lesenswert?

Aufpassen
1
  if(eingang&(1<<STO) == (1 << STO))

gemäss den C Regeln wird das gelesen als (Ich ergänze mal Klammern um 
anzuzeigen, wie die Dinge zusammen gehören.
1
  if( eingang & ( (1<<STO) == (1 << STO) ))


Manchmal, und ganz speziell in C, ist weniger einfach mehr
1
   if( eingang & (1<<STO) )
2
   {
3
      Code
4
   }

Der Code wird ausgeführt, wenn der Ausdruck
1
   eingang & (1<<STO)
nicht 0 ergibt. Die einzige Möglichkeit, dass dieser Ausdruck nicht 0 
sein kann, besteht darin, dass da das Bit STO gesetzt ist. Du musst hier 
nicht extra noch fordern, dass das Ergebnis der & Operation wieder 
1<<STO sein muss. Es kann gar nichts anderes sein (oder 0). Aber wenn du 
das schon machst, dann musst du es richtig machen
1
  if( ( eingang & (1<<STO) ) == (1 << STO) )

aber eigentlich ist das unnötig und daher: weniger ist mehr.


Das hier
1
  if(eingang& (1<<Ta) | (1 << STO) == (1 <<Ta))
geht so gar nicht.
Der Zustand wird verlassen, wenn
  * Taster auf 1 ist   UND
  * Störung auf 0

Solange du mit Operator-Precendence noch auf Kriegsfuss stehst, schreib 
das dann auch genau so hin und künstle nicht rum.
1
  if(  ( eingang & (1 << Ta) ) &&    // Taster muss gesetzt sein
2
      !( eingang & (1 << STO) ) )      // Störung darf nicht gesetzt sein
Das Schema ist immer gleich. Die Pinabfrage lautet

     port & ( 1 << pin )

Sicherheitshalber kann man das in eine Klammer einschliessen, damit man 
bei Verknüpfungen keine Überraschungen erlebt. Und wenn man fordert, 
dass der Pin nicht gesetzt sein darf, dann kommt eben ein NICHT in Form 
eines ! vor den Ausdruck.


Und natürlich all das was Feldinhalt schon angesprochen hat.

von Feldinhalt (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Das Schema ist immer gleich. Die Pinabfrage lautet
>
>      port & ( 1 << pin )
Sorry für die Erbsenzählerei Karl Heinz, aber sonst kommt gleich das 
nächste Problem: Man spricht zwar von "Ports", um den logischen Wert 
abzufragen der am Eingang anliegt muss man beim AVR aber das 
entsprechende PIN-Register auslesen.

Also NICHT PORTB & ... sondern PINB & ...

von Karl H. (kbuchegg)


Lesenswert?

Feldinhalt schrieb:

> Sorry für die Erbsenzählerei

Wo du rechts hast, hast du recht. Das ist doch keine Erbsenzählerei :-)

von Feldinhalt (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wo du rechts hast, hast du recht. Das ist doch keine Erbsenzählerei :-)
        ^^^^^^
Und wenn ich links habe? :-)


Sorry, just kidding... Ich hab Kopfweh und geh gleich ins Bett, gute 
Nacht.

von Feldinhalt (Gast)


Lesenswert?

Es war soooo klar. Nachdem es keine fertige Lösung inkl. Doku gibt 
verschwindet der TO einfach ohne sich für die Mühe die Karl Heinz und 
ich uns gemacht haben zu bedanken.

Ich HASSE solche Leute!

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.