LASMOT00.ASM


1
;Steuerung eines Laser-Spiegel-Schrittmotors mittels AT-Mega8
2
;
3
;
4
5
6
.include"m8def.inc"        ;Hardwarekonstanten definieren
7
8
;----------------------------------------------------------------------------
9
;Anpassungen an die Hardware (Parameter und Konstanten):
10
11
;Tasten und Schalter (3 Stellungen) an PortB
12
.equ tap=pinb              ;Tastenport, Eingänge (PINx)
13
.equ mset=7                ;Modeschalter Stellung SET (Einrichten)
14
.equ mrun=6                ;Modeschalter Stellung RUN (Betrieb)
15
.equ trst=5                ;Taster Reset (Löschen der gespeicherten Liste)
16
.equ tup=4                 ;Taster UP (Aufwärtsbewegung)
17
.equ tdn=3                 ;Taster DOWN (Abwärtsbewegung)
18
.equ tent=2                ;Taster ENTER (Schrittübernahme)
19
.equ tok=1                 ;Taster OK (Rest der Liste wird gelöscht)
20
.equ tla=0                 ;Taster Laser an/aus
21
22
;Lichtschranke für Nullpunkt
23
.equ nup=pinc              ;Nullpunktsensor-Port PINx
24
.equ nuse=1                ;Nullpunkt-Sensor (Lichtschranke)
25
26
;Laser-Stromversorgung
27
.equ lap=portd             ;Laser-Port (PORTx)
28
.equ lapi=3                ;Laser-Pin (Bit x)
29
30
;Schrittmotor an PortD, Pins PD7, PD6, PD5, PD4
31
.equ smp=portd             ;Schrittmotor-Port (PORTx)
32
.equ smm=0b11110000        ;Schrittmotor-Bitmaske
33
34
;Poti zur Zeiteingabe an PC0
35
.equ adq=0                 ;ADC-Quelle
36
37
.equ timer0start=-156      ;Startwert Timer0 bei 1MHz, VT64 und 10ms (100Hz) ISR-Takt
38
.equ schritte=96           ;Anzahl der Vollschritte des Schrittmotors
39
40
;----------------------------------------------------------------------------
41
;Register...
42
.def null=r2               ;immer Null
43
.def srsk=r3               ;Kopie SREG
44
.def tsw=r4                ;Timer-Start (Reload)
45
.def scan=r5               ;Scannwert Tastenport
46
.def tz0=r6                ;Tasten-Prellzähler Bit0
47
.def tz1=r7                ;Tasten-Prellzähler Bit1
48
.def tas=r8                ;Tastenstatus (gültig)
49
50
.def posi=r16              ;Position des Motors
51
.def ztz=r17               ;Zeit-Zähler (CountDown)
52
.def soll=r18              ;Zielposition des Spiegels
53
.def tfl=r19               ;Flags für Tasten, die gedrückt wurden
54
.def flags=r20             ;Steuerflags
55
    .equ las=0        ;Laser
56
57
.def ztv=r22               ;Zeit-Vorteiler
58
.def mode=r23              ;einige Flasgs zur Ablaufsteuerung
59
    .equ nus=0        ;Nullpunkt suchen
60
    .equ savz=1       ;Zeit speichern
61
62
.def wl=r24                ;working-Register 1 (Low)
63
.def wh=r25                ;working-Register 2 (High)
64
65
66
.cseg                 ;Codesegment
67
.org 0                ;Adresse 0
68
 rjmp reset     ;Interrupt-Vektoren überspringen
69
;jetzt folgen die Interruptvektoren des Mega8 (Datenblatt ab S.44)
70
 reti ; rjmp EXT_INT0 ; IRQ0 Handler
71
 reti ; rjmp EXT_INT1 ; IRQ1 Handler
72
 reti ; rjmp TIM2_COMP ; Timer2 Compare Handler
73
 reti ; rjmp TIM2_OVF ; Timer2 Overflow Handler
74
 reti ; rjmp TIM1_CAPT ; Timer1 Capture Handler
75
 reti ; rjmp TIM1_COMPA ; Timer1 CompareA Handler
76
 reti ; rjmp TIM1_COMPB ; Timer1 CompareB Handler
77
 reti ; rjmp TIM1_OVF ; Timer1 Overflow Handler
78
 rjmp timer0 ; Timer0 Overflow Handler
79
 reti ; rjmp SPI_STC ; SPI Transfer Complete Handler
80
 reti ; rjmp USART_RXC ; USART RX Complete Handler
81
 reti ; rjmp USART_UDRE ; UDR Empty Handler
82
 reti ; rjmp USART_TXC ; USART TX Complete Handler
83
 reti ; rjmp ADCC ; ADC Conversion Complete Handler
84
 reti ; rjmp EE_RDY ; EEPROM Ready Handler
85
 reti ; rjmp ANA_COMP ; Analog Comparator Handler
86
 reti ; rjmp TWSI ; Two-wire Serial Interface Handler
87
 reti ; rjmp SPM_RDY ; Store Program Memory Ready Handler
88
89
reset:             ;Programmstart
90
 ldi zl,low(ramend)        ;Stackpointer
91
 ldi zh,high(ramend)       ;am
92
 out spl,zl                ;RAM-Ende
93
 out sph,zh                ;initialisieren
94
95
 clr scan                  ;definierte
96
 clr tz0                   ;Startzustände
97
 clr tz1                   ;für
98
 clr tas                   ;Tasten-
99
 clr tfl                   ;Entprellung
100
101
 ldi zl,3                  ;Timer0-Vorteiler
102
 out tccr0,zl              ;auf 64 einstellen
103
 ldi zl,timer0start        ;Timer0-Startwert
104
 mov tsw,zl                ;definieren
105
 out tcnt0,tsw             ;Timer-Startwert setzen
106
 ldi zl,1<<toie0           ;Timer0-Überlauf-Int
107
 out timsk,zl              ;aktivieren
108
 ldi zl,smm                ;Schrittmotorbits als
109
 out smp-1,zl              ;Ausgang (ddrx=portx-1)
110
 ldi zl,0                  ;alle Bits löschen
111
 out smp,zl                ;Motor erstmal aus
112
 out tap+1,zl              ;Tastenport als Eingang (ddrx=pinx+1)
113
 cbi nup+1,nuse            ;Nullpunkt-Portpin als Eingang (ddrx=pinx+1)
114
 sbi nup+2,nuse            ;Pull-Up Nullpunkt-Portpin ein (portx=pinx+2)
115
 sbi lap,lapi              ;Laser-Anschluss als Ausgang
116
 ldi zl,255                ;alle Bits setzen
117
 out tap+2,zl              ;Pull-UP-R's einschalten (portx=pinx+2)
118
 ldi zl,(1<<adlar)+adq     ;Analogwandler linksbündige Ausgabe und Signalquelle
119
 out admux,zl              ;wie oben in "adq" definiert
120
 ldi zl,(1<<aden)|(1<<adsc)|(1<<adfr)+2  ;ADC freilaufend mit Vorteiler 1:4
121
 out adcsra,zl             ;einschalten
122
 ldi mode,1<<nus           ;beim Start auf Nullposition fahren
123
 ldi posi,255              ;Start der Nullpunktsuche
124
 sei                       ;Int aktivieren
125
126
main:
127
 rjmp main                 ;Nix tun...
128
129
130
131
timer0:
132
; in srsk,sreg              ;SREG sichern
133
 out tcnt0,tsw             ;Timer Reload
134
135
Tastenabfrage:     ;Entprellroutine geklaut bei Peter Dannegger...
136
 in scan,tap               ;Tastenport einlesen (gedrückt=L)
137
 com scan                  ;invertieren (gedrückt=H)
138
 eor scan,tas              ;nur Änderungen werden H
139
 and tz0,scan              ;Prellzähler unveränderter Tasten löschen (Bit0)
140
 and tz1,scan              ;Prellzähler unveränderter Tasten löschen (Bit1)
141
 com tz0                   ;L-Bit zählen 0,2,->1, 1,3,->0
142
 eor tz1,tz0               ;H-Bit zählen 0,2,->tz1 toggeln
143
 and scan,tz0              ;Änderungen nur dann erhalten, wenn im Prellzähler
144
 and scan,tz1              ;beide Bits gesetzt sind (Zählerstand 3)
145
 eor tas,scan              ;erhaltene Änderungen toggeln alten (gültigen) Tastenstatus
146
 and scan,tas              ;nur (neu) gedrückte Tastenbits bleiben erhalten
147
 or tfl,scan               ;und zugehörige Bits setzen (gelöscht wird nach Abarbeitung)
148
 ;in "tas" steht jetzt der gültige Tastenzustand,
149
 ;in "tfl" die Flags der neu gedrückten, noch nicht abgearbeiteten Tasten...
150
151
 sbrs tfl,tla              ;Taste für Laserschalter gedrückt?
152
 rjmp savezeit             ;nein...
153
 in wl,lap                 ;Laserport einlesen
154
 ldi wh,1<<lapi            ;Laserpin
155
 eor wl,wh                 ;toggeln
156
 out lap,wl                ;und wieder ausgeben
157
 cbr tfl,1<<tla            ;Tastenflag löschen
158
159
savezeit:          ;Zweiter Job der "Enter-Taste"
160
 sbrs mode,savz            ;muss Verweilzeit gespeichert werden? (allerhöchste Priorität)
161
 rjmp nullsuch             ;nein...
162
 cbr mode,1<<savz          ;ja, Flag wieder löschen
163
 in wl,adch                ;ADC auslesen,
164
 inc wl                    ;Bereichskorrektur (Minimum=1, Maximum=256=0)
165
 ldi wh,1                  ;obere EEP-Page (Verweilzeiten)
166
 out eearh,wh              ;adressieren (untere Adresse bleibt so)
167
 out eedr,wl               ;ADC-Wert in EEP
168
 sbi eecr,eemwe            ;Schreibschutz aufheben
169
 sbi eecr,eewe             ;Schreiben
170
 rjmp fertig               ;fertig...
171
172
nullsuch:          ;Motor auf Nullpunkt fahren
173
 sbrs mode,nus             ;Nullpunkt suchen? (mittlere Priorität)
174
 rjmp schalter             ;nein...
175
 sbic nup,nuse             ;Nullpunkt-Sensor erreicht? (Lichtschranke unterbrochen?)
176
 rjmp nullfund             ;ja...
177
 dec posi                  ;nein, weiter runter fahren
178
 breq nullfund             ;255 Schritte gesucht? - aufhören, da stimmt was nicht...
179
 rjmp stellmot             ;Motor stellen...
180
nullfund:
181
 andi posi,7               ;Positionszähler löschen, untere 3 Bit bleiben erhalten
182
 ori posi,64               ;Spielraum nach unten
183
 mov soll,posi             ;Sollwert nachziehen
184
 ldi ztv,1                 ;Verweilzeit auf Minimum
185
 mov ztz,ztv               ;einstellen,
186
 ldi wl,255                ;letzte EEP-Adresse 
187
 out eearl,wl              ;(um mit der ersten zu beginnen)
188
 cbr mode,1<<nus           ;Nullsuchflag löschen
189
 rjmp fertig               ;fertig...
190
191
schalter:          ;Einrichten
192
 sbrs tfl,trst             ;ja, Taste "Reset" gedrückt? (immer verfügbar)
193
 rjmp schalter01           ;nein...
194
 cbr tfl,1<<trst           ;ja, Tastenflag löschen
195
 ldi posi,255              ;nur 255 Suchschritte
196
 out eearl,posi            ;letzte EEP-Adresse, um mit 0 zu beginnen
197
 sbr mode,1<<nus           ;Nullsuch-Flag setzen,
198
 rjmp nullsuch             ;und gleich beginnen...
199
schalter01:
200
 sbrs tas,mset             ;Einrichtmodus aktiv?
201
 rjmp schalter1            ;nein, restliche Tasten nicht abfragen...
202
 sbrs tfl,tup              ;Taste "Up" gedrückt?
203
 rjmp schalter02           ;nein...
204
 cbr tfl,1<<tup            ;ja, Tastenflag löschen
205
 inc posi                  ;Position erhöhen
206
 cpi posi,schritte*2       ;Zählumfang auf doppelte Schrittzahl (Halbschritt)
207
 brne schalter01a          ;begrenzen
208
 clr posi                  ;
209
schalter01a:
210
 rjmp stellmot             ;und Motor stellen...
211
schalter02:
212
 sbrs tfl,tdn              ;Taste "Down" gedrückt?
213
 rjmp schalter03           ;nein...
214
 cbr tfl,1<<tdn            ;ja, Tastenflag löschen
215
 dec posi                  ;Position vermindern
216
 cpi posi,0                ;Zählumfang auf doppelte Schrittzahl (Halbschritt)
217
 brne schalter02a          ;begrenzen
218
 ldi posi,schritte*2       ;
219
schalter02a:
220
 rjmp stellmot             ;und Motor stellen...
221
schalter03:
222
 sbrs tfl,tent             ;Taste "Enter" gedrückt?
223
 rjmp schalter04           ;nein...
224
 cbr tfl,1<<tent           ;ja, Tastenflag löschen
225
 in wl,eearl               ;EEP-Adresse holen
226
 inc wl                    ;und erhöhen
227
 cpi wl,255                ;letzte Zelle erreicht?
228
 breq enter1               ;ja, nicht im EEP speichern...
229
 out eearh,null            ;untere EEP-Page (Positionen)
230
 out eearl,wl              ;EEP-Adresse setzen
231
 out eedr,posi             ;Position ins EEP
232
 sbi eecr,eemwe            ;Schreibschutz aufheben
233
 sbi eecr,eewe             ;schreiben
234
 sbr mode,1<<savz          ;Flag zum Zeit Speichern setzen (wird nächste Runde gemacht)
235
enter1:                    ;Sprungziel bei Überlauf (nicht speichern)
236
 rjmp fertig               ;fertig...
237
schalter04:
238
 sbrs tfl,tok              ;Taste "Ok" gedrückt?
239
 rjmp schalter1            ;nein...
240
 cbr tfl,1<<tok            ;ja, Tastenflag löschen
241
 in wl,eearl               ;EEP-Adresse holen
242
 inc wl                    ;und erhöhen
243
 breq enter1               ;Überlauf...
244
 out eearh,null            ;untere EEP-Page (Positionen)
245
 out eearl,wl              ;EEP-Adresse setzen
246
 ldi wl,255                ;Leerbyte (nur eins zur Ende-Kennung)
247
 out eedr,wl               ;ins EEP
248
 sbi eecr,eemwe            ;Schreibschutz aufheben
249
 sbi eecr,eewe             ;schreiben
250
 rjmp fertig               ;
251
 
252
schalter1:         ;RUN
253
 sbrs tas,mrun             ;Runmodus aktiv?
254
 rjmp keinschalter         ;nein...
255
 cp posi,soll              ;Zielpunkt erreicht?
256
 breq warten               ;ja, Zeit abwarten...
257
 brmi motplus              ;nein, Position noch zu klein...
258
 dec posi                  ;nein, Pos. zu groß, verkleinern
259
 cpi posi,0                ;Zählumfang auf doppelte Schrittzahl (Halbschritt)
260
 brne stellmot             ;begrenzen
261
 ldi posi,schritte*2       ;
262
 rjmp stellmot             ;und Motorschritt ausführen...
263
motplus:
264
 inc posi                  ;Position vergrößern
265
 cpi posi,schritte*2       ;Zählumfang auf doppelte Schrittzahl (Halbschritt)
266
 brne stellmot             ;begrenzen
267
 clr posi                  ;
268
stellmot:
269
 ldi zl,low(bimu*2)        ;Zeiger auf
270
 ldi zh,high(bimu*2)       ;Motor-Bitmuster
271
 mov wl,posi               ;Kopie von Position zwecks
272
 andi wl,7                 ;Ausblendung der oberen Bits
273
 add zl,wl                 ;Offset dazu,
274
 adc zh,null               ;Übertrag auch
275
 lpm wl,z                  ;Bitmuster holen
276
 andi wl,smm               ;eventuell ungültige Bits ausblenden
277
 in wh,smp                 ;Schrittmotor-Port einlesen
278
 andi wh,255-smm           ;Schrittmotor-Bits löschen
279
 or wh,wl                  ;neue Schrittmotor-Bits dazu
280
 out smp,wh                ;und an Port ausgeben
281
 rjmp fertig               ;fertig...
282
warten:
283
 dec ztv                   ;Vorteiler (100) runter (1s je Runde)
284
 brne fertig               ;kein Übertrag...
285
 ldi ztv,100               ;Vorteiler auf Startwert
286
 dec ztz                   ;Sekunde runter
287
 brne fertig               ;nicht abgelaufen...
288
 ;Wartezeit abgelaufen...
289
nextpos:
290
 in wl,eearl               ;EEP-Adresse holen
291
 inc wl                    ;erhöhen (nächste Position)
292
vonvorn:
293
 out eearl,wl              ;EEP-Adresse zurückschreiben
294
 out eearh,null            ;untere Page (Positionen)
295
 sbi eecr,eere             ;EEP lesen
296
 in soll,eedr              ;als neuen Sollwert
297
 ldi wh,1                  ;EEP-Adresse obere Page
298
 out eearh,wh              ;(Verweildauer)
299
 sbi eecr,eere             ;EEP lesen
300
 in ztz,eedr               ;als neue Verweilzeit
301
 cpi soll,$ff              ;Wert gültig? (<>$ff)
302
 brne fertig               ;ja, fertig...
303
304
 tst wl                    ;nein, war das Adresse 0?
305
 breq fertig               ;ja, dann ist EEP noch leer...
306
 
307
 mov soll,posi             ;nein, Wert verwerfen
308
 clr ztz                   ;Zeit auch
309
 clr wl                    ;EEP-Adr.
310
 clr wh                    ;von vorn 
311
 rjmp vonvorn              ;beginnen...
312
313
keinschalter:      ;es ist kein Schalter betätigt (Mittelstellung)
314
 ;Platz für Steuerung via RS232 per PC (optionale Erweiterung)
315
fertig:
316
; out sreg,srsk             ;SREG wiederherstellen
317
 reti                      ;fertig...
318
319
320
bimu:                      ;Bitmuster für Schrittmotor
321
.db 0b10000000,0b11000000  ;
322
.db 0b01000000,0b01100000  ;
323
.db 0b00100000,0b00110000  ;
324
.db 0b00010000,0b10010000  ;