Forum: Mikrocontroller und Digitale Elektronik Gabellichtschranke statuswechsel erkennung


von kdoe (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

von kdoe (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

>   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
Noch kein Account? Hier anmelden.