www.mikrocontroller.net

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


Autor: Michael D. (xaero80c51)
Datum:

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

Autor: Philipp Kälin (philippk) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du eine CodeOptimierung eingeschaltet hast, dann putzt dier der 
Compiler vileicht diese Zeile weg:
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

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> if ( rel_state == 1 ) x = x & ~Relais;

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

Autor: Peter Dannegger (peda)
Datum:

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

> #define Relais 0x01       // Relaisausgang am Port
> ...
> x++;
> ...
> x = x & ~Relais;



Vielleicht wolltest Du ja

x += 2;

schreiben.


Peter

Autor: Michael D. (xaero80c51)
Datum:

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

Autor: Matthias (Gast)
Datum:

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

Autor: Michael D. (xaero80c51)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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
x = x + 1 + 1;  // zählen +2 
und dann
x = x + 1 - 1;  // zählen +0


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


Peter

Autor: Michael D. (xaero80c51)
Datum:

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

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.