Forum: Mikrocontroller und Digitale Elektronik Schaltung zum Fotoapparat auslösen -> Softwareproblem


von Mathias H. (Firma: keine) (matze_2)


Lesenswert?

Hallo zusammen!

Ich hoffe ich finde hier Hilfe. Hier mein Problem:

Ich habe eine Schaltung gebaut mit der ich einen Optpkoppler ansteuere 
der meinen Fotoapparat auslöst. Dies soll regelmäßig für Zeitraffer- und 
HDR-Aufnahmen erfolgen. Das ganze wird mit einem Attiny13 (Atmel 
ATTINY13-20PU) gesteuert. Je nach Belegung einzelner "Eingangs-Pins" mit 
High oder Low sollen unterschiedliche Frequenzfolgen durchlaufen. Die 
Hardware steht und sollte soweit auch fehlerfrei sein. Meine Software 
macht mir jedoch immer das selbe Signal: 1 Sekunde Auslösen 1 Sekunde 
Pause, egal was en den Eingangspins anliegt.

Die Beschaltung des Kontrollers sieht wie folgt aus:

 Pin 1 - PB5 - RESET (steht auf High=5V)
 Pin 2 - PB3 - Schalter (High <-> Low)
 Pin 3 - PB4 - Schalter (High <-> Low)
 Pin 4 - GND
 Pin 5 - PB0 - Schalter (High <-> Low)
 Pin 6 - PB1 - Ausgang -> Optokoppler (über Widerstand)
 Pin 7 - PB2 - nicht belegt
 Pin 8 - VCC (5V)

Und hier der verwendete Quellcode:
1
/*
2
* AVRSimpleTrigger.asm
3
*
4
*  Created: 06.01.2012 23:43:25
5
*   Author: Mathias
6
*
7
* Dieses Programm steuert einen Auslöser für meine DSLR.
8
* Vom Prinzip ist es nur ein einfacher Rechteck-Signal-Generator
9
* der einen Optokoppler ansteuert. Je nach Beschaltung der 
10
* "Eingangspins" (Pinbelegung siehe unten) werden unterschiedliche
11
* Rechtecksignale erzeugt.
12
*/
13
14
.include "tn13def.inc"         ; Definitionsdatei für den Prozessortyp einbinden
15
16
.def temp = r16        ; temporäres Register
17
.def temp2 = r22     ; zweites temporäres Register
18
19
.def warten1 = r17     ; Register für Pauseschleife
20
.def warten2 = r18     ; Register für Pauseschleife
21
.def warten3 = r19     ; Register für Pauseschleife
22
23
.def warten4 = r23     ;Register für Pauseschleife
24
.def abfrage = r20     ; Register um Taster einzulesen
25
.def hilfsregister = r21    ;  zweites Register um Taster einzulesen
26
27
28
// Interrupts
29
30
.org 0x000
31
       rjmp main
32
.org INT0addr
33
        reti        ;External Interrupt0
34
.org PCI0addr
35
        reti    ;External Interrupt Request 0
36
.org OVF0addr
37
        reti    ;Timer/Counter0 Overflow
38
.org ERDYaddr
39
        reti        ; EEPROM Ready
40
.org ACIaddr
41
        reti        ; Analog Comparator
42
.org OC0Aaddr
43
        reti    ; Timer/Counter Compare Match A
44
.org OC0Baddr
45
        reti    ; Timer/Counter Compare Match B
46
.org WDTaddr
47
        reti        ; Watchdog Time-out
48
.org ADCCaddr
49
        reti        ; ADC Conversion Complete
50
51
.org INT_VECTORS_SIZE
52
53
54
55
// Hauptprogramm
56
main:
57
58
// Initialisierung
59
60
    cli                 ;Interrupts ausschalten
61
62
    // Stack initialisieren
63
    ldi temp, RAMEND    ; Stackpointer initialisieren
64
    out SPL, temp
65
66
    //Prescaller
67
    ldi temp, (1<<CS02) | (0<<CS01) | (0<<CS00) ; Prescaler auf 256 gestellt
68
    out TCCR0B, temp
69
70
    //Pinbelegung
71
72
  // Verwendeter Kontroller: Attiny 13
73
  // Pin 1 - PB5 - RESET (steht auf High)
74
  // Pin 2 - PB3 - Schalter (High <-> Low)
75
  // Pin 3 - PB4 - Schalter (High <-> Low)
76
  // Pin 4 - GND
77
  // Pin 5 - PB0 - Schalter (High <-> Low)
78
  // Pin 6 - PB1 - Ausgang -> Optokoppler
79
  // Pin 7 - PB2 - nicht belegt
80
  // Pin 8 - VCC
81
82
    //Ein- und Ausgänge festlegen (PB1 -> Ausgang, PB0 und PB3 - PB5 -> Eingänge)
83
    ldi temp, 0b11000110
84
    out DDRB, temp
85
86
    //PB liegen allesamt auf Vcc (PB2 und PB3 - PB5 -> Pullupwiderstände deaktiviert)
87
    ldi temp, 0b11000110
88
    out PORTB, temp
89
90
  sei          ; Interrupts aktivieren
91
92
     //Rechtecksignalerzeugung
93
ende:
94
    // Exteren Schalter abfragen
95
    nop
96
    nop
97
    in abfrage, PORTB
98
    nop
99
    nop
100
101
102
    //Auswahl (Durch externe Schalter)
103
  // der unterschiedlichen Rechtecksignale.
104
  // Eine Sekunde wird ein Schalter gedrückt, dann eine
105
  // bestimmte Zeit lang pause gedrückt.
106
107
  // Pausezeit eine Sekunde
108
    andi abfrage, 0b00011001
109
  mov temp2, abfrage
110
  ldi temp, 1
111
    cpi  abfrage, 0b00000000
112
    breq PWM
113
114
  // Pausezeit 2 Sekunden
115
  mov abfrage, temp2
116
  ldi temp, 2
117
    cpi  abfrage, 0b00000001
118
    breq PWM
119
120
  // Pausezeit 4 Sekunden
121
  mov abfrage, temp2
122
  ldi temp, 4
123
  cpi  abfrage, 0b00010000
124
    breq PWM
125
126
  // Pausezeit 8 Sekunden
127
  mov abfrage, temp2
128
  ldi temp, 8
129
  cpi  abfrage, 0b00001000
130
    breq PWM
131
132
  // Pausezeit 15 Sekunden
133
  mov abfrage, temp2
134
  ldi temp, 15
135
  cpi  abfrage, 0b00010001
136
    breq PWM
137
138
  // Pausezeit 30 Sekunden
139
  mov abfrage, temp2
140
  ldi temp, 30
141
  cpi  abfrage, 0b00001001
142
    breq PWM
143
144
  // Pausezeit 60 Sekunden
145
  mov abfrage, temp2
146
  ldi temp, 60
147
  cpi  abfrage, 0b00011000
148
    breq PWM
149
150
  // Hier wird ein Signal für eine Belichtungsreihe erzeugt.
151
  // Die werden für die Aufnahme von HDR-Bilder benötigt.
152
153
  mov abfrage, temp2
154
  cpi  abfrage, 0b00011001
155
    breq HDR
156
157
  rjmp ende
158
159
160
  // Erzeugung des Rechtecksignals
161
    PWM:
162
    cbi PORTB, 1 // PB2 wird auf GND gesetzt (Schalter geschlossen)
163
    rcall PWMWait_1Sekunde
164
    sbi PortB, 1  // PB2 wird auf Vcc gesetzt (Schalter offen)
165
        loop:
166
      rcall PWMWait_1Sekunde
167
      dec temp
168
      brne loop
169
    rjmp ende
170
171
  // Rechtecksignal für HDR
172
  HDR:
173
  // 1/60 - 1/15 - 1/4 - 1/1 - 4/1 - 16/1 Sekunden
174
175
    //--- (1/60)
176
    cbi PORTB, 1 //(Schalter geschlossen)
177
    rcall PWMWait_60zigstel_Sekunde //(1/60)
178
    sbi PortB, 1  //(Schalter offen)
179
    rcall PMWWait_4Sekunden
180
  
181
    //--- (1/15)
182
    cbi PORTB, 1 //(Schalter geschlossen)
183
    ldi temp, 4 //(1/15)
184
    loop3:
185
      rcall PWMWait_60zigstel_Sekunde
186
      dec temp
187
      brne loop3
188
    sbi PortB, 1  //(Schalter offen)
189
    rcall PMWWait_4Sekunden
190
191
    //--- (1/4)
192
    cbi PORTB, 1 //(Schalter geschlossen)
193
    ldi temp, 16
194
    loop4:
195
      rcall PWMWait_60zigstel_Sekunde //(1/4)
196
      dec temp
197
      brne loop4
198
    sbi PortB, 1  //(Schalter offen)
199
    rcall PMWWait_4Sekunden
200
201
    //--- (1/1)
202
    cbi PORTB, 1 //(Schalter geschlossen)
203
    rcall PWMWait_1Sekunde //(1/1)
204
    sbi PortB, 1  //(Schalter offen)
205
    rcall PMWWait_4Sekunden
206
207
    //--- (4/1)
208
    cbi PORTB, 1 //(Schalter geschlossen)
209
    ldi temp, 4 //(4/1)
210
    loop5:
211
      rcall PWMWait_1Sekunde
212
      dec temp
213
      brne loop5
214
    sbi PortB, 1  //(Schalter offen)
215
    rcall PMWWait_4Sekunden
216
217
    //--- (16/1)
218
    cbi PORTB, 1 //(Schalter geschlossen)
219
    ldi temp, 16 //(16/1)
220
    loop6:
221
      rcall PWMWait_1Sekunde
222
      dec temp
223
      brne loop6
224
    sbi PortB, 1  //(Schalter offen)
225
  loop11: rjmp loop11
226
227
rjmp ende
228
229
//---- 
230
// Hier stehen jede Menge Schleifen, die Zeit verbruachen um die
231
// gewünschten Pausen zu realisieren.
232
PWMWait_1Sekunde:
233
    ldi warten1, 255
234
    wait:
235
    nop
236
    nop
237
    nop
238
    nop
239
    nop
240
        ldi warten2, 206
241
        wait2:
242
            ldi warten3, 5
243
      nop
244
            wait3:
245
                dec warten3
246
                brne wait3
247
            dec warten2
248
            brne wait2
249
        dec warten1
250
        brne wait
251
ret
252
253
//
254
//PWMWait_60erSekunde
255
256
 PWMWait_60zigstel_Sekunde:
257
    nop
258
  nop
259
  nop
260
  nop
261
   ldi warten3, 15
262
      wait7:
263
                dec warten3
264
                brne wait7
265
266
  ldi warten1, 248
267
    wait4: 
268
        ldi warten2, 4
269
        wait5:
270
            ldi warten3, 4
271
      nop
272
            wait6:
273
                dec warten3
274
                brne wait6
275
            dec warten2
276
            brne wait5
277
        dec warten1
278
        brne wait4
279
   ret
280
281
// 4 Sekundenpause
282
  PMWWait_4Sekunden:
283
    ldi temp, 4 //(4sec Pause)
284
    loop8:
285
      rcall PWMWait_1Sekunde
286
      dec temp
287
      brne loop8
288
  ret


Da ich hier neu bin weiß ich nicht ob dieser Quellcode als lang gilt und 
habe ihn einfach in den Beitrag kopiert.

Bin für jede Idee dankbar. Kompilieren läßt sich das Ganze ohne Fehler.

VG
Matze

von Herr M. (herrmueller)


Lesenswert?

Auf die Schnelle:

Du musst PINB abfragen , nicht   -   in abfrage, PORTB  -

mehr hab ich noch nicht gesehen


gruss HerrMueller

von Werner (Gast)


Lesenswert?

Als erstes würde ich da die Schleiferei durch eine kleine Timer 
Zeitbasis ersetzen

Mathias Hoffmann schrieb:
> Meine Software macht mir jedoch immer das selbe Signal: 1 Sekunde
> Auslösen 1 Sekunde Pause, egal was en den Eingangspins anliegt.

Bist du sicher, dass der Prozessor nicht dauern einen Reset bekommt, zB. 
durch den Watchdog? Was sagt der Simulator zu deinem Programm? Verhält 
es sich da genauso?

von Mathias H. (Firma: keine) (matze_2)


Lesenswert?

Danke für die Antworten!

Das mit PINB ist sicherlich eine, wenn nicht die Fehlerquelle.
Timer Sequenzen wären sicherlich schöner, aber da ich erst am Anfang 
stehe habe ich jetzt einfach mit Schritten Laufzeit verbraucht. 
Interrupts habe ich bewusst nichts angelegt. Ich kann sie natürlich über 
mein ganzes Programm über 'cli' ausschalten. Im Simulator sah das ganze 
bisher gut aus. Aber vielleicht habe ich da auch etwas falsch gemacht. 
Ich werde das mit dem PINB ausprobieren und mal sehen ob das ganze 
funktioniert.

Vielen Dank
Mathias

von Herr M. (herrmueller)


Lesenswert?

> Das mit PINB ist sicherlich eine, wenn nicht die Fehlerquelle

Da die Tasten keine Reaktion zeigen, ist das 'Nicht Abfragen' der Tasten 
schon eine Fehlerquelle.

von Mathias H. (Firma: keine) (matze_2)


Lesenswert?

Um mal nachzufragen: In der Simulation in AVRStudio kann ich einen 
'Physisch existierenden PIN' mit dem PINB-Register simulieren? Ist das 
korrekt?

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Ja.

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.