www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Ausgabe-HexWert an 8 Pins?


Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte einen Hex Wert an die die Ports D0-D7 meines LCDs senden. 
Enable und CS funktionieren allerdings stehe ich wie der OChs vorm Berg 
beim Schreiben einer Funktion die mir z.B den Wert 3F an 8 Pins meines 
Kontrollers schickt (Atmel-ARM)!

ICh will keine Lösung, aber wenn mir jemand den grundsäztlichen Ablauf 
erklären könnte wäre das Super, danke!

Gruß


Andreas

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

Bewertung
0 lesenswert
nicht lesenswert
Andreas wrote:
> Hallo,
>
> ich möchte einen Hex Wert an die die Ports D0-D7 meines LCDs senden.
> Enable und CS funktionieren allerdings stehe ich wie der OChs vorm Berg
> beim Schreiben einer Funktion die mir z.B den Wert 3F an 8 Pins meines
> Kontrollers schickt

Du bruachst nichts spezielles zu tun. Gib einfach die 0x3f an
den Port aus und deine Portpins werden den Zustand
     0011 1111
annehmen.

Binär, Hex, Dezimal sind nur verschiedene Schreibweisen für
Zahlen. Das ändert aber an der Zahl nichts.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,


das dachte ich auch! allerdings bekomme ich an allen Pins ein High!
so sieht meine Funktion dazu aus:

void ks0108_write_data (uint8_t data, uint8_t chip) {

  AT91F_PIO_ClearOutput (pPIO, LCD_DATA | LCD_RW | LCD_CS1 | LCD_CS2);
  AT91F_PIO_SetOutput (pPIO, LCD_RW);
  data &= 0xff;

  if (chip == left)  {
    AT91F_PIO_ClearOutput (pPIO, LCD_CS2);
    AT91F_PIO_SetOutput (pPIO, LCD_CS1);
      //pPIO->PIO_SODR = LCD_DATA & (data << LCD_SHIFT);
      pPIO->PIO_SODR = ((uint32_t)data<<LCD_PIN0);
  }
  if (chip == right)  {
    AT91F_PIO_ClearOutput (pPIO, LCD_CS1);
    AT91F_PIO_SetOutput (pPIO, LCD_CS2);
void ks0108_write_data (uint8_t data, uint8_t chip) {

  AT91F_PIO_ClearOutput (pPIO, LCD_DATA | LCD_RW | LCD_CS1 | LCD_CS2);
  AT91F_PIO_SetOutput (pPIO, LCD_RW);
  data &= 0xff;

  if (chip == left)  {
    AT91F_PIO_ClearOutput (pPIO, LCD_CS2);
    AT91F_PIO_SetOutput (pPIO, LCD_CS1);
      //pPIO->PIO_SODR = LCD_DATA & (data << LCD_SHIFT);
      pPIO->PIO_SODR = LCD_DATA & data;
  }
  if (chip == right)  {
    AT91F_PIO_ClearOutput (pPIO, LCD_CS1);
    AT91F_PIO_SetOutput (pPIO, LCD_CS2);
      pPIO->PIO_SODR = LCD_DATA & data;
  }
  ks0108_en();

}
  }
  ks0108_en();

}

LCD_DATA entspricht den Ausgabeports D0-D7 und an allen liegt ein High 
an.
Irgendeine Idee?

Gruß

Andreas

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups.....ich  verunnde das nicht sondern ich mach ein "oder" dazwischen, 
dann liegt an allen Pins ein High an!

So meinte ich das:

pPIO->PIO_SODR = (LCD_DATA | data);

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

Bewertung
0 lesenswert
nicht lesenswert
Andreas wrote:
> ups.....ich  verunnde das nicht sondern ich mach ein "oder" dazwischen,
> dann liegt an allen Pins ein High an!
>
> So meinte ich das:
>
> pPIO->PIO_SODR = (LCD_DATA | data);

Welchen Wert hat LCD_DATA
Welchen Wert hat data

Wenn du die beiden vorODERst, dann kriegst du ueberall dort
eine 1 wo entweder in LCD_DATA oder in data eine 1 ist.

Wenn also an allen Pins eine 1 messbar ist, dann wird wohl
aus der Veroderung von LCD_DATA und data der Wert 0xFF folgen.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Logik

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LCD_Data setze ich mit dem Befehl:

AT91F_PIO_ClearOutput (pPIO, LCD_DATA | LCD_RW | LCD_CS1 | LCD_CS2);

auf 0 am Ausgang.

Die nächste relevante Zeile für LCD_DATA ist dann zum Beispiel folgende:

pPIO->PIO_SODR = (LCD_DATA | data);

danach erscheint an den Ausgängen =0xFF. data beinhaltet 0x3F.
Im Debugmodus habe ich mich versichert das dem auch so ist.


In anderen Beispielel habe ich solche Lösungen gesehen:

      pPIO->PIO_SODR = ((uint32_t)data<<LCD_PIN0);

Wobei LCD_PIN0 D0 repräsentieren soll, kommt aber im Endeffekt das 
Gleiche raus, alle Ausgänge High.

irgendeine Idee?

Gruß

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

Bewertung
0 lesenswert
nicht lesenswert
Andreas wrote:
> LCD_Data setze ich mit dem Befehl:
>
> AT91F_PIO_ClearOutput (pPIO, LCD_DATA | LCD_RW | LCD_CS1 | LCD_CS2);
>

Nochmal:

Welcher   W E R T   (also welche Zahl) steht hinter LCD_DATA.

LCD_DATA ist ein Makro, dass irgendwo in deinem Code vorkommt.
Irgendwo muss stehen

#define LCD_DATA  xxx

und das xxx ist das Interessante.

> irgendeine Idee?

Ja. Lerne C beginnend mit den Grundlagen. Programmieren lernen
nach dem Muster: Ich probier einfach mal jedes Zeichen das ich
irgendwo gesehen oder von dem ich gehört habe, funktioniert
einfach nicht.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das steht hinter LCD_Data:

#define LCD_DATA 
(LCD_D0|LCD_D1|LCD_D2|LCD_D3|LCD_D4|LCD_D5|LCD_D6|LCD_D7)

das steht hinter LCD_Dx:

#define LCD_D0 (1<<23)          // P23
#define LCD_D1 (1<<25)          // P25
#define LCD_D2 (1<<26)          // P26
#define LCD_D3 (1<<27)          // P27
#define LCD_D4 (1<<28)          // P28
#define LCD_D5 (1<<29)          // P29
#define LCD_D6 (1<<30)          // P30
#define LCD_D7 (1<<31)          // P31

Gruß

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

Bewertung
0 lesenswert
nicht lesenswert
Andreas wrote:
> das steht hinter LCD_Data:
>
> #define LCD_DATA
> (LCD_D0|LCD_D1|LCD_D2|LCD_D3|LCD_D4|LCD_D5|LCD_D6|LCD_D7)
>
> das steht hinter LCD_Dx:
>
> #define LCD_D0 (1<<23)          // P23
> #define LCD_D1 (1<<25)          // P25
> #define LCD_D2 (1<<26)          // P26
> #define LCD_D3 (1<<27)          // P27
> #define LCD_D4 (1<<28)          // P28
> #define LCD_D5 (1<<29)          // P29
> #define LCD_D6 (1<<30)          // P30
> #define LCD_D7 (1<<31)          // P31
>


Da darfst du dich jetzt aber nicht wundern, dass alle Ausgabepins
1 sind.

LCD_DATA ist eine 32 Bit Zahl in der 8 Stück 1-en gesetzt sind.
d.h. binär so
    1111 1111 0000 0000 0000 0000

wenn du das jetzt mit 0x3F veroderst

        1111 1111 0000 0000 0000 0000 0000 0000
oder    0000 0000 0000 0000 0000 0000 0011 1111

dann kriegst du als Ergebnis

        1111 1111 0000 0000 0000 0000 0011 1111

        |+++++++|

und wenn es der markierte Bitbereich ist, den du an
den Ausgangspins misst, dann ist der klarerweise immer
alle Bits 1

Du musst logischerweise deine 0x3F erst mal soweit
nach links schieben, dass sie auch uber den 'Ausgangsbits'
liegen.

     data << LCD_D0

oder da es anscheinend dafür ein Makro gibt

     data << LCD_PIN0

(was wahrscheinlich dasselbe ist)
damit wird aus den 0x3F

      0011 1111 0000 0000 0000 0000 0000 0000

und das dann mit LCD_DATA verodert

        1111 1111 0000 0000 0000 0000 0000 0000
oder    0011 1111 0000 0000 0000 0000 0000 0000

ergibt immer noch

        1111 1111 0000 0000 0000 0000 0000 0000

also alle Bits 1, weil Oder die falsche Operation ist.

Aber

        1111 1111 0000 0000 0000 0000 0000 0000
und     0011 1111 0000 0000 0000 0000 0000 0000

ergibt

        0011 1111 0000 0000 0000 0000 0000 0000

und das willst du haben.

In C
    pPIO->PIO_SODR = ((uint32_t)data<<LCD_PIN0) & LCD_DATA;

Wozu das & (die UND Operation).
Angenommen deine Zahl wäre nicht so schön, wei hier und
da wären an anderer Stelle noch ein paar 1-en

        1111 1111 0000 0000 0000 0000 0000 0000
und     0011 1111 0000 0000 1001 0010 0010 0000

dann lautet das Ergebnis wieder
        0011 1111 0000 0000 0000 0000 0000 0000

weil durch die UND-Operation nur dort im Ergebnis eine 1 auftauchen
kann, wo in der Maske (in LCD_DATA) eine 1 steht. Dort wo in der
Maske eine 0 ist, ist auch im Ergebnis auf jeden Fall eine 0.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Logik

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

Bewertung
0 lesenswert
nicht lesenswert
Moment mal:

Ist LCD_D0 sicher  1 << 23 und nicht 1 << 24
(Sorry, habs jetzt erst gesehen, damit ist das meiste
aus dem letzten Post hinfällig)

Wer denkt sich denn sowas aus? Ist doch Schwachsinn die
Datenbits auseinanderzureissen. Das gibt dich nur Ärger
oder zumindest unnötig komplizierten Code. Dann geht das
mit einer einzelnen Schiebe und Maskier- Operation nämlich
sowieso nicht.

Dann muss das heissen:
#define LCD_DATA_REST  LCD_D1 | LCD_D2 | LCD_D3 | LCD_D4 \
                       LCD_D5 | LCD_D6 | LCD_D7

    pPIO->PIO_SODR = ( ((uint32_t)data << LCD_D0) & LCD_D0 ) |
                     ( ((uint32_t)data << (LCD_D1-1)) & LCD_DATA_REST );

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh....Danke für dein Input!

Das wichtigste vorweg....es klappt immer noch nicht. Alle Ausgänge sind 
LOW.
Das mit dem shiften habe ich mir schon gedacht, allerdings war ich noch 
zu sehr in der 8Bit Welt vom Studium.

Das mit den PA 23 PA25 PA26 usw ist wirklich sehr doof, allerdings 
benutzte ich ein EK Board von OLIMEX und das hat max. 7 
aufeinanderfolgen Ports mit einem Anschlußpin auf dem Board, wenn ich 
Port 24 benutzen möchte dann müßte direkt an den Kontroller (Pin23) 
gehen. Andere Ausgänge wie SPI, I²C UART werden schon benutzt und fallen 
somit weg.

Mit deiner schnellen Lösung zu dem Problem kann ich im Debugmodus sehen, 
daß er gar nicht mehr in die Funktion pPIO->PIO_SODR springt, sondern 
sie einfach übergeht!

Eine Warnung bekomme ich auch beim kompilieren:

warning: left shift count >= width of type

aber die ignoriere ich ersteinmal.....

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

Bewertung
0 lesenswert
nicht lesenswert
Andreas wrote:
> Oh....Danke für dein Input!
>
>> Eine Warnung bekomme ich auch beim kompilieren:
>
> warning: left shift count >= width of type
>
> aber die ignoriere ich ersteinmal.....

Die solltest du nicht ignorieren. Die ist nämlich fatal.
Wo genau kriegst du sie?

Im #define steckt übrigens noch ein Fehler:

#define LCD_DATA_REST  ( LCD_D1 | LCD_D2 | LCD_D3 | LCD_D4 \
                         LCD_D5 | LCD_D6 | LCD_D7 )

Auch diese Klammern sind wichtig.

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

Bewertung
0 lesenswert
nicht lesenswert
Wenn du so nicht weiter kommst, dann drösle das ganze
mal auf:

   uint32_t value1, value2;

   value1 = (((uint32_t)data) << LCD_D0;
   value1 = value & LCD_D0;

   value2 = (((uint32_t)data) << (LCD_D1-1);
   value2 = value2 & LCD_DATA_REST;

   value1 = value1 | value2;
   pPIO->PIO_SODR = value1;


und sieh nach wo was verloren geht und wo noch casts
oder Klammern hinmuessen.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe jetzt mal einiges probiert aber im Endeffekt änder sich nichts, zur 
Zeit zumindest:

//      value1 = (data << LCD_D0);  // nach dieser Zeile value1 = 0
//   value1 = value1 | LCD_D0;    // nach dieser Zeile value1 = 8388608 
=>                          100000000000000000000000
//   value2 = (((uint32_t)data) << ((LCD_D1-1)-3));    // nach dieser 
Zeile value2 = 0
//   value2 = value2 | LCD_DATA_REST;        // nach dieser Zeile value2 
= 4261412864  =>  11111110000000000000000000000000
//
//   value1 = value1 | value2;          //nach dieser Zeile value1 = 
4269801472      => 11111110100000000000000000000000
//   pPIO->PIO_SODR = value1;            // alle Pins am Ausgang auf 
High!  gewünscht=> 00111111000000000000000000000000
                          //
                          //

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kleine Korrektur:


//      value1 = (data << LCD_D0);  // nach dieser Zeile value1 = 0
//   value1 = value1 | LCD_D0;    // nach dieser Zeile value1 = 8388608
=>                          100000000000000000000000
//   value2 = (((uint32_t)data) << (LCD_D1-1));    // nach dieser
Zeile value2 = 0
//   value2 = value2 | LCD_DATA_REST;        // nach dieser Zeile value2
= 4261412864  =>  11111110000000000000000000000000
//
//   value1 = value1 | value2;          //nach dieser Zeile value1 =
4269801472      => 11111110100000000000000000000000
//   pPIO->PIO_SODR = value1;            // alle Pins am Ausgang auf
High!  gewünscht=> 00111111000000000000000000000000
                          //
                          //

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

momentaner Stand ist, daß ich herausgefunden habe das der ARM sich nicht 
für das Interessiert was ich ausgeben möchte.
egal ob 0x00 oder 0xff es ist immer das gleiche ergebniss!
Mal schauen wie ich weiterkomme

Autor: Obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sagt senn dein Debugger?

Autor: maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh leute...

schreine doch einfach mal direkt was an deinen port, ohne defines, ohne 
shift ops, soweit das möglich ist...  und dann step bei step aufbohren, 
wenn der arm das macht was du erwartest..

gruß,
m.

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.