PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie kann ich ein Byte über einen Port Pin ausgeben?



CriGri
22.09.2006, 16:02
Hallo liebe Gemeinde.

Ich hätt da mal ne Frage zu folgender Schaltung

Die Hardware:

AT89C2051 -LCD
- 74HC164(8-Bit Schieberegister,seriell in,parallel out) -
74HCT245N(Treiber) - LED's

(Ich programmiere in C)

Also dies wär nun die Hardware.Mein Paps hat mich gebeten im ein kleines effektlich zu basteln wo er die Programmmodes wählen kann(geschw.,Leuchtstärke,mode usw.)Dies ist nun nur ein kleiner Versuch die Leds mit einer µC-Portleitung anzusteuern.Später werden es dann mehrere sein + chipselect.Ahm...meine Frage ist nun ob und wie ich denn ein Bitmuster über eine beliebige Portleitung ausgeben kann?
Der 164er übernimmt die Daten nach jedem H-L-Übergang.Das heißt das ich immer wieder Bit fü Bit senden muss und dann auch noch für jedes Bit nen H-L-Üübergang erzeugen muss.
Gibts da ne möglicht den Port Pin nicht jedesmal neu setzen zu müssen sonder im einfach ein Byte zu übergeben?
Hab da an TxD (SBUF)gedacht.ginge es Wenn ich ins SBUF Register ein Byte schreibe und es über TxD sende?

Ansonsten könnte ich mir nur ne eigene Funktion progn indem ich im Funktionskopf das Muster eingebe und in der Funktion selber immer wieder den Pin setze,den H-L-Übergang erzeuge usw.!

Vielleicht habt ihr ja ne Idee wie ich es eleganter lösen könnte.
Mfg Cri

Peter Dannegger
22.09.2006, 16:21
Wenn Du die UART nicht brauchst, kannst Du sie im Mode 0 nehmen.

Aber es ist auch kein Akt, die Bits seriell in einer Schleife auszugeben.

Ich würde aber besser zum 74HC595 raten.
Da kann man im Hintergrund schieben und dann die Daten gleichzeitig ausgeben. Das Schieben bleibt also unsichtbar.
Den 74HCT245 brauchst Du dann auch nicht.



Peter

guidob
22.09.2006, 16:23
Hallo CriGri,

tja das klingt nach klassischem Bitbanging. Es lohnt wohl schon hierfür eine Funktion
zu programmieren, da man das öfter braucht. Die einfachste Art ist es, das Byte Bit für
Bit mit rlc oder rrc ins CarryFlag zu rotieren, dann den Portpin je nach C setzen oder
zurücksetzen und dann den Takt zu generieren. Klingt umständlich, ist aber kein Thema
dank djnz.

guidob

CriGri
22.09.2006, 16:47
Danke für die schnellen Antworten.

Ich würd gern den 594er verwenden aber leider hab ich den nicht zuhause :/
Ich werds wahrscheinlich mit der selbstgeschrieben Funktion machen da ich die UART für die RS232 nutzen werde.

Das mit dem rotieren hab ich leider noch nie gemacht und ich hab auch (noch!)keine Ahnung wie das geht.

Mfg Cri

Peter Dannegger
22.09.2006, 17:19
void displaywrite( unsigned char dc )
{
unsigned char i = 8;
do{
DISDAT = dc & 0x80;
dc <<= 1;
DISCLK = 1;
DISCLK = 0;
}while( --i );
}



Peter

CriGri
22.09.2006, 20:02
Ahm...danke :)

Aber könntest du mir auch sagen was das Progi tut :) ?
Also wo nimmst du die Variablen (falls es welche sind)her?
Wie funzt denn das??

Sorry aber ich kenn mich grad nicht aus! :)

Nachtrag: OK...also ich habs schon ein wenig verstanden was du mir da angeboten hast, aber das geht ja dann nur mit einem Bit richtig,oder?Da du das Bit ja dann um eine Stelle nach links verschiebst und ich im Funktionskopf ja nur 1 oder 0 eintippseln kann.

lieg ich da nun komplett daneben oder wie ist das nu?


Mfg Cri

HILF MIR WEITER!!!!!!!!!!!!!!!!! :)

semmel
22.09.2006, 20:54
Hi CriGri,

lange nichts mehr von dir gehört. Was macht dein Projekt ?

Vielleicht hilft das hier:

for(n=0;n<8;++n)
{
if (x & (1<<n))
{
PORTPIN |= 0x01;
}
else
{
PORTPIN &= ~0x01;
}
}

Probier es mal aus.

semmel
22.09.2006, 20:57
if (x& (1<<n)

Ich weiß nicht warum die Zeichen hier verbogen werden, 2ter Versuch.

semmel
22.09.2006, 20:59
interessant, da sollte stehen: wenn x und 1 kleiner, kleiner n

Jedesmal der Mist hier.

neuling
22.09.2006, 21:32
versuchs mal mit Code:


Die schaltfläche mit der Raute und dan einfach zwischen den zwei Wörtern mit klammern reinschreiben

davor dann nochmal per Vorschau überprüfen und passt ^^

CriGri
23.09.2006, 18:23
Hi Semmel!!!!

Mein Projekt hab ich auf Eis gelegt(zur Zeit)...Die Sommerferien über war ich leider sehr faul :) aber nu beginnt ja die FH und da werd ich nun wieder den Turbo einschalten ;p

Wie gehts dir???

hmm...Hab mir ne Routine geschrieben für die Muster die ich Ausgeben will.Berauche nur 2 Leitungen(CLK & DATA) und der 164er wandelt mir die dann parallel um.

void LED_Muster(bit a,bit b,bit c,bit d,bit e,bit f,bit g,bit h)
{
S_Out=a;
CLK=0; CLK=1;
S_Out=b;
CLK=0; CLK=1;
S_Out=c;
CLK=0; CLK=1;
S_Out=d;
CLK=0; CLK=1;
S_Out=e;
CLK=0; CLK=1;
S_Out=f;
CLK=0; CLK=1;
S_Out=g;
CLK=0; CLK=1;
S_Out=h;
CLK=0; CLK=1;
}

Sieht zwar nicht so schön aus aber die funzt ganz gut :)

Wolltest du vorher [CODE] if(x&(1<n)) [/code="" schreiben="">
woher nimmst das x bzw. wo wird das gesetzt?

lol...das is ja ein Dreck mit dem Code einschreiben hier...der schneidet echt den hinteren Teil einfach weg...lol

Mfg Cri</n))>

Peter Dannegger
23.09.2006, 19:17
Was gefällt Dir denn daran nicht, ein ganzes Byte zu übergeben ?

Der 8051 ist Byte-orientiert, d.h. ein Byte 8* zu schieben und auf dem Pin auszugeben, gefällt ihm viel besser, als jedes Bit einzeln.

Das DISDAT und DISCLK die beiden Pindefinitionen sind, sollte wohl klar sein.


Peter

CriGri
23.09.2006, 19:23
Ahm...nicht dass es mir nicht gefällt aber soweit ich dein Programm richtig "verstanden"habe (oder auch nicht :) ),kann ich da nicht verschiedene Muster ausgeben sondern einfach nur ein Lauflicht erzeugen.
Für meine Bedürfnisse benötige ich jedoch Muster. z.B.:01010101 oder 11001100 usw.

Also ich hab mir nun deine Progi noch mal angesehn und glaube geschnallt zu haben dass ich doch Muster darstellen kann :)
Durch DISDAT = dc & 0x... (beliebige Hex-Zahl)
kann ich ja das dc immer verändern und somit ein Muster generieren.
Richtig oder?


Mfg Cri

Peter Dannegger
23.09.2006, 19:46
Also ich hab mir nun deine Progi noch mal angesehn und glaube geschnallt zu haben dass ich doch Muster darstellen kann :)
Durch DISDAT = dc & 0x... (beliebige Hex-Zahl)
kann ich ja das dc immer verändern und somit ein Muster generieren.
Richtig oder?

Ja, nachdem Du die Routine aufgerufen hast, ist das ganze Byte "dc" in Deinem 74HC164.
Das höherwertige Bit dc.7 an Ausgang 7 und dc.0 an Ausgang 0.

Das Schieben geht so schnell, daß Du es nicht siehst.

D.h. nur wenn Du sehr oft schiebst, glimmen die LEDs, die aus sein sollen, leicht. Das Schieben ist nur beim 74HC595 komplett unsichtbar.


Peter

semmel
23.09.2006, 19:49
Hi Christian,

mir gehts gut. Woher nehm ich das x ? Na das ist der Wert der herausgeschoben werden soll.

Trau mich nicht hier Code hereinzustellen.

Also, du vergleichst jedes BIT das in x steht mit 1.
1 = 00000001

Nun wird die 1 durch das (kleiner, kleiner Zeichen) nach links geschoben (mittels der for Schleife) und dann x (der Ausgabewert) BIT für BIT abgetastet. Ist das betreffende BIT=1, so wird auch der Port Pin = 1, else 0.

Verstanden ?

Das Ganze wird also MSB first herausgeschoben. Willst du umgekehrt schieben so verwendest du das (größer, größer). Das schiebt nach rechts, also LSB first. Statt mit einer 1 wird dann aber auf 0x80 verglichen.

0x80 = 10000000

Nun alles klar ?

semmel
23.09.2006, 19:57
{
_OENABLE &=~0x01;
for (n=0; n<8; n++)
{
if (dsp_char_out & (0x80 >> n))
{
_DATA |= 0x01;
}
else
{
_DATA &= ~0x01;
}
shift_clock();
}
_DATA |=0x01;
_OENABLE |=0x01;
char_count ++;
}


So, hab mich noch einmal getraut, sieht grauenhaft aus, denke aber du siehst das wesentliche. In shift_clock() erzeugst du dann noch einen Schiebetakt. In dsp_char_out steht dein Wert den du ausgeben willst, kannst du ja wieder x nennen ;-))

CriGri
23.09.2006, 22:06
Hidiho...

Vielen Dank an euch (Peter und Semmel).
Schön dass ihr gedult mit mir habt 8) Es gibt noch viele Sachen die ich nicht kann und das dauert halt ein wenig.
Ich werd morgen mal eure Progis Testen und euch dann bescheid geben.

@Semmel

HAst du zur Zeit ein Projekt am laufen?

Mfg Cri

Holger
24.09.2006, 12:08
Vielleicht habe ich da ja was nicht ganz gerafft, aber wenn ich ein Byte aus nem 889C2051 rausschieben will, beschreib ich einfach Sbuf, den Rest macht da die Hardware. Daten kommen aus RXD, der Takt aus TXD, sofort ein Masch-Takt nach dem Beschreib-Befehl!
Vielleicht hilfts ja....;)

semmel
24.09.2006, 18:03
Die Frage die Christian gestellt hatte: ...über eine beliebige Portleitung ...

Klar kann man auch SBUF nehmen, aber so sollte es nicht gelöst werden.

@ Christian, ja, mehrere Projekte, wenn es nur eins wäre dann hätte ich ein bischen mehr Zeit.

CriGri
25.09.2006, 12:19
ja wenigstens lanweilst du dich nicht ;)
Ich werd nun mein Projekt auch beginnen.In Verbindung mit der FH(kann dort alle technischen Gegenstände und Laboratorien verwenden wann und wie oft ich will)wird es sicherlich mehr als geil am Robo zu tüffteln und endlich neue Dinge anzuwenden.

Tja...und was hast für Projekte? Kann man die irgendwo(inet) bewundern ? :)

Mfg Cri

CriGri
07.10.2006, 12:52
Hi Leute!!!

Nochmals vielen Dank für eure Hilfe!!!!

Habe (fast ;) )Peters Routine genommen!



void Led_Muster(uchar zeich)
{
uchar i;
uchar mask = 0x80;

for(i=0;i<8;i++)
{
S1 = zeich & mask;
mask >>= 1;
CLK = 0; CLK = 1;
}
}

Habe am Anfang probs gehabt da ich zeich immer ein binäres Muster übergeben habe bis ich endlich geschnallt habe,dass ich HEX übergeben sollte.NU gehts :) !!!!

Also nochmals THX!!!

PS:nu is ein neues Prob vorhanden!habe schon nen Thread gemacht!!!!

Mfg Cri