Forum: Mikrocontroller und Digitale Elektronik Probleme mit Minniprogramm 80c51 C-Code


von Michael D. (Gast)


Lesenswert?

Hallo zusammen!

Ich bin gerade ein wenig beim Experimentieren und hier auf ein problem 
gestoßen.

Ich will ein Relais (P2.0) über zwei Taster ein und ausschalten. Dies 
fünktioniert bereits so wie es soll.

Des weiteren will ich andere willkürliche Zustände (x auf P2.1 - P2.7) 
mitsimulieren.

Mein Problem: ist das Relais aktiviert, so wird x nicht mehr 
kontinuierlich ausgegeben. Ist es auschgeschalten schon.

Der Controller ist ein 89C51RD2.

Vielleicht hat ja wer einen Tipp für mich,
Besten Dank, Mike

Code:

#include "reg51f.h"

#define Relais 0x01       // Relaisausgang am Port

sbit Relais_ein = P1^0;       // Ein Taster
sbit Relais_aus = P1^1;       // Aus Taster

unsigned char rel_state = 0; // Relais Status: 0 = aus, 1 = ein

unsigned char x;
unsigned char y;

void main (void)
{
  while (1)
  {
     // Taster abfragen:
           if ( !Relais_ein ) rel_state = 1;  // Relais ein. Nur Status!
     if ( !Relais_aus ) rel_state = 0;  // Relais aus. Nur Status!

     // Simulator für andere Pinfunktionen (x)
           x++;

           if ( rel_state == 1 ) x = x & ~Relais;
           // Relais ein: Alle unverändert nur Bit 0 Low (0)
     else x = x | Relais;
           // Relais aus: Alle unverändert nur Bit 0 High (1)

     P2 = x;

           // Warteschleife
           for ( y = 0; y < 255; y++)  x=x;
  }
}

von Philipp K. (philippk) Benutzerseite


Lesenswert?

Wenn du eine CodeOptimierung eingeschaltet hast, dann putzt dier der 
Compiler vileicht diese Zeile weg:
1
for ( y = 0; y < 255; y++)  x=x;

Weil x=x; ergibt für ihn keinen Sinn (verändert sich ja nicht), also weg 
damit. Versuch dein Delay anders zu lösen. z.B. mit nem NOP

von Matthias (Gast)


Lesenswert?

> if ( rel_state == 1 ) x = x & ~Relais;

versuch es mal so:
1
if ( rel_state == 1 ) x = x & (~Relais);
2
//oder
3
if ( rel_state == 1 ) x &= (~Relais);

von Peter D. (peda)


Lesenswert?

Michael D. wrote:
> Mein Problem: ist das Relais aktiviert, so wird x nicht mehr
> kontinuierlich ausgegeben. Ist es auschgeschalten schon.

Dann ist ja alles in Butter.
Das Programm verhält sich völlig korrekt, genauso, wie Du es 
hingeschrieben hast.

Du hast einen logischen Fehler drin.
D.h. das was Du hingeschrieben hast, ist wohl nicht das, was Du 
erreichen willst:
1
> #define Relais 0x01       // Relaisausgang am Port
2
> ...
3
> x++;
4
> ...
5
> x = x & ~Relais;


Vielleicht wolltest Du ja
1
x += 2;
schreiben.


Peter

von Michael D. (Gast)


Lesenswert?

Hallo Phillip, Hallo Matthias, Hallo Peter!

Besten Dank für Eure Antworten!

An der Warteschleife liegt es nicht, diese wird korrekt ausgeführt.

Das x hat den Sinn dass sich am Port kontinuierlich etwas ändert und 
somit andere Relaise und LED Anzeigen simuliert werden, und nur das eine 
Relais, welches ich in diesem Programm ein und aus schalte korrekt, 
angesteuert wird, was auch funktioniert.

Ist das Relais aus zählen Bit 1 - Bit7 koninuierlich weiter.

Problem:
Ist das Relais ein, dann bleiben Bit 1 - Bit 7 in ihmem Zustand.
Ziel:
Bit 1 - Bit 7 sollen sich so verhalten wie im Rel. aus Modus.

Wenn ich >> x = x & ~Relais; << zB. mit x = 0xff ersetze, wird auch dass 
richtig ausgegeben..

An der Syntax >> x = x & ~Relais; << Finde ich leider keinen Fehler 
obwohl es ganz offensichtlich an diesem liegt.

Ich werde morgen mal den Tipp von Matthias ausprobieren.

Besten Dank nochmal,
Mike

von Matthias (Gast)


Lesenswert?

irgendwann wird mal x=0
x++; // x=0000 0001
x = x & ~Relais; // 0000 0001 & 1111 1110 = 0000 0000

Damit machst Du X immer zu 0, wenn X zuvor 1 war, da hängt es dann und 
es wird immer 0 am Port ausgegeben. Das meinte wohl PD.

von Michael D. (Gast)


Lesenswert?

Hallo!

Das klingt einleuchtend und das habe ich auch nicht bedacht!
Leider bleibt x bei willkürlichem x (auch != 0 stehen). Die von Dir 
vorgeschlagenen Lösungen brachten leider auch nix. Trotzdem besten Dank.

Ich werd das ganze mal über eine Zwischenvariable Probieen..

Mfg, Mike

von Peter D. (peda)


Lesenswert?

Michael D. wrote:
> Leider bleibt x bei willkürlichem x (auch != 0 stehen).

Wie bereits gesagt, das ist korrekt.
Du kannst nicht das Bit zählen, welches Du danach wieder auf 0 setzt.
Damit gibt es nie einen Übertrag auf das nächste Bit.
Dafür gibt es immer einen Übertrag, wenn Du es auf 1 setzt.
Du machst also einmal
1
x = x + 1 + 1;  // zählen +2
und dann
1
x = x + 1 - 1;  // zählen +0


Wie oben schon geschrieben, Du mußt das hier:
1
x++;     // falsch !!!
so ändern:
1
x += 2;  // richtig


Peter

von Michael D. (Gast)


Lesenswert?

Hallo Peter!

So.. jetzt hat es geklingelt bei mir!

Und jetzt verstehe ich auch das +2! Da das Bit 0  manuell festgelegt 
wird muss ich beim Zählen beim Bit 1 anfangen und dieses hat halt die 
Wertigkeit 2.

Sorry für meine "Uneinsichtigkeit".
Threoretisches Wissen währ ja da, nur wird in paktischen Umsetzungen 
nicht immer darauf zugegriffen..

Danke nochmals, Mike

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.