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
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.
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
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);
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
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ß
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.
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ß
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
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 );
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.....
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.
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.
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 // //
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 // //
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
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.
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.