Hallo Leute, ich habe da ein Problem, ich bin noch ganz in den Anfängen und wollte nun mit zwei tastern zwei led's zum leuchten bringen, und eine dritte soll die ganze zeit leuchten aber irgendwie klappt das nicht. die led's liegen am Port: B0, B1 und B2 die taster an: D2 und D3 die Taster schalten auf Masse wenn man sie drückt. Ich wollte dann also die LED Ports auf ausgänge schalten und die Taster Ports auf eingang mit entsprechendem PullUp. das ganze übrigens in -Assembler- So jetzt wollte ich erst mal mit einem schalter anfangen, jetzt hab ich das problem dass das board garnicht auf den schalter reagiert und die led sofort leuchtet? hier der code, danke schon mal .include "4433def.inc" ;----------------------------------------------------------------------- - ;Reset and Interrupt vector ;VNr. Beschreibung rjmp main ;1 POWER ON RESET reti ;2 Int0-Interrupt reti ;3 Int1-Interrupt reti ;4 TC2 Compare Match reti ;5 TC2 Overflow reti ;6 TC1 Capture reti ;7 TC1 Compare Match A reti ;8 TC1 Compare Match B reti ;9 TC1 Overflow reti ;10 TC0 Overflow reti ;11 SPI, STC Serial Transfer Complete reti ;12 UART Rx Complete reti ;13 UART Data Register Empty reti ;14 UART Tx Complete reti ;15 ADC Conversion Complete reti ;16 EEPROM Ready reti ;17 Analog Comparator reti ;18 TWI (I²C) Serial Interface reti ;19 Store Program Memory Ready ;----------------------------------------------------------------------- - ;Start, Power ON, Reset main: ;ldi r16,0x00 ;out DDRD,r16 ldi r16,0xFF out DDRB, r16 ; Port B als Ausgang cbi DDRD,2 cbi DDRD,3 sbi PORTD, 2 ; Pullup sbi PORTD, 3 ;----------------------------------------------------------------------- - mainloop: wdr sbi PORTB, 2 ldi r17, PIND2 sbrs r17,0 sbi PORTB, 0 ;ldi r17, PIND3 ;sbrs r17,0 ;sbi PORTB, 2 rjmp mainloop
main: ;ldi r16,0x00 ;out DDRD,r16 Diese Befehle werden nicht ausgeführt ! und warum ?
ja das is klar die wollte ich erst mal ausgrenzen um den fehler zu suchen ich wollte das ja hiermit dann manuell machen cbi DDRD,2 cbi DDRD,3 sbi PORTD, 2 ; Pullup sbi PORTD, 3
Hi, bin selber schon seit 2 Jahren Anfänger(ich schäm mich ja). Ich glaube das mit ->ldi r17, PIND2<- is nicht korrekt. Es sollte so aussehen ->in r17, PinD2<- und wenn man auf Port schreiben will dann out ->PortX,rx<-
cbi DDRD,2 cbi DDRD,3 ist nicht nötig, ich weiss nicht ob das funktioniert ,cbi sbi ich glab das geht nur mit den Portregistern. Besser über ein Register einstellen also : ldi r16,0 out ddrd,r16 WDR ist nicht nötig weil Du den Watchdog nicht brauchst. Ich würde es so machen: ldi r16,0 out ddrd,r16 ;port d als eingang ldi r16,0xff our ddrb,r16 ;portb als ausgang sbi portb,2 ;led2 an vonanfang: sbic PIND, 2 ;nächsten Befehl überspringen,wenn Bit 2 im IO-Register PIND =0 rjmp led0aus sbi portb,0 ;leb an taste2: sbic PIND, 3 nächsten Befehl überspringen,wenn Bit 3 im IO-Register PIND =0 rjmp led1aus sbi portb,1 rjmp vonanfang led1aus: cbi portb,1 rjmp vonanfang led0aus: cbi portb,0 rjmp taste2 Viel Erfolg !
;Hi ich täte das in etwa so realisieren: ;I/O festlegen ldi r16,0b00001100 out DDRD,r16 ; PortD Pin 2,3 Input ldi r16,0b0000 0111 out DDRB,r16 ; PortB Pin 0,1,2 Output main: in r17,PinD ;PinD2,3 andi r17,0b00001100 ;Pin2,3 mit Logisch "1" verknüpfen sbi r17,1 ; je nachdem wo deine dauerhaft leuchtende LED hängt out PortB,r17 rjmp main gtf ;(go to forest) mein eigener Befehl. Der funktioniert auch!!!! ->AVR- Tutorial<- "http://www.mikrocontroller.net/tutorial" - Das ist sozusagen das große Buch wo alles drin steht!! - Ein muß für jeden Anfänger MFG dotstyler_321
hallo danke, ich habs ausprobiert, dann ist aber doch gar kein pullup widerstand aktiviert? da brauch ich nur dran wackeln dann flackern die led's auf oder ab
Achtung Semikolon vergessen ! sbic PIND, 3 ;nächsten Befehl überspringen,wenn Bit 3 im IO-Register PIND =0
wenn ichs so mache funktioniert einer der schalter und schaltet dann die led von 1-0-1 auf 0-1-0. so rein von meiner logik her müsste ich doch dann das pinb durch pinb4 ersetzen wenn ich will dass anstatt dem ersten der zweite schalter das macht, dann is aber schicht im schacht. also ich hab jetzt mal alles an einen port gelegt. led: b1,b2,b3 taster: b0,b4 main: cbi ddrb, 0 ;eingang cbi ddrb, 4 sbi portb, 0 ;pullup sbi portb, 4 ;pullup sbi ddrb, 1 ;ausgang sbi ddrb, 2 sbi ddrb, 3 mainloop: ldi r16, 0b00001101 in r17, pinb sbrs r17, 0 ldi r16, 0b00000011 out portb, r16 rjmp mainloop
wenn du an PortB das Bitmuster 00001101 ausgibst, dann passieren mehrere Dinge: Der Port ist ja so eingestellt: 00001110 (das ist das Ergebniss deiner diversen cbi und sbi) eeeeaaae ( e steht fuer Eingang, a steht fuer Ausgang) so, gibst du jetzt 00001101 aus eeeeaaae 00001101 dann wird ueberall wo ein e über einer 0 steht der Pullup ausgeschaltet. Ein e über einer 1, schaltet den Pullup ein, während alles was unter einem a steht als Ausgang rausgeschaltet wird. d.h. Das Bitmuster sorgt dafür, dass * am Pin B - 4 der Pullup ausgechaltet wird * am Pin B - 0 der Pullup eingeschaltet bleibt * am Pin B - 1 eine 0 am Ausgang erscheint * an den Pins B - 2 und B - 3 eine 1 am Ausgang erscheint. Da du den Pullup auf B-4 ausschaltest, wird dein Taster an diesem Pin nachher nicht mehr richtig funktionieren. > so rein von meiner logik her müsste ich doch dann das pinb > durch pinb4 Wie du auf diese Logik kommst ist mir rätselhaft. Du arbeitest mir ein bischen zu viel auf Bit-Ebene an den Ports. Mittels 'in' kannst du nur den ganzen Port einlesen, so wie er grade eingestellt ist. Was du aber möchtest ist, du möchtest das Bit Nummer 4 in dem was du vom Port gelesen hast (und was jetzt im Register r17 steht) testen. Also sbrs r17, 4 "Skip next instruction if bit #4 is set in register 17" "Überspringe die nächste Anweisung, wenn Bit #4 in R17 gesetzt ist" Aber: Das ganze ist doch eigentlich im Tutorial ganz gut beschrieben. Hast Du da mal reingeschaut?
ich arbeite mit dem myavr leerbuch, aber ich glaub ich hab jetzt von dir verstanden wo das problem liegt, dass ich erst in nen register laden muss welchen pin er abfragtund dann den ganzen port abfragen und das dann nochmal für den anderen, ich werd morgen mich nochmal dran setzen wenn mein kopf wieder klarer ist, jetzt hab ich soviel schon probiert, da mach ich heute eh nix mehr richtiges.
> dass ich erst in nen register laden > muss welchen pin er abfragtund dann den ganzen port > abfragen und das dann nochmal für den anderen, Genau anders rum: Du liest den ganzen Port in ein Register ein und testest dann in diesem Register welche Bits gesetzt waren oder eben nicht gesetzt waren. Das Register enthält eine Kopie des kompletten Portzustandes. Im Grunde ist es ganz simpel. Geh mal (gedanklich) einen Schritt zurück und vergiss mal all die cbi, sbi, und wie sie alle heissen. Mach dir einen Plan. Was soll passieren? 0) die Ports entsprechend initialisieren 1) die LED an B-1 einschalten 2) den B Port einlesen 3) Im Eingelesenen das Bit 0 testen Ist es gesetzt, dann die LED an B-2 einschalten Wenn nicht, dann die LED an B-2 ausschalten 4) Im Eingelesenen das Bit 4 testen Ist es gesetzt, dann die LED an B-3 einschalten Wenn nicht, dann die LED an B-3 ausschalten 5) Weiter gehts mit Schritt 2 (und damit endlos dahin) So, dass ist dein Plan. So sollte das ganze ablaufen. Wenn Du selbst Computer spielst und das ganze durchläufst, kannst du dich davon überzeugen, dass es das Gewünschte macht. Kümmern wir uns jetzt etwas mehr um die Details: 0) die Ports entsprechend initialisieren Hmm. Wie muessen die stehen? Wir brauchen an B die Pins 0 und 4 als Eingang; 1, 2, 3 als Ausgang. Die restlichen Pins (5, 6, 7) definieren wir der Einfachheit halber ebenfalls einfach als Eingang. d.h. wir brauchen ein Steuerwort von 0b00001110 in DDRB. Was ist mit den Pullups? Klar wollen wir! An den beiden Eingangspins B0 und B4. Das entspricht einem Bitmuster von 00010001 das an PORTB ausgegeben werden muss, damit die Pullups aktiv werden. Ungluecklicherweise werden dadurch die Ausgangspins alle auf 0 gezogen, aber das soll uns im Moment nicht weiter stören. Der Programmteil lautet daher ldi r16, 0b00001110 out DDRB, r16 ldi r16, 0b00010001 out PORTB, r16 1) die LED an B-1 einschalten das ist leicht. Ich weiss zwar nicht, wie du deine LED angehaengt hast, aber ich rate mal: LED gegen Vcc verschaltet. d.h. eine 0 am Port bringt die LED zum leuchten. damit bedeutet diese Aufgabe: stelle sicher dass an B-1 eine 0 ausgegeben wird. Oder in Code cbi PORTB, 1 2) den B Port einlesen das ist leicht. Alles was du brauchst ist ein Register, dass den Zustand des kompletten B-Ports (und damit den Zustand der beiden Input-Pins) aufnimmt. Entscheiden wir uns für Register 17 in r17, PINB (Achtung: beliebter Fehler. Beim rausschreiben heisst es PORT, beim reinlesen heisst es PIN !) 3) Im Eingelesenen das Bit 0 testen Ist es gesetzt, dann die LED an B-2 einschalten Wenn nicht, dann die LED an B-2 ausschalten Wie testet man ein Bit? Da gibt es mehrere Möglichkeiten. Aber ich will das benutzen was du schon kennst: sbrs Also: mittels sbrs testen wir das Bit. Ist es gesetzt, dann wird die nächste Instruktion übersprungen, ansonsten wird sie ausgeführt. Wir machen das so: Ist das Bit nicht gesetzt dann springen wir zum Programmcode der die LED ausschaltet. Ist das Bit gesetzt, dann unterbleibt dieser Sprung (da ja die Anweisung vom sbrs uebersprungen wird) und es folgt direkt der Code, der die LED einschaltet. sbrs r17, 0 ; Bit 0 gesetzt ? rjmp LED_0_AUS ; ja: weiter gehts beim Ausschalten cbi PORTB, 2 ; nicht gesetzt, schalte LED ein rjmp LED_0_ENDE ; Das wars, LED 0 ist behandelt LED_0_AUS: sbi PORTB, 2 LED_0_ENDE: Soweit so gut. 4) Im Eingelesenen das Bit 4 testen Ist es gesetzt, dann die LED an B-3 einschalten Wenn nicht, dann die LED an B-3 ausschalten Das ist analog zu obigem, nur ein paar Zahlen aendern sich. Daher: sbrs r17, 4 ; Bit 0 gesetzt ? rjmp LED_1_AUS ; ja: weiter gehts beim Ausschalten cbi PORTB, 3 ; nicht gesetzt, schalte LED ein rjmp LED_1_ENDE ; Das wars, LED 0 ist behandelt LED_1_AUS: sbi PORTB, 3 LED_1_ENDE: 5) Weiter gehts mit Schritt 2 (und damit endlos dahin) Das ist wieder leicht. Alles was wir brauchen ist ein rjmp und ein entsprechendes Label als Ziel des rjmp. Das Ziel ist der Schritt 2: LOOP: in r17, PINB ... ... rjmp LOOP D.h. das komplette Programm sieht dann so aus: ldi r16, 0b00001110 out DDRB, r16 ldi r16, 0b00010001 out PORTB, r16 ; cbi PORTB, 1 ; eine LED ist immer ein ; LOOP: in r17, PINB sbrs r17, 0 ; Bit 0 gesetzt ? rjmp LED_0_AUS ; ja: weiter gehts beim Ausschalten cbi PORTB, 2 ; nicht gesetzt, schalte LED ein rjmp LED_0_ENDE ; Das wars, LED 0 ist behandelt LED_0_AUS: sbi PORTB, 2 LED_0_ENDE: sbrs r17, 4 ; Bit 0 gesetzt ? rjmp LED_1_AUS ; ja: weiter gehts beim Ausschalten cbi PORTB, 3 ; nicht gesetzt, schalte LED ein rjmp LED_1_ENDE ; Das wars, LED 0 ist behandelt LED_1_AUS: sbi PORTB, 3 LED_1_ENDE: ; rjmp LOOP
Boaaahhh danke vielen vielen dank ihr habt mir echt geholfen, jetzt hab ichs endlich, und weiß sogar genau warum, hab mir jetzt erst mal weiter zum lernen erst mal ne selbsthaltung mit gebaut, echt genial. Mein problem liegt halt noch größtenteils in der ganzen logik mit der hardware. dachte ich könnte jeden pin einzeln direkt überprüfen ohne den ganzen port in einem register zwischenzuspeichern, weil ich halt in ner tabelle noch so sachen wie PORTB0...7 gefunden habe dachte ich halt, dass ich dass dann halt direkt machen könnte, hatte mich aber auch die ganze zeit gefragt warum er denn eigendlich bit 0 automatisch nimmt. ich dachte mit dem sbrs befehl kontrolliere ich das register und die stelle danach wäre für ist gleich 0 oder 1 und nicht für die stelle des registers. das ist die umstellung auf assembler, man versucht halt irgendwie noch in diesen if then else anweisungen zu denken, und spagetthi code mit sprungmarken war bei anderen sprachen er verpönt und als zu vermeiden angesehen, deshalb muss ich mich da jetzt erst mal reinfinden ;) danke nochmal
> und > spagetthi code mit sprungmarken war bei anderen sprachen er verpönt Das war dann "Ravioli" (Objekte mit Füllung)... Duck & wech... ...
hehehe, musste dich nicht ducken, ich hab das programmieren was wir machen mussten total gehasst, weil man das ergebniss nur am monitor hatte, der stundenlangen arbeit. jetzt hab ich endlich was inner hand, was ich gemacht habe. und ich find mich immer besser mit zurecht. ich dachte z.b. das ganze board wär im eimer weil es beim an und ausschalten jedesmal was anderes gemacht hat. das lag an der styropor unterlage die ich hatte damit das board nicht auf dem metall vom pc liegt. kopfschütte nenenenee, sowas gemeines lach.
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.