Forum: Mikrocontroller und Digitale Elektronik Byte seriell ausgeben


von mr.chip (Gast)


Lesenswert?

Hallo

Wohl ein relativ triviales bzw. alltägliches Problem: Wie kann ich ein
Byte am effizientesten seriell ausgeben? D.h. ich habe ein Byte, und
dieses wird nun Bit für Bit an einem Port ausgegeben. Wie macht man
sowas effizient - es würde mich sowohl AVR-Assembler als auch C
interessieren.

Gruss

Michael

von Laeubi (Gast)


Lesenswert?

angenommen bei einer low to high transistion werden die daten
übernommen:

push temp
push counter
ldi counter, 8
_loop:
clock_low
daten_low
shiftleft temp
skip_if_carry_is_not_set
daten_high

clock_high
dec counter

branch_not_null _loop

pop counter
pop temp

(das wäre jezt so meine Idee)

von mr.chip (Gast)


Lesenswert?

Hallo

Ja, das mit dem Schieben hört sich schonmal nicht schlecht an! Ich
glaube, in AVR-Assembler heisst der Befehl doch irgend was mit
'rotate' - rotieren ist ja im Prinzip das selbe. Nur finde ich leider
keinen C-Operator (?) zum schieben.

Gruss

Michael

von Rahul (Gast)


Lesenswert?

">>" Rechtschieben
"<<" Linksschieben

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

Fertich...

von Laeubi (Gast)


Lesenswert?

ne da heist das shl (shift left) benötigt wird heir der Arithmetische
Shift!

in C ist der ShiftOperator  >> aber heir muß man vorsichtig sein ob der
logische oder arithmetische Shift gemacht wird! (kann ggf das ergebnis
unerwartet verändern!

von mr.chip (Gast)


Lesenswert?

Arithmetisch oder Logisch? Ihr verwirrt mich ;-)

Naja, heisst dann wohl ausprobieren.

von Werner B. (Gast)


Lesenswert?

>Arithmetisch oder Logisch?

Hinweis: Probiere das mit negative Zahlen aus, dann findest Du den
Unterschied schneller ;-)

von Laeubi (Gast)


Lesenswert?

Du kannst in diesem Falle beides verwenden.

Logischer Shift bedeutet, was rausgeschoben wird "fällt raus" (bzw in
das Carry) und es wird immer eine 0 "reingeschoben".

Arithmetischer Shift bedeutet, was rausgeschoben wird, wird dann wieder
"reingeschoben" (sozusagen alles immer im kreis) (Meist nur beim
Rechtsshift! Linksshift bekommt auch hier eine "0")

Rotieren bedeutet, das Carry wird "reingeschoben" und was raus fällt
ins Carry übertragen.

Dies kann aber ggf. abweichen je nach Programmiersprache!

In C z.B. ist es so, das der Shift nach links ein "logischer" ist,
der Shift nach rechts meist ein Arithmetischer!

Das Instruction Set zu AVR sagt:
LSL Rd Logical Shift Left Rd(n+1) &#8592; Rd(n), Rd(0) &#8592; 0
 Also Shift nach Links, 0 wird reingeschoben, Carry bleibt
unbeeinflußt.

LSR Rd Logical Shift Right Rd(n) &#8592; Rd(n+1), Rd(7) &#8592; 0
 Also Shift nach Rechts, 0 wird reingeschoben, Carry bleibt
unbeeinflußt.

ROL Rd Rotate Left Through Carry Rd(0)&#8592;C,Rd(n+1)&#8592;
Rd(n),C&#8592;Rd(7)
 Shift nach Links, Cary wird reingeschoben, erstes Bit kommt ins Carry

 ROR Rd Rotate Right Through Carry Rd(7)&#8592;C,Rd(n)&#8592;
Rd(n+1),C&#8592;Rd(0)

 Shift nach Rechts, Cary wird reingeschoben, leztes Bit kommt ins
Carry
 ASR Rd Arithmetic Shift Right Rd(n) &#8592; Rd(n+1), n=0..6
Shift nach Rechts, Carry bleibt unbeeinflußt das Rausgeschobene Bit
wird Links "drangesezt"

von Bjoern M. (salival)


Lesenswert?

Wie waere es, die SPI-Schnittstelle zu benutzen? OK, dann geht es nicht
an nem beliebigen Portpin, aber dafuer schneller als in Software.

gruss, bjoern.

von mr.chip (Gast)


Lesenswert?

> Wie waere es, die SPI-Schnittstelle zu benutzen? OK, dann geht es
nicht an nem beliebigen Portpin, aber dafuer schneller als in
Software.

Eine Idee wäre es. Allerdings ist das empfangende Gerät ein M64282FP
(Bildwandlerchip der Gameboy-Kamera). Es sind 8 Bytes zu übertragen,
denen jeweils 3 Bit Adressinformation vorausgehen. Das ganze kann mit
500 kHz geschehen, aber auch deutlich langsamer. Naja, die 8 Bytes + 24
Bit kann ich auch etwas langsamer verkraften ;-)

von Joe (Gast)


Lesenswert?

">>" Rechtschieben | das ist links
"<<" Linksschieben | das ist rechts

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

@ Rahul, haste das mal auf einem Osci. gesehen ?

von Laeubi (Gast)


Lesenswert?

@mr Chip
bei 500khz kann der AVR auch "ineffizent" das Bit rausschieben :D
Da langweilt der sich doch nur :)

von Bjoern M. (salival)


Angehängte Dateien:

Lesenswert?

"Eine Idee wäre es. Allerdings ist das empfangende Gerät ein M64282FP
(Bildwandlerchip der Gameboy-Kamera)."
Japp, der kann auch bedeutend langsamer. Sag Bescheid, wenn du das mit
den Registern hinbekommen hast. Ich hatte da so meine Probleme, um
passable Einstellungen zu finden.

gruss, bjoern.

von Rahul (Gast)


Lesenswert?

@Joe: War da irgendwas von "es soll schön aussehen" geschrieben?

von Rahul (Gast)


Lesenswert?

x=1;
for(n=0;n<7;++n)
{
 if (y & x)
 portpin an;
 else
 portpin aus;
 x *=2;
}

besser so?

von mr.chip (Gast)


Lesenswert?

> Japp, der kann auch bedeutend langsamer.

Weisst du zufällig, wie langsam?

von Bjoern M. (salival)


Angehängte Dateien:

Lesenswert?

"Weisst du zufällig, wie langsam?"

Ich glaube, da hab ich mich zu weit aus dem Fenster gelehnt. Soweit ich
meinen alten Sourcecode auf die Schnelle durchschaut hab, hab ich keine
Wartezeiten eingebaut und einfach nur dem Protokoll entsprechend einen
Schritt nach dem Anderen ausgefuehrt.
Ich hab ihn mal angehaengt, vielleicht hilft er dir irgendwie weiter.
Der Mega8 lief auf 8Mhz und der Ram war mit Schieberegistern
angebunden.

gruss, bjoern.

von Bjoern M. (salival)


Lesenswert?

Oh ich seh grad, die Inputs der GBCam waren auch mit am Schieberegister.
Also gab es doch erhebliche Wartezeiten...

von Bjoern M. (salival)


Lesenswert?

Und ums vollstaendig zu machen, hier noch Bilder vom Aufbau:
http://www.lania.de/salival/bilder/gbcam

gruss, bjoern.

von Bjoern M. (salival)


Lesenswert?

So, ich hab meinen Code wieder halbwegs durchschaut, und ich hab mich
scheinbar doch nicht zu weit rausgelehnt. Der Chip wird im Takt der
AD-Wandlung angesteuert. Diese laeuft bei 8Mhz mit Prescaler 64 im
Free-Running-Mode. Ergibt ca 9,6kHz und damit deutlich weniger als die
maximalen 500kHz.

gruss, bjoern.

von Profi (Gast)


Lesenswert?

@Rahul:
oder so:

unsigned char x=1;
do
  if (y & x)
    portpin an;
  else
    portpin aus;
  while(x*=2);

Der Clou ist, dass x "Zähler" und Maske in einem ist.

von mr.chip (Gast)


Lesenswert?

@Björn Müller:

Danke für den Code! Ich konnte ihn ganz gut gebrauchen für meine eigene
Implementation, da er deutlich mehr aussagt als das magere Datenblatt!

Ich glaube sogar, es funktioniert auch - die Kamera reagiert nämlich
auf die eingestellte Belichtungszeit. Doch leider misst der ADC nur 0 0
0 0 0 0 0 ..... 0 0 0 Der Vout Pin der Kamera habe ich direkt an den
ADC-Eingang des AVR angeschlossen, ohne jegliche Zusatzbeschaltung.

Ob dies wohl an den Kamera-Register-Einstellungen liegt? Ich verwende
bisher Einstellungen von einer anderen Webseite. Werde es dann evtl.
mal mit deinen versuchen, die sollten doch gehen?

von mr.chip (Gast)


Lesenswert?

Uuups...das mit dem 'Alles 0 0 0 0 0' war ein ganz dämlicher Fehler
meinerseits. Immerhin bin ich jetzt soweit, dass ein verrauschtes
'Pixelmuster' herauskommt. Mit einem Bild hat dies noch wenig zu
tun... Register?

von mr.chip (Gast)


Lesenswert?

Noch interessanter: Das Pixelmuster ist immer exakt das selbe, egal
wie ich die Kamera halte, selbst nach einem kompletten Reset des ganzen
Systems (= Strom weg & PC-Programm neu gestartet)

von Bjoern M. (salival)


Lesenswert?

Wiegesagt, passende Registereinstellungen zu finden, ist das grosse
Problem. Die einzelnen Einstellungen beeinflussen sich teilweise
gegenseitig und bei unpassenden Einstellungen kommt nur Muell raus. Am
besten waere es, alle Register per GUI vom PC aus einstellen zu
koennen, und die Veraenderungen direkt zu vergleichen. Das waere bei
mir der naechste Schritt gewesen, ich hab die PC-Software aber nie
fertig geschrieben.
Auf irgendner Page gabs auch Code mit automatischer Belichtung.

Es koennten natuerlich auch Timingprobleme sein.

Ach ja, folgende Seite kennst Du? Auf deren Basis hab ich die
Ansteuerung programmiert:
http://www.angelfire.com/de3/juliprograms/amr/gbcam.htm

gruss, bjoern.

von mr.chip (Gast)


Lesenswert?

Jep, die Seite kenne ich - ist ebenfalls meine Grundlage.

Mit deinen Einstellungen habe ich jetzt erste Ansätze eines Bildes
entdecken können! Als nächstes schreibe ich jetzt mal kurz ein GUI für
die Einstellungen, dann kann ich trial-n-error einfach ausprobieren.

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
Noch kein Account? Hier anmelden.