Forum: Mikrocontroller und Digitale Elektronik Fehler beim vergleichen zweier Werte


von Siegfried S. (dieleena)


Lesenswert?

Hallo,

MPLap, C18, Pic18F4550,

Habe einen dummen Fehler.
In einer Schleife vergleiche zwei char Werte miteinander. Jedoch schlägt 
dieses öffters fehl.
Als Kontrolle habe ich die beide dummy eingefügt.
Ob das auch bei gebrenntem PIC erfolgt, weis ich noch nicht.

dummy_1 = BusSpiOutput[BusSpi_02].Byte;
dummy_2 = BusSpiInput[BusSpi_03].Byte;
if (BusSpiOutput[BusSpi_02].Byte == BusSpiInput[BusSpi_03].Byte)
{
CheckCount ++;
}
else
{
BusSpiError ++;
}

mache ich aber folgendes, funktioniert es.

dummy_1 = BusSpiOutput[BusSpi_02].Byte;
dummy_2 = BusSpiInput[BusSpi_03].Byte;
if (dummy_1 == dummy_2)
{
CheckCount ++;
}
else
{
BusSpiError ++;
}




/******************************************************/
/******  BusSpiInput  ***************************/
union
{
  struct
  {
    unsigned Bit7:1;               //  Bit  7
    unsigned Bit6:1;               //  Bit  6
    unsigned Bit5:1;               //  Bit  5
    unsigned Bit4:1;               //  Bit  4
    unsigned Bit3:1;               //  Bit  3
    unsigned Bit2:1;               //  Bit  2
    unsigned Bit1:1;               //  Bit  1
    unsigned Bit0:1;               //  Bit  0
  };
   unsigned char Byte;
} GLOBAL BusSpiInput[MaxBusSpiInOut];


/******************************************************/
/******  BusSpiOutput  ***************************/
union
{
  struct
  {
    unsigned Bit7:1;               //  Bit  7
    unsigned Bit6:1;               //  Bit  6
    unsigned Bit5:1;               //  Bit  5
    unsigned Bit4:1;               //  Bit  4
    unsigned Bit3:1;               //  Bit  3
    unsigned Bit2:1;               //  Bit  2
    unsigned Bit1:1;               //  Bit  1
    unsigned Bit0:1;               //  Bit  0
  };
   unsigned char Byte;
} GLOBAL BusSpiOutput[MaxBusSpiInOut];





Gruß Siegfried

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>Jedoch schlägt dieses öffters fehl.

Wenn das schiefgeht:
>if (BusSpiOutput[BusSpi_02].Byte == BusSpiInput[BusSpi_03].Byte)

Und das funktioniert (bzw. weniger of schiefgeht):
>dummy_1 = BusSpiOutput[BusSpi_02].Byte;
>dummy_2 = BusSpiInput[BusSpi_03].Byte;
>if (dummy_1 == dummy_2)


Dann fällt der Verdacht auf ein klassisches Semaphoren-Problem.
Ich würde da einen Interrupt verdächtigen,
der dir deine Werte während der Abfrage ändert...

Wo werden denn    BusSpiOutput[BusSpi_02].Byte
und  BusSpiInput[BusSpi_03].Byte   beschrieben?


Ein amoklaufender Pointer ist natürlich auch immer mal drin... ;-)

von Siegfried S. (dieleena)


Lesenswert?

Hallo,

PS. Bin immer noch am PC. Habe noch nicht das an einem PIC probiert.

BusSpiOutput[BusSpi_02].Byte wird vor der Schleife beschrieben.
BusSpiInput[BusSpi_03].Byte wird normalerweise von SSPBUF beschrieben.
Zur Zeit abe ich aber die komplette SPI Routine deaktiviert.

Habe in beite Routinen je einen eignen BusSpiError_1 & BusSpiError_2 
eingesetzt.
bei
"if (BusSpiOutput[BusSpi_02].Byte == BusSpiInput[BusSpi_03].Byte)"
wird BusSpiError_1 hochgezählt
und bei
"if (dummy_1 == dummy_2)"
bleibt BusSpiError_2 auf NULL.

Das könnte auch sein "Ich würde da einen Interrupt verdächtigen,
der dir deine Werte während der Abfrage ändert...
"
Im Hintergrund ist Timer 1 "T1CONbits.TMR1ON = 1;" aktiv. Alle 100 µs 
wird ein Interrupt ausgelößt.

Habe schon länger das Programm laufen. Das "if (dummy_1 == dummy_2)" 
arbeitet ohne Fehler. Das andere aber nicht. Zur Zeit einen Wert von 
2C33.


Gruß Siegfried

von Matthias L. (Gast)


Lesenswert?

Ich würde vorschlagen, die Strukturen BusSpiOutput und BusSpiInput mal 
als volatile zu deklarieren...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Matthias Lipinsky wrote:
> Ich würde vorschlagen, die Strukturen BusSpiOutput und BusSpiInput mal
> als volatile zu deklarieren...
Wenns das wäre, dann müssten aber beide Varianten fehlschlagen, oder?


@  Siegfried Saueressig
>wird normalerweise von SSPBUF beschrieben...
Nun, ich meinte nicht aus welchem Register, sondern an welcher Stelle im 
Code. Interrupt-Routine, Main-Schleife...

Ich dachte, diese union-Geschichte wäre ausgestorben.
Das
1
:
2
union
3
{
4
  struct
5
  {
6
    unsigned Bit7:1;               //  Bit  7
7
    unsigned Bit6:1;               //  Bit  6
8
    unsigned Bit5:1;               //  Bit  5
9
    unsigned Bit4:1;               //  Bit  4
10
    unsigned Bit3:1;               //  Bit  3
11
    unsigned Bit2:1;               //  Bit  2
12
    unsigned Bit1:1;               //  Bit  1
13
    unsigned Bit0:1;               //  Bit  0
14
  };
15
   unsigned char Byte;
16
} GLOBAL BusSpiOutput[MaxBusSpiInOut];
17
:
18
if (BusSpiOutput[BusSpi_02].Byte == BusSpiInput[BusSpi_03].Byte)"
19
:
sieht nicht nur kompliziert aus, es liest sich auch unwahrscheinlich 
umständlich. Jedesmal "Byte" hinzuschreiben, nur, um ein Byte 
abzusprechen, ist schlicht unleserlich.
Glaub es mir:
Du wirst diese Unions auch wieder wegwerfen (früher oder später)...

Auch das unmäßige #definieren macht zwar Spass, aber jedesmal zu suchen,
ob BusSpi_02 denn jetzt 1,2 oder 3 ist, das macht keinen Spass.
Glaub es mir:
Du wirst diese #defines auch wieder wegwerfen (früher oder später)...

So sieht das viel schnuckeliger aus, und dein Nachfolger wird es dir 
danken:
1
:
2
GLOBAL volatile unsigned char BusSpiOutput[MaxBusSpiInOut];
3
:
4
if (BusSpiOutput[2] == BusSpiInput[3])"
5
:

von Siegfried S. (dieleena)


Lesenswert?

Hallo,
Wie vermutet ist ein Fehler in der Interrupt Rotine aufgetreten.
Habe einige Zeit benötigt, um ihn zu beseitigen.

werde morgen das Programm in dem PIC testen.

Das mit union,  struct und (BusSpiOutput[BusSpi_02].Byte habe ich aus 
einem Beispiel abgeleitet.
Für meine jetzige C Kenntnise ist dieses ausreichend., um mein Programm 
zu verwirklichen.
Ich möchte nicht nur Byte bewegen, abfragen sondern auch jedes Bit. 
Jedes Bit wird einen Namen zugewiesen, somit habe ich eine bessere 
Übersicht.

Danke an alle.
Gruß Siegfried

von Siegfried S. (dieleena)


Lesenswert?

Hallo und guten morgen,

Code in der *.h
union
 {
   struct
   {
     unsigned RunProg:1;            //  Run Programm
     unsigned TransferError:1;    //  Daten Transfer Error
     unsigned RunService:1;    //  Run Service
   };
//   unsigned short Byte;
   unsigned char Byte;
 } PicGlobal ProzessStatus;

Code in der *.c
#define UsbGlobal
#include "UsbPcGlobal.h"
...
#pragma code
...

if (ProzessStatus.RunProg == 1)
{
....
}

@Lothar
"Ich dachte, diese union-Geschichte wäre ausgestorben"
welche möglichkeit ist nach deiner Ansicht besser? Habe dieses gewählt, 
um im Klartext ein Bit mit einem Namen anzusprechen. Finde ich besser 
als immer zu überlegen, welches Bit aus einem Byte ich gerade benötige.

Auch dieses " #definie " nutze ich, um die Variable/Byte richtig 
einzubinden.

Kannst du mir andere Möglichkeiten anbieten?

Für alle Infos bin ich sehr dankbar. Lasse mich gerne besseres belehren.

Gruß Siegfried

von Gabriele (Gast)


Lesenswert?

Hallo  Siegfried,

Mit welcher IDE arbeitest Du?

Gruß

von Siegfried S. (dieleena)


Lesenswert?

hallo,

MPLAP 7.60, C18, Pic18F4550,

gruß Siegfried

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.