Hallo, ich bastle derzeit an einem Testgerät für Kabelbäume und versuche damit auch erst mal in die Assemblerprogrammierung rein zu kommen. Ich habe einen Draht (später eine Ader des Kabelbaums) zwischen PA0 und PB0. PA0 möchte ich nun auf High schalten und an PB0 wieder einlesen. So kann ich nach und nach die Ports durchschalten damit ich sichergehen kann dass die einzelnen Adern auch in der richtigen reihenfolge auf den Steckern sitzt... Nur irgendwie schaffe ich es nicht das Programm richtig zu schreiben. PB0 gegen Masse lässt meine LED (ende:) schon mal leuchten. Hier nun mein bisheriger Code, der Controller ist ein atmega32. .include "m32def.inc" .def temp = r16 taster_lesen: ldi temp,0b11111111 out DDRD,temp in temp,PIND cpi temp,0b00010000 ; taster für start breq start rcall taster_lesen rjmp start start: ldi temp,0b00000000 out DDRA,temp ldi temp,0b11111111 out DDRB,temp rjmp check1 check1: ldi temp,0b00000001 out PORTA,temp in temp,PINB cpi temp,0b00000001 breq ende rcall fehler fehler: ldi temp,0b00100000 out PORTD,temp rjmp check1 ende: ldi temp,0b01000000 out PORTD,temp rjmp ende vielleicht hat ja einer von euch eine Idee, bedanke mich schonmal!! MfG Daniel
Sorry, habe mich oben vertan: > Nur irgendwie schaffe ich es nicht das Programm richtig zu schreiben. > PB0 gegen Masse lässt meine LED (ende:) schon mal leuchten. Es ist natürlich PB0 gegen 5V.
Am besten, du schreibst ganz konkret, was nicht so funktioniert, wie vorgestellt. Dann muss man nicht erst deinen ganzen Code verstehen, sondern kann gezielt suchen.
.include "m32def.inc" .def temp = r16 auch wenn du den stack im Moment nicht unbedingt brauchst, solltest du ihn initialisieren. taster_lesen: ldi temp,0b11111111 out DDRD,temp Das ist ja wohl Mist! Das solltest du schon als Eingang schalten, mit internem pullup, falls nicht extern einer dranhängt. in temp,PIND cpi temp,0b00010000 ; taster für start Ob das so richtig ist, kann dir keiner ohne deine Schaltung sagen, eher nicht. Besser ist es sowieso, nur auf die entsprechenden einzelnen Pins zu reagieren, nicht auf den ganzen Port. Also entweder maskieren oder direkt sbis/sbic verwenden. Irgendwann bastelst du was an den PortD dran, dann funktionierts so wie du es machst nicht mehr. breq start rcall taster_lesen Das ist ein dicker Hund, rcall ist hier ganz fehl am Platz. Der SP macht nicht halt am Ende des Rams, sondern überschreibt dir auch den I/O-Bereich und die Register. brne taster lesen würde reichen rjmp start wozu dieses? start: ldi temp,0b00000000 out DDRA,temp ldi temp,0b11111111 out DDRB,temp rjmp check1 und dieses? check1: ldi temp,0b00000001 out PORTA,temp in temp,PINB cpi temp,0b00000001 das kann bei längeren Leitungen schon zum Problem werden, kleine Warteschleife einfügen. breq ende Und dasselbe Problem wie oben, du setzt stillschweigend voraus, dass die anderen Pins l-Pegel haben, warum? rcall fehler und wieder ein unmotivierter rcall... fehler: ldi temp,0b00100000 out PORTD,temp rjmp check1 ende: ldi temp,0b01000000 out PORTD,temp rjmp ende Das Ganze ist kein Programm, sondern Murks...:-) Hast du schon jemals ein funktionierendes Programm für einen AVR geschrieben? Ich glaube nicht. Aber lass dich nicht entmutigen, dass wird schon.
Hi Kurty Am besten ist es, man definiert am Anfang einmal welcher Pin Eingang und welcher Ausgang wird, und nicht irgendwo nach Lust und Laune im Programm. Das bleibt übersichtlicher: ldi temp, 0b11111111 out DDRD, temp Wichtig: Eingänge werden mit 0 definiert, Ausgänge mit 1 >taster_lesen: > ldi temp,0b11111111 > out DDRD,temp > in temp,PIND Hier definierst du den Port D als Ausgang, versuchst dann aber einen Schalter einzulesen. Dass das nicht ganz funktionieren kann ist ja klar. (Pin auf Ausgang + Pin gewaltsam auf ein Potential zeihen...) > cpi temp, 0b00010000 ; taster für start > breq start bedenke, dass nur zu "start" gesprungen wird, wenn AUSSCHLIESSLICH PinD, 4 ein ist. Alle anderen Pins müssen Null sein, sonst wird nicht gesprungen. Besser wäre für sich wohl SBIS (Skip if Bit in I/O Register Set) > rcall taster_lesen > rjmp start Wenn an deinem Pin keine eins anliegt wird das ausgefürht. Dabei springst du mit dem rcall wieder an den Anfang. rcall ist eigentlich so gedacht: Man ruft eine Unterroutine auf, und beendet diese mit ret. Dadurch macht dann der Controller beim nächsten befehl nach dem rcall weiter. Die Adresse wo er weiter machen muss speichert er natürlich bevor er zum Unterprogramm springt. Dein Programm lässt den Controller jetzt wieder an den Anfang springen, wieder überprüfen ob der Taster gedrückt ist und dann wieder an den Anfang springen. Das gibt binnen kürzester Zeit probleme im Speicher. Was mir gerade einfällt: Du hast den Stackpointer garnicht initialisiert. D.h. dass du sowieso probleme bekommst. Das beste ist wohl, wenn du dir mal das AVR-Tutorial anschaust. Link ist oben Links. >start: ldi temp,0b00000000 > out DDRA,temp > > ldi temp,0b11111111 > out DDRB,temp >rjmp check1 Zum ein/Ausgänge definieren hab ich ja schon was gesagt. Du hasts halt wieder falschrum definiert. >check1: ldi temp,0b00000001 > out PORTA,temp > > in temp,PINB > cpi temp,0b00000001 > breq ende > rcall fehler Der Teil sollte soweit funktionieren wie ich denke dass du es wolltest. >fehler: ldi temp,0b00100000 > out PORTD,temp > rjmp check1 Wenn du im Port D einen Pin als Ausgang statt als eingang haben willst, dann musst du das am anfang so definieren. Also z.B. ldi temp, 0b10011111 macht alle pins von PortD zu Ausgängen ausser Pin5 und Pin6 >ende: ldi temp,0b01000000 > out PORTD,temp > rjmp ende Wieder das gleiche. Port D richtig definieren. Ganz nebenbei: Man kann Ausgänge auch einzeln setzten und löschen. Viel Spass mit dem Tutorial Sebastian
Also meine ersten Assembleranfänge vor einem Jahr sahen auch so ähnlich aus und kann ich nen t6963 mit assembler zu steuern, also das wird schon. Wichtig ist nur das du verstehst, was du codest, d.h. schleife für schleife durchgehen und verstehen. Wie ich sehe hast du große Probleme mit den Sprüngen: 1) lerne den unterschied zwischen rcall und rjmp. Dazu ist es notwenig den stack zu verstehen und die ram adressierung. Ohne dieses Know how kann man etwas fortgeschrittenere Assemblercodes nicht verstehen! 2) rcall und rjmp sind nur die befehle zum springen, nicht um an diesen ort hinzukommen. beispie rjmp start start: ldi temp,0b00000000 entspricht clr temp ldi temp,0b11111111 entspricht ser temp ist völlig für die Katz, der Programmcounter wird nach jedem Command um eins inkrementiert (+1), wenn es kein sprung ist. Ganzzz primitiv erklärt: du sagst dem PC wenn er sich bei rjmp start bei z.b. 1 befindet er soll zu 2 springen, obwohl er sich ja eh nach dem Befehl um eins inkrementieren würde. Ende des liedes: rjmp start kannst du dir hier sparen. Habe mir jetzt dein Programm nicht weiter angesehen nur so viel: es empfiehlt sich active low zu schalten. D.h. standartmäßig den Pin auf 5v halten und sobald der taster gedrückt ist diesen pin auf gnd zu ziehen (pullup widerstand nicht vergessen, da du sonst nen kurzen hast). Außerdem prellen taster gewöhnlich aber dazu gibts genug im Internet zu lesen :) Ich kann dir das Buch Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie ans Herz legen. Wenn du das durchgearbeitet hast (die 35 euro sind wirklich gut investiert) bist du auch für andere controller gewappnet.
Wenn das wirklich ein Leitungstester werden soll, dann mußt Du auch mit Kurzschlüssen rechnen. Also immer nur einen Ausgang auf low und die anderen auf inaktiv (Eingang), sonst kommt es zu Datenkämpfen (Low gegen High) und das ist ungesund für den AVR. Und die Eingänge mit internen oder externen Pullups, damit offen = High. Peter P.S.: Ich hab mal nen Leitungstester für 40-pol. Kabel in C geschrieben mit 3 Stück AT89S8252 um auf die Pinzahl zu kommen. Verbunden sind sie über die UART.
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.