mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Fehler bei Bit manipulation


Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Habe einen neuen Beitrag geschrieben, da das Thema von gestern nichts 
mit zu tun hat.
Habe ein Problem bei der "Bit Manipulation".

Habe ein kurzer Hand einen Test-Sourcecode geschrieben.

Das Problem bleibt bestehen.
Wenn ich Bit 7 setze/lösche, wird die nachfolgende Adresse auf 0xFF/0x00 
gesetzt.


#if defined(__18F8722)
  #include <p18f8722.h>
#else
  #error  "PIC-TYP ist nicht richtig!"
#endif

//---------------------------------------------------------------------
// Set configuration bits
//
//  - set HS oscillator
//  - disable watchdog timer
//  - disable low voltage programming
//---------------------------------------------------------------------
//
#pragma config OSC = HS
#pragma config BOREN = OFF
#pragma config WDT = OFF      //Watchdog Timer
#pragma config LVP = OFF      //Low Voltage ICSP
#pragma config PWRT = OFF
//#pragma config DEBUG = ON

#define SET_BIT(var,bit)  ( (var) |=   (1<<(bit)) )
#define DEL_BIT(var,bit)  ( (var) &= ~ (1<<(bit)) )
#define TEST_BIT(var,bit) ( (var) &    (1<<(bit)) )

#define MaxFifoBuffer 16

ram unsigned int     *FifoAdresse[MaxFifoBuffer];
ram unsigned char   FifoPortBitNr[MaxFifoBuffer];
ram unsigned char   BusSpiOutput[MaxFifoBuffer];

ram unsigned int   *FifoZeiger;

ram unsigned char  FifoPortBit;

#pragma code

void main(void)
{
//
unsigned int i;
unsigned int y = 0;


  for (i=0; i<MaxFifoBuffer; i++)
    {
      BusSpiOutput[i] = 0;
      FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i];
      FifoAdresse[i]= FifoZeiger;
    }
  for (i=0; i<8; i++)
    {
      FifoPortBitNr[i] = i;
    }

  while(1)
  {
    for (i=0; i<MaxFifoBuffer; i++)
      {
      FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i];
        for (y=0; y<8; y++)
          {
          FifoPortBit = FifoPortBitNr[y];
          SET_BIT(*FifoZeiger,FifoPortBit);
          }
        for (y=0; y<8; y++)
          {
          FifoPortBit = FifoPortBitNr[y];
          DEL_BIT(*FifoZeiger,FifoPortBit);
          }
      }
  }
//
//  ---->>>>  .....
}
/*  **********  END main()  */

Gruß Siegfried

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i];
Dein BusSpiOutput ist ein char, dein FifoZeiger ein integer.
Deklarier den FifoZeiger mal als char*.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siegfried Saueressig schrieb:

> Das Problem bleibt bestehen.
> Wenn ich Bit 7 setze/lösche, wird die nachfolgende Adresse auf 0xFF/0x00
> gesetzt.

Ist korrekt bei diesem Code:

> #define SET_BIT(var,bit)  ( (var) |=   (1<<(bit)) )
> #define DEL_BIT(var,bit)  ( (var) &= ~ (1<<(bit)) )
> ...
> ram unsigned char   BusSpiOutput[MaxFifoBuffer];
> ram unsigned int   *FifoZeiger;
> ...
>       FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i]; #1 #2 #3
> ...
>           SET_BIT(*FifoZeiger,FifoPortBit); #4
> ...
>           DEL_BIT(*FifoZeiger,FifoPortBit); #4

Du nimmst die Adresse auf ein Element eines unsigned char Felds (#1)
Änderst die Adresse in einen unbestimmten Universalzeiger (#2)
Änderst den unbestimmten Zeiger in einen Zeiger auf unsigned int (#3)
Dann manipulierst du Bits an der Stelle auf den der neue Zeiger 
gerichtet ist (#4)
Bei Schritt #4 müssen 16-Bits beeinflusst werden!

ADD:
Korrektur s. Lothar
Tipp: Zunächst keine casts einsetzen und Warnungen des Compilers 
beachten

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

@Stefan B.

jetzt stehe ich auf dem Schlauch.

keine Warnungen vom Compilers


Gruß Siegfried

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du die ganzen casts entfernt?

Das glaub ich dir nicht, dass es dann keine Warnings gibt. Du schmeisst 
unsigned char und unsigned int durcheinander, als ob es kein Morgen 
gibt!

Du solltest dir eines merken:
Wenn du Adressen oder Pointer zurechtcasten musst, dann ist in 95% aller 
Fälle etwas oberfaul.
FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i];
warum musst du hier auf Teufel komm raus casten?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siegfried Saueressig schrieb:

> jetzt stehe ich auf dem Schlauch.
> keine Warnungen vom Compilers

Kommst du an die Optionen/Kommandozeile des Compilers ran? Steht da 
vielleicht eine Option, die (alle) Warnungen abschaltet? Ich würde das 
Handbuch des Compilers rauskramen oder online nach Compileroptionen 
suchen.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das habe ich vor längerer Zeit aus dem Forum.
FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i];


hier das Compiler Ergebnis.
----------------------------------------------------------------------
Debug build of project 
`E:\Pic_C_Sourcecode\Stellpult\StellpultController_18F8722\mytest\my_tes 
t.mcp'  started.
Preprocessor symbol `__DEBUG' is defined.
Sat Nov 28 11:14:42 2009
----------------------------------------------------------------------
Clean: Deleting intermediary and output files.
Clean: Deleted file 
"E:\Pic_C_Sourcecode\Stellpult\StellpultController_18F8722\mytest\my_mai 
n.o".
Clean: Deleted file 
"E:\Pic_C_Sourcecode\Stellpult\StellpultController_18F8722\mytest\my_tes 
t.cof".
Clean: Deleted file 
"E:\Pic_C_Sourcecode\Stellpult\StellpultController_18F8722\mytest\my_tes 
t.hex".
Clean: Done.
Executing: "C:\MCC18\bin\mcc18.exe" -p=18F8722 "my_main.c" 
-fo="my_main.o" -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
MPLAB C18 v3.22 (feature limited)
Copyright 2000-2008 Microchip Technology Inc.
This version of MPLAB C18 does not support the extended mode
and will not perform all optimizations.  To purchase a full
copy of MPLAB C18, please contact your local distributor or
visit buy.microchip.com.

Executing: "C:\MCC18\bin\mplink.exe" /l"C:\mcc18\lib" "..\18f8722.lkr" 
"my_main.o" /u_CRUNTIME /u_DEBUG /z__MPLAB_BUILD=1 /z__MPLAB_DEBUG=1 
/o"my_test.cof" /M"my_test.map" /W
MPLINK 4.22, Linker
Copyright (c) 2008 Microchip Technology Inc.
Errors    : 0

MP2HEX 4.22, COFF to HEX File Converter
Copyright (c) 2008 Microchip Technology Inc.
Errors    : 0

Loaded 
E:\Pic_C_Sourcecode\Stellpult\StellpultController_18F8722\mytest\my_test 
.cof.
----------------------------------------------------------------------
Debug build of project 
`E:\Pic_C_Sourcecode\Stellpult\StellpultController_18F8722\mytest\my_tes 
t.mcp'  succeeded.
Preprocessor symbol `__DEBUG' is defined.
Sat Nov 28 11:14:43 2009
----------------------------------------------------------------------
BUILD SUCCEEDED


Gruß Siegfried

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AH, da sieht man zumindest den Compiler (MPLAB C18)

Nimm in die Kommandozeile die Option -verbose auf.

Im User's Guide sieht man nicht, welcher Warnlevel default eingestellt 
ist und wie man den gewünschten Warnlevel 2 einstellt. Ich vermute, dass 
die -w2 Option es tut; könnte aber auch -w=2 sein. (Abschnitt 1.2.2 
Displaying Diagnostics)

Kompiliere dann neu mit dieser Zeile im Sourcecode (Verschlag von Karl 
heinz): FifoZeiger = /* (unsigned int*)(void*) */ &BusSpiOutput[i];

MPLAB C18 C COMPILER USER'S GUIDE
http://ww1.microchip.com/downloads/en/.../C18_User...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:

> Kompiliere dann neu mit dieser Zeile im Sourcecode (Verschlag von Karl
> heinz): FifoZeiger = /* (unsigned int*)(void*) */ &BusSpiOutput[i];

Da muss dann zumindest eine Warnung kommen. Ich würde sogar eher einen 
Fehler erwarten, weil die Pointertypen nicht kompatibel sind.

Wenn die Warnung da ist, dann änderst du um auf
ram unsigned char   *FifoZeiger;

denn dort steckt das eigentliche Problem (und die Behebung des Problems 
macht dann auch die Casts unnötig)

Aber gib auf keinen Fall auf, solange du in der Version mit dem unsigned 
int Pointer und den weggelassenen Casts keine Diagostic bekommst (Error 
oder Warning). Bei solchen Sachen MUSS der Compiler seinen Senf 
dazugeben! Ansonsten sind Fehlern Tür und Tor geöffnet!
Und nein: Casts sind dann keine Lösung. Die Lösung steckt praktisch 
immer darin, dass man sich die Datentypen der Pointer ansieht und 
angleicht.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siegfried Saueressig schrieb:
> Hallo,
>
> das habe ich vor längerer Zeit aus dem Forum.
> FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i];

Das mag sein und im richtigen Zusammenhang kann das auch richtig sein.
Bei dir ist es aber falsch.

Bei dir wäre richtig

   FifoZeiger = &BusSpiOutput[i];

und dazu muss FifoZeiger ein Pointer auf unsigned char sein.

Autor: Siegfried Saueressig (dieleena)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
hoffe das ich die richtige Infos gefunden habe.

Diagnostic's level
Error and warnings

Default storage class
Auto

Inherit global setting
-Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-

Als Anhang das Projekt

Gruß Siegfried

PS:
Info, habe weitere Zeilen eingefügt

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Solange du dich resistent zeigst, und diesen Unsinn

ram unsigned int   *FifoZeiger;

nicht endlich änderst, hat das alles keinen Sinn.
Es wurde dir jetzt schon mindestens 5 mal gesagt, dass die Casts raus 
müssen und der Datentyp des Pointer angepasst werden muss.

Schmeiss endlich die Casts raus!
Mit den Casts sagst du sinngemäss dem Compiler:
Es ist mir scheissegal, ob die Datentypen stimmen oder nicht. Halt die 
Schnauze und machs einfach!

Und kauf dir ein C-Buch!

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe jetzt den Rat befolgt.
Was ich nicht verstehe, ist das mit dem
"ram unsigned char *FifoZeiger;"
Ich war der Meinung, das ein Zeiger immer " int " ist.
Gruß Siegfried

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich war der Meinung, das ein Zeiger immer " int " ist.

schrei

Der Typ des Zeigers gibt an, auf was er Zeigt. Ganz einfach. ein /char* 
p;/ zeigt auf ein char und ein /int* p;/ zeigt auf ein int. Und /klaus* 
finger;/ zeigt auf einen Klaus.

Und nun kauf dir ein C-Buch, daran wirst du viel freude haben, weil das 
Programmieren auf einmal sehr viel einfacher geht!

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups, hab die formatierungen versemmelt. Denk dir alle / weg.

Autor: wieder nur ein gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Zeiger beinhaltet tatsächlich eine 16-bit-Adresse, das ist aber 
nicht ausschlaggebend, sondern auf welchen Datentyp jener Zeiger 
verweist!

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siegfried Saueressig schrieb:

> Ich war der Meinung, das ein Zeiger immer " int " ist.

Diese Meinung musst du korrigieren!

Vielleicht hast du die Größe eines Zeigers im Speicher mit dem Typ auf 
den er zeigt verwechselt. Bei manchen (!) Systemen ist der 
Speicherbedarf eines Zeigers genau so groß wie der Speicherbedarf einer 
int Variablen, also z.B. beide 16-Bit.

>> Und kauf dir ein C-Buch!

Das kann ich nur unterstützen ;-)

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Habe es jetzt verstanden.
C-Buch geht klar.
Gruß Siegfried

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>> FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i];
> keine Warnungen vom Compilers
Klar, wenn sie mit einem Monster-Cast unterdrückt werden   :-o

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Lothar Miller
bitte erkläre mir, wo ich was unterdrückt habe.

>>  Klar, wenn sie mit einem Monster-Cast unterdrückt werden   :-o

Habe all meine Projekte mit dem "Project Wizard" erstellt.

Gruß Siegfried

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Habe all meine Projekte mit dem "Project Wizard" erstellt.
Schon, aber das hier hast du selber gemacht:
   FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[i];
Schreib das mal ohne den Warnungs-Unterdrückungs-Cast:
   FifoZeiger = &BusSpiOutput[i];
Und jetzt sieh dir die Warnung zum Thema Wortbreite an.

Autor: Paul Baumann (paul_baumann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh wie schön ist Sprache "C",
schon beim Lesen tut das weh....

Mit "c" schreibt sich ein ganz normaler Kasten,
weil dort die Typen gar nicht passten.

Was glaubt ihr denn, wie mich das freut,
wenn ich nicht lesen muss ein "Void".

Auch das kleine Woertchen "Main"
ist bei mir nicht gern geseh'n.

Wenn ich bestimmen koennte all:
Auf den Schirm käm' nur PASCAL!

In diesem Sinne
Paul

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.