Hätt mal ne Anfängerfrage. Wenn ich an einem Pin einlesen möchte ob da ne 1 oder 0 ankommt wie mach ich das im AVR Assembler? Kann ich da einfach schreiben: in r16,PinB6 zum Beispiel? Oder liest er wenn ich alle Pins als Ausgänge und nur den einen als Eingang gesetzt habe mit: in r16,PortB dann auch nur den einen Pin ein? Vielen Dank schonmal für eure Antworten!
Du liest den kompletten Port ein in r16, PinB In r16 sind dann die 8 Bits des Port abgebildet (sowohl Eingänge als auch Ausgänge). Mittels UND Operationen kannst Du dann gezielt einzelne Bits in r16 auf 0 setzen, sodass nur mehr der dich interessierende Eingang in r16 übrig bleibt.
Eine andere Möglichkeit ist im Tutorial beschrieben. http://www.mikrocontroller.net/tutorial/io-basics
Wenn du nur einen enzelnen Pin abfragen willst, kannst du auch SBIC oder SBIS verwenden. Die überspringen jeweils den nächsten Befehl, wenn das Bit gelöscht bzw. gesetzt ist. Wenn du IN verwenden willst, mußt du evtl. die gewünschten Portbits mit einem ANDI ausmaskieren.
Danke schonmal. Wie kann ich denn nun die ankommenden Bits in ein Register speichern? Also es kommt ne 0 oder 1 an,die speicher ich in ein Register und rotiere es um eine Stelle. Danach les ich das nächste Bit ein,speichern und rotieren...usw... Nach 8 mal (1 Byte) möchte ich den Wert als LOWByte Speichern und das HIGHByte einlesen. Die Daten kommen über SPI an MISO an.
Ich verstehe dein Problem nicht. Wenn du alle 8 Bit einlesen willst, tust du doch genau das mit: in r16,PinB Danach stehen in den 8 Bit von r16 die 8 Bit von PinB drin. Du mußt nicht 8 Mal den Port einlesen und jedes Mal nur ein Bit davon speichern.
Ja aber ich will ja nicht den gesamten PortB einlesen sondern nur den einen Pin MISO an dem ich Daten über SPI bekomme. Da bekomm ich bit für bit ein Byte welche ich einlesen möchte. oderichaufdemschlauchstehe
Oder Frage erstmal anderst gestellt. Wie kann ich ein Bit an die erste Stelle eines Registers speichern? Also z.B, bekomm ich ne 1,speicher die in ein Register. 00000001 So dann einmal rotieren: 00000010 Jetzt wieder an die erste Stelle das nächste Bit. Z.B. wieder ne 1: 00000011 Dann wieder rotiere....usw. Also wie kann ich auswählen das ein Bit immer an die erste Stelle eines Registers gespeichert wird? Werd langsam selbst ganz durcheinander :-)
Bin nicht besonders asm-bewandert, aber so sollte es gehen: Testen, ob SCK high ist. Ist SCK nicht high, weiter testen (SBIS ) Ist MISO low, dann überspringe die nächste Anweisung verodere das Register mit 1 rotiere das Regsiter inkrementiere den Bit-zähler wenn es schon 8 bit sind überspringe die nächste Anweisung springe zum SCK-Test mach das gleiche mit dem High-byte...
Jetzt kommt wieder das "guck doch ins Datenblatt" ;) Beim PIC hat sich das SPI-Register immer volltakten lassen und wenn die Übertragung fertig ist, liest man auf Schlag alle 8 Bit als Byte aus. Halt "normale" SPI-Übertragung. Ich habs nur kurz im AVR-Datenblatt nachgeschaut, das ist ähnlich. Wenn du doch eine SPI-Übertragung hast, würde ich das auch so wie im Datenblatt nutzen.
Hab jetzt noch die Befehle bst und bld gefunden. Damit kann ich das Bit am MISO in ein Register and die Stelle des ersten Bits speichern. Ich lese PortB in ein Register ein,speicher Bit 6 (MISO Leitung) an die erste Stelle eines anderen Registers und rotiere dieses dann. Das ganze achtmal und schon müsste ich das Byte haben. Kann dies jemand eventuell so bestätigen? :-)
Du hast leider nicht geschrieben, welchen Controller genau du verwendest, aber kannst du denn kein Hardware-SPI verwenden, statt das umständlich per Software zu machen?
Ach ja, ich hatte vergessen: Ja, mit BLD und BST ginge das. Erst mit IN einlesen, dann mit BST das Bit ins T-Flag kopieren und mit BLD ins Zielregister. Übrigens: Statt rotieren lieber ein shift, denn sonst mußt du vorher noch das carry-flag löschen.
Ja stimmt shift ist besser,danke! Werd mir aber die Hardware Lösung mal anschauen. hatte ich zwar schon jedoch dacht ich mir das es auf die "Software-Art" einfacher sein sollte aber naja.... Danke nochmal für Tipps bis hierher! Aso Controller ist ein Atmega8
Genau den Hardware-SPI-meinte ich auch. Mega8 Datenblatt S. 124. Natürlich kann man das auch zu Fuss machen ("Software-Art") , aber wenn die Funktion doch schon da ist, kann man die auch nutzen. Dann kan nman auch die durchaus sinnvollen Features wie End Of Transmission Interrupt Flag nutzten.
> hatte ich zwar schon jedoch dacht ich mir das es auf die > "Software-Art" einfacher sein sollte aber naja.... Glaubst du denn, die bauen extra dafür zusätzliche Hardware ein, damit es dann komplizierter wird, als eine Software-Implementation? Mit der Hardware ist es einfacher, weil du dich nicht selbst um die Bitschiebereien und das Timing kümmern mußt.
@ Rahul mir ist noch nicht aufgefallen, daß das Hardware-TWI buggy ist. Hast du dazu weitere nähere Informationen? Gruß Schmidle
> Naja, die TWI-Einhiet gilt ja als etwas "buggy"... Meines Erachtens ging es hier aber nicht um TWI sondern um SPI: > Die Daten kommen über SPI an MISO an. Hardware-SPI ist schon besser. Der Int meldet dir das neu empfangene Byte, in der ISR liest du es dann aus und schon bist du fertig. ...
@Markus: Peter Dannegger hatte mal von Problemen berichtet; ich weiß jetzt aber nicht mehr genau in welchem Zusammenhang.
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.