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...
|