Hallo Leute, vielleicht kann mir einer von Euch weiterhelfen, ich beisse im Moment auf Granit: Ich möchte an einem AT Tiny 2313 den PIN 3 von PortD auf High oder Low abfragen. Wenn er High ist, soll über UART eine 1 an mein Terminalprogramm geschickt werden (das Ganze läuft auf einem STK500). Wenn der Pin Low ist, soll eine Null gesendet werden. Soweit, so gut. Gedacht ist das, um das Echosignal eines SRF04 Ultraschallmoduls abzufragen. Um ein Signal erstmal zu simulieren lasse ich PINB0 meines Tiny2313 0,2 Sekunden ein High-Signal schicken, dann 0,2 Sekunden Low. Verbunden habe ich den PINB0 des Tiny mit PIND3. Das Ganze funktionert auch mit einer LED, die ich mit PINB0 verbunden habe. Sie blinkt brav mit 2,5Hz vor sich hin. Aber wenn ich jetzt statt diese LED blinken zu lassen, eine 0, bzw. 1 über UART rausschicke, dann bekomme ich entweder nur Nullen, oder nur Einsen am Hyperterminal. Ich raffs nicht. Benutzt habe ich einen Teil des Programms "extinttest.asm" hier aus dem Tutorial. Dabei ist INT0=0 und INT1=1, d.h., es sollte bei jeder Änderung am PIN der entsprechende Zustand auch rausgeschickt werden (Hoffe, ich stelle das hier verständlich dar). Aber ich bekomme nur Nullen. Wenn ich INT0=1 und INT1=1 mache, dann bekomme ich nur Einsen (und das auch noch viel langsamer als die Nullen im vorherigen Fall...) Kann mir jemand weiterhelfen ? Hier ist mein Code: .include "tn2313def.inc" .def temp = r16 .equ CLOCK = 4000000 .equ BAUD = 9600 .equ UBRRVAL = CLOCK/(BAUD*16)-1 .org 0x000 rjmp main ; Reset Handler .org INT1addr rjmp int1_handler ; IRQ1 Handler main: ; Stackpointer initialisieren ldi temp, LOW(RAMEND) out SPL, temp ; Baudrate einstellen ldi temp, LOW(UBRRVAL) out UBRRL, temp ldi temp, HIGH(UBRRVAL) out UBRRH, temp ; Frame-Format: 8 Bit ldi temp, (1<<UCSRC)|(3<<UCSZ0) out UCSRC, temp sbi UCSRB,TXEN ; TX aktivieren ldi temp, 0b00001000 ;00:Low Level , 01: jede Änderung, 10: fallende Flanke, 11: steigende Flanke out MCUCR, temp ldi temp, 0b11000000 ;INT1 (PD 3) aktivieren out GIMSK, temp ldi temp, 0x00 ; Port D = Eingang out DDRD, temp ldi temp, 0xFF ; Port B = Ausgang out DDRB, temp sei ;Interrupts allgemein aktivieren ;***Send 200ms pulse to PB0: fire: ldi temp, 0xff out DDRB,temp ;out PORTB,temp rcall pause ;wait 200 ms ldi temp, 0x00 out DDRB,temp ;out PORTB,temp rcall pause rjmp fire ;***200 ms pulse has been sent int1_handler: sbic PIND,3 ldi r24,'1' sbis PIND,3 ldi r24,'0' ldi temp, 0xff out DDRB, temp rcall pause ldi temp, 0x00 out DDRB, temp rcall pause int0_: sbis UCSRA,UDRE ; Warten bis UDR bereit ist rjmp int0_ out UDR, r24 reti pause: ; ============================= ; Warteschleifen-Generator ; 800000 Zyklen: (200 ms) ; ----------------------------- ; warte 799995 Zyklen: ldi , $5F WGLOOP0: ldi , $17 WGLOOP1: ldi , $79 WGLOOP2: dec brne WGLOOP2 dec brne WGLOOP1 dec brne WGLOOP0 ; ----------------------------- ; warte 3 Zyklen: ldi , $01 WGLOOP3: dec brne WGLOOP3 ; ----------------------------- ; warte 2 Zyklen: nop nop ; ============================= ret
Gib doch einfach mal an einem freien Pin den Wert des Registers R24 aus und hänge über einen Vorwiderstand eine LED an den Port. So kannst du zumindest eingrenzen, ob dein Problem am Einlesen von D3 oder am Ausgeben des Seriellen Wertes liegt. Viel Glück beim Suchen Remo
Deine Interrupt-Routine sichert keinerlei Register, und auch die Flags werden nicht gesichert. Außerdem solltest du in deiner Interrupt-Routine eher nicht in einer Warteschleife auf die Schnittstelle warten, denn während dieser Zeit bleibt auch deine Pin-toggle-Schleife stehen. Und warum hast du innerhalb der Interrupt-Routine noch mal eine zweite toggle-Schleife? Und warum nimmst du zum Toggeln DDRB? Damit schaltest du den Port nur zwischen Eingang und Ausgang um.
Danke Remo. Danke Rolf, ja ja, Du hast Recht, viele Fragen, auf die ich selbst nicht genau die Antwort kenne, was ein sicherer Hinweis darauf ist, dass es mir im mOment noch stark am nötigen Know How fehlt. Ich muss das alles noch mal neu machen. Die Warteschleife ist dazu da, um eine Zustandsänderung am PIND3 sichtbar zu machen, d.h. also mal kurz warten und währenddessen die LEDs an PORT B anmachen, damit ich halt sehe, dass sich da was tut. Ich beutze DDRB, weil wenn ich "out PORTB" schreibe, dann gehen die LEDs nicht an, das klappt irgendwie nur mit "out DDRB", ist schon klar, dass das eigentlich das Richtungsregister ist. Na ja, danke für die Hilfe.
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.