Hallo, Ich besitze eine Gabellichtschranke vom Typ TCST 2103 und einen ATmega8. Jetzt möchte ich eine gelochte scheibe (4 Löcher) drehen. Bei einer vollen umdrehung soll ein signal über die Serielle schnittstelle an den pc gesendet werden und das ganze auch noch in Assembler :). Mit dem versenden von dem Signal hab ich kein Problem allerdings mit der Lichtschranke... Ich habe bereits ein kleines Assembler Programm zum laufen bekommen, allerdings sendet mir der ATmega8 nicht immer bei jedem 4. Loch ein Signal, sondern manchnal auch nach jedem 2. oder 3... Muss man eine Lichtschranke änlich wie ein Taster entprellen? Hat jemand ein gutes Tutorial parat?
Normalerweise nicht. Bei einer Lichtschranke gibt es ja keine mechinschen Kontakte. Schaden kanns allerdings auch nicht, sofern deine maximal erkennbare Scheibendrehzahl nicht unzulässigerweise gedrückt wird. Du kannst das wie einen Taster behandeln AVR-Tutorial Im Abschnitt über Taster und Entprellung Wie sieht denn dein Programm aus und wie machst du denn jetzt die Lichtschrankenabfrage? Vielleicht hast du ja auch einfach nur einen ganz ordinären Programmfehler.
Danke für die schnelle Antwort. Ich habe genau den beispielcode verwendet, der im Tutorial für die Entprellung von Tastern benutzt wird. Habe ihn natürlich ein bisschen erweitert:
1 | ;+---------------------------------------------------------------------- |
2 | ;| Title : Lichtschranke |
3 | ;+---------------------------------------------------------------------- |
4 | ;| Prozessor : ATmega8 |
5 | ;| Takt : 3,6864 MHz |
6 | ;| Sprache : Assembler |
7 | ;| Datum : 16.11.2011 |
8 | ;| Version : 1.0 |
9 | ;+---------------------------------------------------------------------- |
10 | |
11 | ;------------------------------------------------------------------------Includes |
12 | |
13 | .include "m8def.inc" |
14 | |
15 | ;------------------------------------------------------------------------Definitionen |
16 | |
17 | .def iwr0 = r1 |
18 | .def iwr1 = r2 |
19 | |
20 | .def key_old = r3 |
21 | .def key_state = r4 |
22 | .def key_press = r5 |
23 | |
24 | .def temp1 = r17 |
25 | |
26 | .equ key_pin = PIND |
27 | .equ key_port = PORTD |
28 | .equ key_ddr = DDRD |
29 | |
30 | ;------------------------------------------------------------------------Interrupt Vektoren |
31 | .org 0x0000 |
32 | rjmp init |
33 | |
34 | .org OVF0addr |
35 | rjmp timer_overflow0 |
36 | |
37 | ;------------------------------------------------------------------------Interrupt Routine |
38 | timer_overflow0: |
39 | |
40 | push r0 ; temporäre Register auf dem Stackpointer sichern |
41 | in r0,SREG ; Statusregister in r0 laden |
42 | push r0 ; r0 auf dem Stackpointer sichern |
43 | push iwr0 ; r1 auf dem Stackpointer sichern |
44 | push iwr1 ; r2 auf dem Stackpointer sichern |
45 | |
46 | getkey: |
47 | mov iwr0,key_old ;00110011 10101010 00110011 |
48 | in key_old,key_pin ;11110000 |
49 | eor iwr0,key_old ; 11000011 |
50 | com key_old ;00001111 |
51 | mov iwr1,key_state ; 10101010 |
52 | or key_state,iwr0 ; 11101011 |
53 | and iwr0,key_old ; 00000011 |
54 | eor key_state,iwr0 ; 11101000 |
55 | and iwr1,iwr0 ; 00000010 |
56 | or key_press,iwr1 ; gedrückte Taste merken |
57 | ; |
58 | ; |
59 | pop iwr1 ; Register r2 wiederherstellen |
60 | pop iwr0 ; Register r1 wiederherstellen |
61 | pop r0 ; Register r0 wiederherstellen |
62 | out SREG,r0 ; Statusregister gleich r0 setzen |
63 | pop r0 ; Register r0 wiederherstellen |
64 | reti ; Interrupt return |
65 | |
66 | ;------------------------------------------------------------------------Initalisierung |
67 | init: |
68 | ;------------------------------------------------------------Stackpointer initialisieren |
69 | |
70 | ldi temp1,HIGH(RAMEND) |
71 | out SPH,temp1 |
72 | ldi temp1,LOW(RAMEND) |
73 | out SPL,temp1 |
74 | |
75 | ;------------------------------------------------------------UART |
76 | |
77 | sbi UCSRB,RXCIE ; Interrupt bei Empfang |
78 | sbi UCSRB,RXEN ; RX (Empfang) aktivieren |
79 | sbi UCSRB,TXEN ; TX (Senden) aktivieren |
80 | ldi r16,3686400/(9600*16)-1 |
81 | out UBRRL,r16 ; Baudrate 9600 einstellen |
82 | |
83 | ;------------------------------------------------------------Eingänge/Ausgänge setzen |
84 | |
85 | cbi key_ddr,7 ;PortD 2 auf Eingang setzen |
86 | sbi key_port,7 ;Pullup für PortD2 |
87 | sbi DDRB,0 |
88 | |
89 | ;------------------------------------------------------------Timer initalisieren |
90 | |
91 | ldi temp1,1<<CS00 ;|1<<CS00 ; Timer mit Vorteiler 256 oder 1024 |
92 | out TCCR0,temp1 |
93 | ldi temp1,1<<TOIE0 ; Timer Overflow Interrupt einrichten |
94 | out TIMSK,temp1 |
95 | |
96 | ;------------------------------------------------------------Register initalisieren |
97 | |
98 | clr key_old ; die Register für die Tastenauswertung im |
99 | clr key_state ; Timer Interrupt initialisieren |
100 | clr key_press |
101 | |
102 | ldi r18,255 ; r18 ist das register für den counter |
103 | ldi r19,4 ; r19 hält die Zahl für eine volle umdrehung |
104 | |
105 | ;------------------------------------------------------------Globale Interrupts aktivieren |
106 | |
107 | sei ; Timer freigeben |
108 | |
109 | ;------------------------------------------------------------------------Mainloop |
110 | main: |
111 | cli ; Globale interrupts werden abgeschaltet |
112 | mov temp1,key_press ; Einen ev. Tastendruck merken und ... |
113 | clr key_press ; Tastendruck zurücksetzen |
114 | sei ; Globale interrupts werden eingeschaltet |
115 | |
116 | cpi temp1,0 ; Tastendruck auswerten. Wenn eine Taste |
117 | breq main ; gedrückt worden wäre, wäre ein entsprechendes Bit in key_press gesetzt gewesen |
118 | |
119 | dec r19 ; dekrementiere r19 |
120 | brne main ; wenn r19 = 0 sende byte |
121 | out UDR,r18 ; Byte senden |
122 | ldi r19,4 ; Register r19 auf 4 zurücksetzen |
123 | |
124 | rjmp main ; Rücksprung zu mai |
> sbi UCSRB,RXCIE ; Interrupt bei Empfang > sbi UCSRB,RXEN ; RX (Empfang) aktivieren Du gibst den UART Empfang frei ohne ihn zu behandeln. Das alleine wäre noch nicht schlimm. Du gibst aber auch den Empfangs-Interrupt frei, ohne ihn zu behandeln. Keine gute Idee!
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.