Kennt jemand eine Lösung um ein Datenbyte gesplittet bidirektional von 2 verschiedenen Ports zu senden bzw zu empfangen(z.B. von PortA[A7,A6] und von PortC[C7...C2]). Steuerleitung geht ohne Probleme, aber 8Bit Datenleitung irgendwie nicht. Dachte ich könnte das so lösen (geht aber nicht!): ----------------------------------- Code ---------------------------------- void ausgabeP(unsigned char bitsVar) // Auslesen aus dem Byte und übergebe an PortC bzw. A {unsigned char bitsA, bitsC; bitsA = bitsVar & 0b00000011; // Maske bitsA <<= 6; // schiebe 6 mal nach links PORTA |= bitsA; bitsC = bitsVar & 0b11111100; PORTC |= bitsC; } unsigned char einlesenP(void) // einlesen in den Byte vom Port C und Port A { unsigned char bitsVar, bitsA = PINA, bitsC = PINC; bitsA &= ~((1<<PA7)|(1<<PA6)); bitsA >>= 6; bitsC &= 0b11111100; bitsVar = (bitsA | bitsC); return bitsVar; } ------------------------------ Ende Code --------------------------------------- Gibt es da anderen weg, weiß es nicht warum das so nicht geht... Danke :)
Beim Einlesen machst du dir hier deine gewünschten Daten kaputt:
1 | bitsA &= ~((1<<PA7)|(1<<PA6)); |
Beim schreiben musst du mal überlegen was passiert wenn im Vorfeld ein Bit im jeweiligen PORT-Register bereits gesetzt ist, du aber bei den neuen Daten eine 0 haben willst. Schreib dir deine Befehle einfach mal an einem konkreten Beispiel auf ein Blatt Papier auf, da solltest du es schon sehen.
Hi >Gibt es da anderen weg, weiß es nicht warum das so nicht geht... Was geht nicht? JTAG abgeschaltet? MfG Spess
Ungetestet:
1 | // schreiben:
|
2 | PORTA = (PORTA & ~(3 << 6)) | (bitsVar << 6); |
3 | PORTC = (PORTC & 3) | (bitsVar & ~3); |
4 | |
5 | // lesen:
|
6 | return (PORTA >> 6) | (PORTC & ~3); |
Viele LCD-Controller verfügen über einen 4-Bit Modus. Damit hättest du das Problem aus der Welt und vereinfachst dein Layout.
Entweder wie vorher, oder die belegung so umbauen dass du einen vollständigen Port zur Verfügung hast. PD würde sich anbieten.
test schrieb: > Beim Einlesen machst du dir hier deine gewünschten Daten kaputt:bitsA &= ~((1<<PA7)|(1<<PA6)); Da mach ich nur die überflüssigen Bits weg, die Beiden die mir wichtig sind bleiben doch erhalten.... Spess53 schrieb: > Was geht nicht? JTAG abgeschaltet? JTAG? warum spielt es da eine Rolle? Hab glaub ich abgeschaltet.... Philipp K. schrieb: > Ungetestet:// schreiben: > PORTA = (PORTA & ~(3 << 6)) | (bitsVar << 6); > PORTC = (PORTC & 3) | (bitsVar & ~3); > > // lesen: > return (PORTA >> 6) | (PORTC & ~3); Sieht das ganze nur verkürzt aus...??? Stimmts? Michael schrieb: > Viele LCD-Controller verfügen über einen 4-Bit Modus. Damit hättest du > das Problem aus der Welt und vereinfachst dein Layout. Wie gesagt, wenn der PortC Ganz normal genutzt wird, also vollständig, dann Funktioniert es. Hinzufügend: Es ist ein Grafik LCD, da gibt es leider den 4-Bit Modus nicht. Bzw. nicht bei dem LCD. Michael Reinelt schrieb: > Entweder wie vorher, oder die belegung so umbauen dass du einen > vollständigen Port zur Verfügung hast. PD würde sich anbieten. PD geht leider nicht wegen den 2 Externen Interrupts [Int0 und Int1], ja Sorry, sieht man nicht auf der Zeichnung, alle Pins mit Roten Markierung sind belegt oder reserviert. Und wenn ich Port C benutze, muss ich auf den I²C Bus verzichten... :( Meinst du es geht gar nicht?
Alex Daimler schrieb: > Hinzufügend: Es ist ein Grafik LCD, da gibt es leider den 4-Bit Modus > nicht. Das kann ja keiner ahnen ;-(
Hi >JTAG? warum spielt es da eine Rolle? Hab glaub ich abgeschaltet.... Bei aktivierten JTAG kannst du auf PC2...5 nicht zugreifen. >Meinst du es geht gar nicht? Wieso nicht? Ist doch nur etwas Bitschubsen. Allerdings verlängert das die Ausgabe auf das Display. MfG Spess
Spess53 schrieb: > Bei aktivierten JTAG kannst du auf PC2...5 nicht zugreifen. Gut, dann spielt es in meinem Fall keine Rolle, da ich nur PC6 und PC7 benutze. :) Spess53 schrieb: > Wieso nicht? Ist doch nur etwas Bitschubsen. Allerdings verlängert das > die Ausgabe auf das Display. Ich habe mir auch bereits überlegt, dass es wegen der kurzen Rechenzeit nicht klappt, bin mir aber nicht so sicher. Ist ja nur eine Vermutung gewesen. Wahrscheinlicher ist es dass ich was falsch mache... :/
Alex Daimler schrieb: > test schrieb: >> Beim Einlesen machst du dir hier deine gewünschten Daten kaputt:bitsA &= > ~((1<<PA7)|(1<<PA6)); > > Da mach ich nur die überflüssigen Bits weg, die Beiden die mir wichtig > sind bleiben doch erhalten.... Nein machst du eben nicht. Bit 7 und 6 sind ja die, um die es dir geht (mit den Pfeilen drunter). Beispiel: (angenommen bitsA == 10100110): ^^ ((1<<PA7)|(1<<PA6)) --> 11000000 ~((1<<PA7)|(1<<PA6)) --> 00111111 bitsA &= ~((1<<PA7)|(1<<PA6)) --> 10100110 & 00111111 = 00100110 bitsA >>= 6 --> 00000000
Alex Daimler schrieb: > Spess53 schrieb: >> Bei aktivierten JTAG kannst du auf PC2...5 nicht zugreifen. > > Gut, dann spielt es in meinem Fall keine Rolle, da ich nur PC6 und PC7 > benutze. :) Hä? Das sind eben genau die, die du benutzt. TMS,TCK,TDI,TDO Da hängt ein großteil deiner Datenpins vom Display dran. Wenn JTAG an ist, kannst du die nicht nutzen.
test schrieb: > Nein machst du eben nicht. Bit 7 und 6 sind ja die, um die es dir geht > > (mit den Pfeilen drunter). > > Beispiel: (angenommen bitsA == 10100110): > > ^^ > > > > ((1<<PA7)|(1<<PA6)) --> 11000000 > > ~((1<<PA7)|(1<<PA6)) --> 00111111 > > bitsA &= ~((1<<PA7)|(1<<PA6)) --> 10100110 & 00111111 = 00100110 > > bitsA >>= 6 --> 00000000 Danke dir für deine Mühe, war mein Fehler, hab aber auch mit Binären Maske gemacht also; bitsA = BitsA & 0b11000000; .. ging dennoch nicht. ------------------- test schrieb: > Hä? Das sind eben genau die, die du benutzt. TMS,TCK,TDI,TDO > > > > Da hängt ein großteil deiner Datenpins vom Display dran. Wenn JTAG an > > ist, kannst du die nicht nutzen. XD, ich glaub ich hab dich verwirrt^^ Ja du hattes Recht hab da den Port C mit Port A verwechselt ;) Mit JTag Häckchen bei Sec Bits würde das nicht funzen, ich habe keins gesetzt! Hab nachgeschaut und Probiert! Also Liegt das irgendwie am verarbeiten von Signalen. Irgendwo ist etwas zu schnell oder etwas zu langsam.. Wenn die Logic richtig ist. Grüße
Alex Daimler schrieb: > Wie gesagt, wenn der PortC Ganz normal genutzt wird, also vollständig, > dann Funktioniert es. > Hinzufügend: Es ist ein Grafik LCD, da gibt es leider den 4-Bit Modus > nicht. Bzw. nicht bei dem LCD. Nimm ein 74HC164 Schieberegister und takte die Daten über PA6 und PA7 raus. Musst Du Daten zurücklesen? Dann nimm ein HC595 und ein HC597. Ansonsten wäre einfach ein AVR mit mehr Pins die einfachste Lösung. Es gibt welche mit 100 Pins. Nur halt nicht im DIL-Gehäuse. Alternative: I2C Port Extender wie z.B. Microchip MCP23017. Dann hast Du 16 weitere Pins. fchk
Frank K. schrieb: > Nimm ein 74HC164 Schieberegister und takte die Daten über PA6 und PA7 > > raus. > > > > Musst Du Daten zurücklesen? Dann nimm ein HC595 und ein HC597. > > > > Ansonsten wäre einfach ein AVR mit mehr Pins die einfachste Lösung. Es > > gibt welche mit 100 Pins. Nur halt nicht im DIL-Gehäuse. > > > > Alternative: I2C Port Extender wie z.B. Microchip MCP23017. Dann hast Du > > 16 weitere Pins. > > > > fchk Danke, I2C Erweiterung mit 16 Ausgängen wäre meine Lösung als nächstes. Jetzt kenn ich zumindest die Bausteinbezeichnung für 16 Bit I2C Baustein. ;) Wollte es einfach ohne zusätzliche Hardware Lösen, wenn du verstehst was ich meine ;)
So Liebe Leut jetzt geht es, nach allen möglichen Lösungen, funktioniert dieses hier (geht sicher kürzer, aber so ist übersichtlich, wer möcht kann es abkürzen):
1 | void ausgabeP(unsigned char bitsVar) // Auslesen aus dem Byte und übergebe an Port |
2 | {
|
3 | PORTC = bitsVar & 0b11111100; |
4 | |
5 | switch (bitsVar & 0b00000011) |
6 | {
|
7 | case 0: |
8 | cbi(PORTA, PA7); |
9 | cbi(PORTA, PA6); |
10 | break; |
11 | case 1: |
12 | sbi(PORTA, PA6); |
13 | cbi(PORTA, PA7); |
14 | break; |
15 | case 2: |
16 | sbi(PORTA, PA7); |
17 | cbi(PORTA, PA6); |
18 | break; |
19 | case 3: |
20 | sbi(PORTA, PA7); |
21 | sbi(PORTA, PA6); |
22 | break; |
23 | }
|
24 | }
|
25 | |
26 | unsigned char einlesenP(void) // einlesen in den Byte vom Port |
27 | {
|
28 | unsigned char bytee = PINC; |
29 | |
30 | if (PINA & (1<<PINA7)) |
31 | {
|
32 | sbi(bytee,1); |
33 | }
|
34 | else
|
35 | {
|
36 | cbi(bytee,1); |
37 | }
|
38 | |
39 | if (PINA & (1<<PINA6)) |
40 | {
|
41 | sbi(bytee,0); |
42 | }
|
43 | else
|
44 | {
|
45 | cbi(bytee,0); |
46 | }
|
47 | return bytee; |
48 | }
|
MfG Alex
Alex Daimler schrieb: > Philipp K. schrieb: >> Ungetestet:// schreiben: >> PORTA = (PORTA & ~(3 << 6)) | (bitsVar << 6); >> PORTC = (PORTC & 3) | (bitsVar & ~3); >> >> // lesen: >> return (PORTA >> 6) | (PORTC & ~3); > > Sieht das ganze nur verkürzt aus...??? Stimmts? Verkürzt und korrigiert: 1. Schreiben: Die einzige Stelle, bei der bei Dir PORTC auftaucht, ist
1 | PORTC |= bitsC; |
Das setzt nur Bits, löscht aber keine. D.h., dass wenn Du beim letzten mal 111111xx in PORC geschrieben hattest, und Du willst nun 101010xx schreiben, keine Änderung erfolgt. 111111xx | irgendwas = 111111xx 2. Lesen: Ooops, Asche auf mein Haupt! Da habe ich PORTx statt PINx geschrieben, aber sei's drum, Du weißt was ich meinte:
1 | // lesen:
|
2 | return (PINA >> 6) | (PINC & ~3); |
Du schriebst ~((1<<PA7)|(1<<PA6)) als Maske, das ~ kannst Du weglassen, denn (1<<PA7)|(1<<PA6) = 11000000, und das ist das, was Du maskieren willst. Du kannst aber auch das Maskieren weglassen, weil die 6 rechten Bits mit "bitsA >>= 6" eh' verschwinden. Du scheinst dazu zu neigen, beim Programmieren erst mal alles in die kleinsten Einzelschritte aufzuteilen, was grundsätzlich gut ist. Nur hat es den Vorteil, das andere Programmierer es besser lesen können, und dass Compiler besser optimieren können, wenn solche Einzelschritte danach zu kompakten Ausdrücken zusammengefasst werden, solange diese Ausdrücke überschaubar bleiben. Auch hier gilt: Alles in Maßen, und wenn die Sache so komplex wird, dass mittendrin x?y:z Ausdrücke auftauchen oder es über viele Zeilen geht, dann schreibt man doch lieber ein paar einzelne Anweisungen. Dein zuletzt geposteter Code ist diesbezüglich nicht so optimal. Es ist möglich, dass ein bestmöglich optimierender Compiler Deine ganze switch-Anweisung wegoptimiert und am Ende Dein und Mein Code das gleiche Ergebnis produzieren, aber mein Code stiftet beim Lesen weniger Verwirrung und wird von einem anderen Bitfrunzel-Programmierer oder Jahre später von einem selbst in wenigen Sekunden verstanden. Um Deinen Code zu verstehen, muss man ihn erst mal im Kopf abarbeiten.
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.