Hallo an alle, seit etwas über ein Jahr verfolge ich hin und wieder dieses Forum und heute habe ich mich dann doch noch angemeldet :) Habe heute die ersten Gehversuche mit meinem SKT500-Board und Assembler gemacht. Mein erster Code sollte diese Funktion haben: Betätigung Taster 0 -> LED3 ein Betätigung Taster 7 -> LED4 ein beide Taster betätigt -> beide LEDs ein würde mich freuen wenn ihr meinen Code mal anschaut und verbesserungsvorschläge hättet :) Beim Testen am STK500 kommt selten dieser Fehler: Ist einer der beiden Taster betätigt und wir der andere auch betätigt, sind beide LEDs kurz aus oder solange aus, bis ich die Taster (oder nur einen von beiden) loslasse und wieder betätige. Dann funktioniert es wieder einige male problemlos. Vielen Dank schon mal für eure Hilfe, Tips und Tricks :)
Juke Box schrieb: > Betätigung Taster 0 -> LED3 ein > Betätigung Taster 7 -> LED4 ein > beide Taster betätigt -> beide LEDs ein Für so etwas einen µC verwenden, ist wie mit Kanonen auf Spatzen schiessen. Umständlicher geht es wohl nicht mehr?
Was willst du Kevin? Ich versuche mir Assembler beizubringen und du versuchst am Sonntagabend einen auf dicke Hose zu machen!!? WIESO meldest du dich wenn du zu meinem Anliegen absolut nichts beitragen willst oder kannst??? Ich wollte einfach nur mal anfangen zu coden. Aller Anfang ist schwer. Bin froh dass ich mein Ziel gar nicht so schlecht erreicht habe. Hätte ich mir ein Ziel gesetzt, das für einen µc zugeschnitten ist, hätte ich heute sicher kein Code zustande gebracht, das funktioniert. Hat hier irgendwer noch Lust mein Prog anzuschauen und zu beurteilen, was man einfacher machen kann oder oder oder...??? Und du Kevin... lass die Hände schön über der Bettdecke wenn du gleich schlafen gehst!
Arbeite dich durch diesen Artikel durch (Stichwort: Tasten Entprellen): http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten
Man kann auch einzelne Bits testen, bzw setzen und löschen. Beitrag "sbr,cbr.sbrs,sbrc" cpi r16, 0b11111110;vergleiche Tasterkombination mit NUR Taster 0 gedrückt Da gibt es einen Befehl: sbrs (Skip if bit in Register is set) analog dazu sbrc (Skip if bit in Register is clear) Da wird der jeweils nächste Befehl übersprungen (skip). Das würde ich hier eher verwenden. Ansonsten passt das wohl schon, ohne es jetzt genau ausprobiert zu haben. Aber es gilt: Viele Wege führen nach Rom.
Danke Norbert! Werd ich mir anschauen. Kennst du dich sehr gut mit Assembler aus? Was kann ich im Code besser machen? Abgesehen jetzt von der Tatsache, dass hier mit Kanonen auf spatzen geschossen wird^^
Sehr gut Rainer :) werde mir auch diese Befehle anschauen und rumprobieren. Vielen Dank
Auch eine Lösung wäre. Käme ohne Vergleiche etc. aus. loop: IN r16,PINB ;einlesen AND r16,0b10000001 ;wichtige Bit Maskieren CLC ;Carrybit löschen ROR r16 ;Rollen durchs Carrybit 5 mal ROR r16 ROR r16 ROR r16 ROR r16 IN r17,PORTB ;Outport lesen AND r16,0b11100111 ;beeinflußte Bits löschen EOR r17,r16 ;XOR-Verknüpfen OUT PORTB,r17 ;Outport ausgeben RJMP loop oder loop: IN r16,PIND ;lade Tasterkombination in r16 IN r17,PORTB OR r17,0b00011000 SBRS r16,0 ;Überspringen des nächst.Befehls bei gesetzem Bit 0 CBR r17,3 ;Clear Bit 3 in Reg r17 SBRS r16,7 ;Überspringen des nächst.Befehls bei gesetzem Bit 7 CBR r17, 4 OUT PORTB, r17 RJMP loop Was sich dafür noch empfiehlt zu lesen ist http://www.atmel.com/images/doc0856.pdf Dieses Dokumemt zeigt eine Übersicht über die Assembler-Befehle und deren Wirkung.
oookay... danke schon mal Dennis ich sehe schon... es gibt sehr viel zu lernen :) werd morgen gleich mal eure vorschläge genauer anschauen und hoffentlich auch einen guten tag haben wie heute
MoinMoin, ich hätte da ein paar Vorschläge =). 1. Lass dich von solchen Beiträgen wie dem vor mir nicht davon abhalten weiterzumachen, jeder fängt mal klein an, und natürlich ist simple LEDs an und aus machen nicht DAAAAS Metier wo man unbedingt nen µC braucht, aber wie gesagt, irgendwomit muss man ja anfangen. und nun zu deinem Code. Ich würde in deiner Loop direkt abfragen, ob auch beide Tasten gedrückt sind. Also quasi so:
1 | loop: in r16, PIND ; lade Tasterkombination in r16 |
2 | |
3 | cpi r16, 0b11111110 ; vergleiche Tasterkombination mit NUR Taster 0 gedrückt |
4 | breq LED3_on ; Springe zu LED3_on |
5 | cpi r16, 0b01111111 ; verlgeiche Tasterkombination mit NUR Taster 7 gedrückt |
6 | breq LED4_on ; Springe zu LED4_on |
7 | cpi r16,0b011111110 |
8 | breq LED34_on |
9 | rjmp loop |
dann kannst du dir nämlich in deiner LED3_on und LED4_on die Abfrage sparen. Als nächstes ist mir aufgefallen, das du deine LEDs genaugenommen nicht einschaltest, wenn du die Taste drückst, sondern (wenn auch sehr schnell) blinken lässt. Evtl kann man das in eine LED_on und eine LEDoff splitten, die dann je nachdem was gedrückt ist, aufgerufen werden. Dann müsstest du aber davon abrücken, jeweils den ganzen PortD abzufragen, welche Tasten gedrückt sind, sondern maskierst dir deine Bits für den jeweiligen schalter aus. also quasi so:
1 | StartLED: |
2 | |
3 | in r16,PortD |
4 | andi r16,0b00000001 (evtl auch nur and und den binären Wert in nen Register laden, bin grad unsicher obs andi gibt *gg.) |
5 | sbrc r16,1 (kann auch sbrc r16,0 sein, bin grad unsicher ob bei sbrc das bit oder die Wertigkeit angegeben wird, |
6 | lange nix mehr mit assembler gemacht) |
7 | rcall LED3_off |
8 | sbrs r16,1 |
9 | rcall LED3_on |
10 | |
11 | in r16,PortD |
12 | andi r16,0b10000000 |
13 | sbrc r16,128 |
14 | rcall LED4_off |
15 | sbrs r16,128 |
16 | rcall LED4_on |
17 | |
18 | in r16,PortD |
19 | andi r16,0b10000001 |
20 | sbrc r16,129 |
21 | rcall LED34_on |
22 | sbrs r16,129 |
23 | rcall LED34_on |
24 | |
25 | rjmp Start_LED |
26 | |
27 | LED3_on: |
28 | ldi r16,0b11111110 |
29 | out PortB,r16 |
30 | ret |
andi (and imediate) macht eine bitweise Verknüpfung des Registerwertes mit dem Wert der da steht. Damit maskierst du dir deine Bits aus, um die es dir geht. sbrc (skip if bit in register is cleared) überspringt den nächsten Befehl, wenn die ausmaskierten Bits null sind. Also wenn dein Taster gedrückt ist, liefert er dir ne 0, also wird der Befehl zum LED auschalten übersprungen. sbrs macht das gleiche nur andersrum. rcall springt zu der entsprechenden Sprungmarke, also ähnlich wie dein breq, mit dem Unterschied, das er sich beim call/rcall merkt, von wo er gesprungen ist, und kehrt danach wieder dorthin zurück. Deshalb musst du auch den Stackpointer initialisieren, dort "merkt" sich dein µC nämlich, wo er herkam. Mit ret in LED3_on springst du dann zurück. Damit umgehst du dann auch das Problem, das sich dir wahrscheinlich gestellt hat, als du die Abfrage ob beide gedrückt sind, in deine LED3/LED4_on getan hast. Nämlich wenn Taster0 gedrückt, würde er bei dir ja nicht weiter nach den anderen Tasten fragen. Und mit rcall umgehst du das Problem ganz einfach, indem du einfach dort weitermachst, wo du herkamst. Wichtig, wenn du mit rcall arbeiten möchtest, ist den Stackpointer zu initialisieren ;stackpointer initialisieren ldi r16,low(ramend) out spl,r16 ldi r16,high(ramend) out sph,r16. Ich hoffe, damit ist dir erstmal ein wenig geholfen und wünsch dir viel Spass beim Basteln MfG Chaos
Da war ich schon etwas umnachtet. SBRS muß SBRC sind. loop: IN r16,PIND ;lade Tasterkombination in r16 IN r17,PORTB OR r17,0b00011000 SBRC r16,0 ;Überspringen des nächst.Befehls bei gelöschtem Bit 0 CBR r17,3 ;Clear Bit 3 in Reg r17 SBRC r16,7 ;Überspringen des nächst.Befehls bei gelöschtem Bit 7 CBR r17, 4 OUT PORTB, r17 RJMP loop Gruß Dennis
Hi Ich hätte da noch eine Quelle für dich, die dir zusätzlich zum Tutorial, welches du hier findest, ein wenig weiterhelfen könnte. Schau mal bei AVR-Praxis-Forum rein. Dort findest du unter der Rubrik FAQ einen Beitrag: Keine Angst vor Assembler. Da steht so ein bischen was drin. Gruß oldmax
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.