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
>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... ;-)
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
Ich würde vorschlagen, die Strukturen BusSpiOutput und BusSpiInput mal als volatile zu deklarieren...
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 | :
|
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.