mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik struct - Port emulieren - MPLAB C18


Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich weis manche werden sich warscheinlich den Kopf halten, aber für mich 
ist das noch neuland!

Ich Programiere in C mit MPLAB C18 den pic 18F2550.

1. Ich möchte ihn jetzt auch mit I²C betreiben, und deswegen fallen an 
PORTB 2 ausgänge weg, die ich zufor für das display benutzt habe (DIP 
204-4). Ich hab das Display über 8bit angesprochen:
PORTB = "c";
Das ging wunderbar, doch jetzt fällt das weg.
Ich hab mir gedacht das ich ja eine eigene struktur machen kann, aber es 
will net.
extern volatile near unsigned char LCD_DATA;
extern volatile near struct {
  unsigned LATA0:1;
  unsigned LATA1:1;
  unsigned LATA2:1;
  unsigned LATA3:1;
  unsigned LATA4:1;
  unsigned LATB5:1;
  unsigned LATB7:1;
  unsigned LATB6:1;
} LCD_DATAbits;

2. Können auch 2 Master Pics auf I²C miteinander komuniezieren, Wie?

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
>
> extern volatile near unsigned char LCD_DATA;
> extern volatile near struct {
>   unsigned LATA0:1;
>   unsigned LATA1:1;
>   unsigned LATA2:1;
>   unsigned LATA3:1;
>   unsigned LATA4:1;
>   unsigned LATB5:1;
>   unsigned LATB7:1;
>   unsigned LATB6:1;
> } LCD_DATAbits;
> 

Bitfelder sind eines der am wenigsten definierten Konstrukte in C 
überhaupt. Bis auf die Tatsache, dass du einer Komponente eines 
Bitfeldes einen Wert zuweisen kannst und ihn danach auch wieder 
herausbekommst, ist nix festgelegt.
Zitat:
> If insufficient space remains, whether a bit-field that does not fit
> is put into the next unit or overlaps adjacent units is
> implementation-defined. The order of allocation of bit-fields within
> a unit (high-order to low-order or low-order to high-order) is
> implementation-defined. The alignment of the addressable storage unit
> is unspecified.

Autor: Be Bo (bebo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wäre es mit einem #define Macro?

Z.B. sowas (nur Beispielhaft):
#define LCD_DATA(x) {\
LATB &= ~0xF3;\
LATC &= ~0x03;\
LATB |= x & 0xF3;\
LATC |= (x>>2) & 0x03;\
}

Hiermit könntest Du Dein Byte beliebig zerlegen und auf mehrere Ports 
verteilen.

Dann würdest Du anstatt
PORTB = x
LCD_DATA(x);
schreiben.

Übrigens, würde ich Dir empfehlen zum Schreiben die LATx Register zu 
verwenden. Insbesondere dann, wenn ein Port von verschiedenen 
Programmteilen angesprochen wird.

Zu den Bitfeldern: Dadurch, daß Du die Namen änderst, ändert sich nichts 
an den Bitpositionen. Du hast damit nur die Bits in PortB umbenannt. Bei 
Dir heißt das erste Bit in PortB nun LATA0, aber physikalisch wird ist 
Dein LATA0 das gleiche Bit, das vorher LATB0 hieß.

Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Be Bo schrieb:
> #define LCD_DATA(x) {\
> LATB &= ~0xF3;\
> LATC &= ~0x03;\
> LATB |= x & 0xF3;\
> LATC |= (x>>2) & 0x03;\
> }

das &= und |= irritiert mich grad ein bissle.
kannst du das vllt auch in ganz "billiger" schreibweise für mich 
schreiben? :)

Be Bo schrieb:
> Übrigens, würde ich Dir empfehlen zum Schreiben die LATx Register zu
> verwenden. Insbesondere dann, wenn ein Port von verschiedenen
> Programmteilen angesprochen wird.

xD oops ja mach ich ja eigentlich, hab vorhin nur ein bissle hektik 
gehabt





Michael schrieb:
> 2. Können auch 2 Master Pics auf I²C miteinander komuniezieren, Wie?

Autor: Be Bo (bebo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

& und | sind sognannte binäre Verknüpfungen.
Also wenn ein Byte %10101010 enthält und Du es mit 0x0F verUNDest 
erhältst Du %00001010. Das | ist das gleiche nur mit ODER Verknüfung.

Die Schreibweise

VARIABLE &= 0x0F   ist das selbe wie    VARIABLE = VARIABLE & 0x0F

Gibt's auch für alle andere Operatoren. Z.B.:

x++ <==> x=x+1 <==> x+=1

oder

y = y<<2  <==>  y<<=2

Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Be Bo schrieb:
> Hi,
>
> & und | sind sognannte binäre Verknüpfungen.
> Also wenn ein Byte %10101010 enthält und Du es mit 0x0F verUNDest
> erhältst Du %00001010. Das | ist das gleiche nur mit ODER Verknüfung.
>
> Die Schreibweise
>
> VARIABLE &= 0x0F   ist das selbe wie    VARIABLE = VARIABLE & 0x0F
>
> Gibt's auch für alle andere Operatoren. Z.B.:
>
> x++ <==> x=x+1 <==> x+=1
>
> oder
>
> y = y<<2  <==>  y<<=2


Blick ich jetzt trotzdem net, was bringt das mir nun?
kannst du mir vllt ein einer ganz billigen schreibweise zeigen wie ich 
pins von  verschiedenen ports in eine struktur unterbringe?

Autor: Dieter Werner (dds5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Struktur aus "verteilten" Bits ist grundsätzlich nicht möglich, die 
Bits einer Struktur müssen zusammenhängend sein.

Es dürfte daher am einfachsten sein, sich eine Funktion zur 
(Port-)Bitmanipulation selbst zu schreiben.

Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab jetzt mal ein bisschen probiert:

[c]
#define LCD_DATA(x) {\
LATAbits.LATA0 = x & 0x01;\
LATAbits.LATA1 = x & 0x02;\
LATAbits.LATA2 = x & 0x04;\
LATAbits.LATA3 = x & 0x08;\
LATAbits.LATA4 = x & 0x10;\
LATBbits.LATB5 = x & 0x20;\
LATBbits.LATB7 = x & 0x40;\
LATBbits.LATB6 = x & 0x80;\
}
[\c]

Stimmt das mit meinen zielen überein?

Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hab nun am Display die reihenfolge geändert (notdürftig, 2 pins 
getauscht)
D7 A0
D6 A1
D5 A2
D4 A3
D3 A4
D2 B5
D1 B6
D0 B7

dann hab ich mir eine kleine funktion geschrieben:
void LCD_DATA (char x)
{
  LATA = x & 0xF8;
  LATB = x & 0x07;
 } 

Was ich leider erst jetzt herausgefunden habe, ist das eigentlich

D7 B7
D6 B6
D5 B5
D4 A4
D3 A3
D2 A2
D1 A1
D0 A0

Also genau umgekehrt.
wie kann ich nun praktisch
x = !x;
machen, um diesen effekt aufzuheben?

Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Also genau umgekehrt.
> wie kann ich nun praktisch
> x = !x;
> machen, um diesen effekt aufzuheben?

ähm, x = !x; net aber halt verdrehen:

aus
01110000 mach
00001110

Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> aus
> 01110000 mach
> 00001110

stimmt ja au net, oh man,
kann mir denn keiner helfen?

Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Michael schrieb:
>> aus
>> 01110000 mach
>> 00001110
>
> stimmt ja au net, oh man,
> kann mir denn keiner helfen?

Also ich müsste die bits verschieben können, wie mach ich das? kann ich 
au einzelne einem ausgang übergeben. wie?

Beispiel:

11010101
  | |
  | +-> Ausgang B7
  +---> Ausgang A0

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit >> und <<. 'Einzeln' geht mit Masken, zuerst mit einer 
UND-Verknüpfung das alte oder die alten Bits im Register löschen, dann 
mit ODER die neuen einbauen.
char reg, v;

/* Lösche Bits 2 und 3 */
reg &= ~0b00001100;

/* Schreibe Bit 1 von v ins 3. Bit des Registers */
reg |= ( v & (1 << 1) ) << 2;

/* Schreibe Bit 6 von v ins 2. Bit des Registers */
reg |= ( v & (1 << 6) ) >> 4;

Autor: *Michael* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dankeschön an alle die geholfen haben und mich auf den richtigen weg 
gebracht haben. :D

Ich hab nun für folgende verbindung eine kleine funktion geschireben.

D7 B7
D6 B6
D5 B5
D4 A4
D3 A3
D2 A2
D1 A1
D0 A0
void LCD_DATA (char x)
{
  char Er_1 = 0x00;
  char Er_2 = 0x00;

  Er_1 = LATA & 0xE0; // A5 - A7 aufheben
  Er_2 = x & 0x1F;    // Daten für A0 - A4 filtern
  LATA = Er_1 | Er_2;

  Er_1 = LATB & 0x1F;  // B0 - B4 aufheben
  Er_2 = x & 0xE0;  // Daten für B5 - B7 filtern
  LATB = Er_1 | Er_2;
}

Kurze erleuterung für die nachwelt.

B7      0
B6      0
B5      0
B4      1
B3   &  1 -> Momentane einstellung auf den Ports B0 - B4 aufheben in 
Er_1
B2      1
B1      1
B0      1

X7      1
X6      1
X5      1
X4      0
X3   &  0 -> Bestimmten bereich herrausfiltern und aufheben in Er_2
X2      0
X1      0
X0      0

PORTB = Er_1 | Er 2  -> Zusammenfutzeln und in PORTB schreiben



Das selbe Prinzip auc für den 2ten teil.

Ich wünsch euch nun noch eine schöne Wheinachtszeit!!!!!!!

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.