servogen01.asm


1
;Baustelle...
2
/*
3
Servoimpulsgenerator 
4
5
6
Anschlussbewegung ATTiny13:
7
8
Pin 1:  PB5,    Reset
9
Pin 2:  PB3,    ADC 3   Position 1
10
Pin 3:  PB4,    ADC 2   Position 2
11
Pin 4:  GND
12
Pin 5:  PB0,    Impulsausgang
13
Pin 6:  PB1,    Eingang (binärer Pegel)
14
Pin 7:  PB2,    erstmal unbenutzt
15
Pin 8:  Vcc
16
17
*/
18
19
.include "tn13def.inc"
20
21
;feste Konstanten:
22
.equ ste=pb1                ;Steuereingang
23
.equ impa=pb0               ;Impulsausgang
24
.equ muxpos2=(1<<adlar)+2   ;ADC2 linksbündig in ADMUX, Position 2
25
.equ muxpos1=(1<<adlar)+3   ;ADC3 linksbündig in ADMUX, Position 1
26
.equ ipause=6               ;Dauer der Impulspause (mal 3,4 Sekunden)
27
28
29
30
.dseg                       ;Variablen im SRAM
31
.org sram_start             ;
32
adcq:       .byte 2         ;ADC-Messquellen (Einstell-Werte für ADMUX)
33
adcn:       .byte 2         ;ADC-Nachkommawerte (Messwertberuhigung)
34
mwp1:       .byte 1         ;ADC-Mittelwert Position 1
35
mwp2:       .byte 1         ;ADC-Mittelwert Position 2
36
pos1:       .byte 1         ;fertiger Wert Position 1
37
pos2:       .byte 1         ;fertiger Wert Position 2
38
39
40
;Variablen in Registern:
41
.def srsk=r2                ;SREG-Sicherung
42
.def null=r3                ;immer 0
43
44
45
.def tmp=r20                ;temp
46
.def it0=r21                ;temp in ISR
47
.def it1=r22                ;temp in ISR
48
.def pauz=r23               ;Impuls-Pausenzähler
49
.def wl=r24                 ;temporär L
50
.def wh=r25                 ;temporär H
51
;XH:XL wird als Impulsdauerzähler genutzt
52
;YH:YL wird als Pointer für SRAM benutzt
53
54
55
56
;-------------------------------------------------------------------
57
.cseg               ;Programmspeicher
58
.org 0              ;ab Adresse 0
59
 rjmp RESET         ;Reset Handler Tiny13
60
 rjmp nix;EXT_INT0      ;IRQ0 Handler
61
 rjmp nix;PCINT0        ;PCINT0 Handler
62
 rjmp TIM0_OVF      ;Timer0 Overflow Handler
63
 rjmp nix;EE_RDY        ;EEPROM Ready Handler
64
 rjmp nix;ANA_COMP      ;Analog Comparator Handler
65
 rjmp TIM0_COMPA    ;Timer0 CompareA Handler
66
 rjmp nix;TIM0_COMPB    ;Timer0 CompareB Handler
67
 rjmp nix;WATCHDOG      ;Watchdog Interrupt Handler
68
 rjmp nix;ADCC          ;ADC Conversion Handler
69
nix:                    ;Falle für Fehler
70
 rjmp nix                   ;Endlos-Schleife bei versehentlichem INT-Aufruf
71
72
RESET:
73
 ldi wl,1<<clkpce           ;Schreibschutz-Bit Systemvorteiler
74
 ldi wh,1                   ;neuer Wert für Systemvorteiler für 4,8 MHz
75
 out clkpr,wl               ;Schreibschutz Systemvorteiler aufheben
76
 out clkpr,wh               ;Controllertakt auf
77
 out clkpr,wh               ;4,8MHz umschalten
78
 nop                        ;Zeit zum Einschwingen geben
79
 clr null                   ;immer 0
80
 ldi pauz,ipause*2          ;Impuls-Start verzögern
81
 sbi portb,pb1              ;PullUp für Eingang einschalten
82
 sbi portb,pb2              ;PullUp für unbenutzten Pin einschalten
83
 sbi ddrb,pb0               ;Impuls-Ausgang
84
85
;ADC-Mittelwerte initialisieren
86
 ldi yl,low(adcq)           ;Pointer auf Array mit
87
 ldi yh,high(adcq)          ;ADMUX-Bitmustern und ADC-Mittelwerten
88
 ldi wl,(1<<aden)|6         ;ADC-Einzelmessung mit 75 kHz 
89
 out adcsra,wl              ;vorbereiten
90
 ldi wl,muxpos2             ;ADMUX-Bitmuster 
91
adcreset0:
92
 st y,wl                    ;für später eintragen
93
 out admux,wl               ;und setzen
94
 sbi adcsra,adsc            ;ADC starten
95
adcreset1:
96
 sbic adcsra,adsc           ;auf Ergebnis warten...
97
 rjmp adcreset1             ;noch nicht fertig...
98
 in wh,adch                 ;ADC fertig, Ergebnis holen
99
 std y+4,wh                 ;Ergebnis als Mittelwert sichern
100
 std y+2,null               ;Nachkommastellen auf 0
101
 inc wl                     ;ADC-Quelle hochzählen
102
 adiw yh:yl,1               ;nächster ADC-Kanal
103
 cpi yl,low(adcn)           ;alle 2 Kanäle fertig?
104
 brne adcreset0             ;nein, nochmal...
105
 ldi yl,low(adcq)           ;ja, Pointer wieder auf Start setzen
106
 ldi wl,muxpos2             ;ADMUX-Bitmuster 
107
 out admux,wl               ;setzen
108
 sbi adcsra,adsc            ;ADC starten
109
110
;Timer initialisieren:
111
 ldi wl,3                   ;Timer0 mit Vorteiler 1:64 
112
 out tccr0b,wl              ;ohne Sonderfunktionen starten
113
 ldi wl,(1<<ocie0a)|(1<<toie0)  ;Compare A und Überlauf-
114
 out timsk0,wl              ;Interrupts des Timer 0 freigeben
115
116
 sei                        ;Interrupts global freischalten
117
118
;-------------------------------------------------------------------
119
120
mainloop:           ;Hauptschleife
121
 sbic adcsra,adsc           ;auf ADC-Ergebnis warten...
122
 rjmp mainloop              ;noch nicht fertig...
123
 in r0,adch                 ;erste Messung verwerfen
124
 sbi adcsra,adsc            ;ADC neu starten
125
mainloop_0:
126
 sbic adcsra,adsc           ;auf ADC-Ergebnis warten...
127
 rjmp mainloop_0            ;noch nicht fertig...
128
129
 ldd wl,y+2                 ;ADC-Nachkommawert holen
130
 ldd wh,y+4                 ;ADC-Mittelwert holen
131
 sub wl,wh                  ;1/256 des Mittelwertes
132
 sbc wh,null                ;mit Übertrag entfernen
133
 in r0,adch                 ;neuen Messwert holen
134
 add wl,r0                  ;1/256 davon in Mittelwert
135
 adc wh,null                ;hineinlegen,
136
 std y+4,wh                 ;Mittelwert und
137
 std y+2,wl                 ;Nachkommawert wieder sichern
138
 lsr wh                     ;Mittelwert halbieren (255 -> 127)
139
 mov wl,wh                  ;Kopie davon
140
 lsr wl                     ;nochmal
141
 lsr wl                     ;vierteln (127 -> 31)
142
 sub wh,wl                  ;vom halben Mittelwert abziehen (127 -> 96)
143
 subi wh,-64                ;Positionswert auf 64 bis 160 verschieben
144
 std y+6,wh                 ;und für Inrerrupt mundgerecht sichern
145
 ld wl,y+                   ;neues MUX-Bitmuster holen
146
 out admux,wl               ;und einstellen
147
 cpi yl,low(adcn)           ;letzte ADC-Quelle erreicht?
148
 brne mainloop_1            ;nein...
149
 ldi yl,low(adcq)           ;ja, Pointer wieder auf Start setzen
150
mainloop_1:
151
 sbi adcsra,adsc            ;ADC neu starten
152
 rjmp mainloop              ;nochmal...
153
154
;-------------------------------------------------------------------
155
156
TIM0_COMPA:
157
 cbi portb,impa             ;Ausgangsimpuls deaktivieren
158
 reti                       ;fertig, zurück...
159
160
161
TIM0_OVF:
162
 in srsk,sreg               ;PSW sichern
163
 dec pauz                   ;Pausenzähler runterzählen
164
 brne tim0_ovf_end          ;abgelaufen? - nein, weiter...
165
 sbi portb,impa             ;ja, Impuls setzen
166
 lds it0,pos1               ;erstmal Position 1 vermuten
167
 sbis pinb,ste              ;Steuereingang betätigt? - nein...
168
 lds it0,pos2               ;Position 2 holen und als
169
 out ocr0a,it0              ;Abschalt-Termin für Impuls vereinbaren
170
 ldi pauz,ipause            ;Pausenzähler auf Startwert setzen
171
tim0_ovf_end:
172
 out sreg,srsk              ;PSW wiederherstellen
173
 reti                       ;fertig, zurück...