1 | ;Voltmeter mit Tiny24 und dreistelliger Lichtschacht-Anzeige mit
|
2 | ;gemeinsamer Anode je Ziffer und PNP-Transistoren als Digit-Treiber.
|
3 |
|
4 | .include "tn24def.inc" ;Portnamen
|
5 |
|
6 | .equ skalier=125 ;Skalierfaktor
|
7 | .equ bremse=50 ;Anzeigebremse (verlangsamt Berechnung)
|
8 |
|
9 | .dseg ;SRAM
|
10 | .org sram_start ;Anfang
|
11 | bimu: .byte 24 ;Bitmuster für Zeichensatz (16-Bit)
|
12 | ;12 Segment-Bitmuster für PortB (0..11)
|
13 | ;12 Segment-Bitmuster für PortA (12..23)
|
14 |
|
15 | zeichen: .byte 12 ;Zeichen- und Digit-Bitmuster der 3 Stellen
|
16 | ;3 Digit-Bitmuster für PortB (0..2)
|
17 | ;3 Digit-Bitmuster für PortA (3..5)
|
18 | ;3 Segment-Bitmuster für PortB (6..8)
|
19 | ;3 Segment-Bitmuster für PortA (9..11)
|
20 |
|
21 | .def null=r3 ;immer 0
|
22 | .def srsk=r4 ;SREG-Kopie
|
23 | .def mwn=r5 ;Messwert / Mittelwert Nachkomma
|
24 | .def mwl=r6 ;Messwert / Mittelwert Low
|
25 | .def mwh=r7 ;Messwert / Mittelwert High
|
26 | .def scheibe=r8 ;Zeitscheibe
|
27 | .def sfl=r9 ;Skalierfaktorzähler Low
|
28 | .def sfh=r10 ;Skalierfaktorzähler High
|
29 | .def ausa=r11 ;Bitmuster Digits aus PortA
|
30 | .def ausb=r12 ;Bitmuster Digits aus PortB
|
31 |
|
32 | .def wert1=r16 ;Low-Byte Zwischenwert zur Skalierung
|
33 | .def wert2=r17 ;Mid-Byte
|
34 | .def wert3=r18 ;High-Byte
|
35 |
|
36 | .def digit=r21 ;Digit-Zähler für Anzeige-Multiplexing
|
37 | .def iwl=r22 ;ISR-Working L
|
38 | .def iwh=r23 ;ISR-Working H
|
39 | .def wl=r24 ;Working L
|
40 | .def wh=r25 ;Working H
|
41 |
|
42 | .cseg
|
43 | .org 0
|
44 | rjmp RESET ;Reset Handler
|
45 | rjmp nix;EXT_INT0 ;IRQ0 Handler
|
46 | rjmp nix;PCINT0 ;PCINT0 Handler
|
47 | rjmp nix;PCINT1 ;PCINT1 Handler
|
48 | rjmp nix;WATCHDOG ;Watchdog Interrupt Handler
|
49 | rjmp nix;TIM1_CAPT ;Timer1 Capture Handler
|
50 | rjmp nix;TIM1_COMPA ;Timer1 Compare A Handler
|
51 | rjmp nix;TIM1_COMPB ;Timer1 Compare B Handler
|
52 | rjmp nix;TIM1_OVF ;Timer1 Overflow Handler
|
53 | rjmp nix;TIM0_COMPA ;Timer0 Compare A Handler
|
54 | rjmp nix;TIM0_COMPB ;Timer0 Compare B Handler
|
55 | rjmp nix;TIM0_OVF ;Timer0 Overflow Handler
|
56 | rjmp nix;ANA_COMP ;Analog Comparator Handler
|
57 | rjmp ADCC ;ADC Conversion Handler
|
58 | rjmp nix;EE_RDY ;EEPROM Ready Handler
|
59 | rjmp nix;USI_STR ;USI STart Handler
|
60 | rjmp nix;USI_OVF ;USI Overflow Handler
|
61 | nix:
|
62 | rjmp nix
|
63 | ;
|
64 | RESET:
|
65 | ldi wl,low(RAMEND) ;Stackpointer-Init
|
66 | out SPL,wl
|
67 | clr null ;immer 0
|
68 | clr mwn ;Messwert
|
69 | clr mwl ;erstmal
|
70 | clr mwh ;auf 0
|
71 |
|
72 | out porta,null ;alle Ports
|
73 | out portb,null ;auf L-Pegel,
|
74 | ldi wl,$fe ;alle Portpins
|
75 | out ddra,wl ;außer
|
76 | ldi wl,7 ;PA0
|
77 | out ddrb,wl ;als Ausgang
|
78 | sbi didr0,0 ;Digitalteil vom ADC-Port trennen
|
79 |
|
80 | ldi zl,low(charset*2) ;Bitmuster
|
81 | ldi zh,high(charset*2) ;im Flash
|
82 | ldi yl,bimu ;Array
|
83 | clr yh ;im SRAM
|
84 | reset1:
|
85 | lpm r0,z+ ;Segment-Bits für PortA
|
86 | std y+12,r0 ;in obere Array-Hälfte kopieren
|
87 | lpm r0,z+ ;Segment-Bits für PortB
|
88 | st y+,r0 ;in untere Array-Hälfte kopieren
|
89 | cpi yl,bimu+12 ;alle 12 Werte fertig?
|
90 | brne reset1 ;nein, nochmal...
|
91 |
|
92 | ldi zl,low(stelle*2) ;Bitmuster für Digits
|
93 | ldi zh,high(stelle*2) ;im Flash
|
94 | ldi yl,zeichen ;Array für Zeichen und Digits im SRAM
|
95 | lds wh,bimu+12 ;Bitmuster für 0 PortA
|
96 | lds wl,bimu ;und PortB holen
|
97 | reset2:
|
98 | std y+9,wh ;Startwert PortA in oberes Array-Viertel
|
99 | std y+6,wl ;Startwert PortB in drittes Array-Viertel
|
100 | lpm r0,z+ ;Digit-Bits für PortA
|
101 | std y+3,r0 ;in zweites Array-Viertel kopieren
|
102 | lpm r0,z+ ;Digit-Bits für PortB
|
103 | st y+,r0 ;in unteres Array-Viertel kopieren
|
104 | cpi yl,zeichen+3 ;alle 3 Werte fertig?
|
105 | brne reset2 ;nein, nochmal...
|
106 | lpm ausa,z+ ;Bitmuster für Digits aus
|
107 | lpm ausb,z+ ;holen
|
108 | ; ldi wl,(1<<refs1)+0 ;ADC0 (PA0) gegen interne 1,1V
|
109 | ldi wl,0 ;ADC0 (PA0) gegen Vcc (5V)
|
110 | out admux,wl ;rechtsbündig messen
|
111 | ldi wl,(1<<aden)|(1<<adsc)|(1<<adate)|(1<<adie)+3 ;ADC freilaufend mit
|
112 | out adcsra,wl ;Interrupt und Vorteiler 8 (125kHz) starten
|
113 | ldi yl,zeichen ;Startwert für Display-Multiplexing in der ISR
|
114 | ldi zh,0 ;für Mainloop vorbereiten
|
115 | ldi wl,low(skalier+257) ;Startwert
|
116 | mov sfl,wl ;für
|
117 | ldi wl,high(skalier+257) ;Skalierung (Kumulation)
|
118 | mov sfh,wl ;des Messwertes
|
119 | ldi wl,1<<se ;Sleep-Mode IDLE
|
120 | out mcucr,wl ;vobereiten
|
121 | sei ;Enable interrupts
|
122 |
|
123 | mainloop: ;Hauptschleife
|
124 | tst scheibe ;Zeitscheibe auf 0?
|
125 | breq machwert ;ja, Wert machen...
|
126 |
|
127 | sleep ;bis zum nächsten Interrupt pennen
|
128 | rjmp mainloop ;nochmal...
|
129 |
|
130 | machwert: ;Job der Hauptschleife, gibt Messwert an Anzeige
|
131 | ldi wl,-bremse ;Startwert Anzeigebremse
|
132 | mov scheibe,wl ;setzen
|
133 | dec sfl ;Rundenzähler L runter
|
134 | brne machwert4 ;unten? - nein, weiter sammeln...
|
135 | dec sfh ;ja, H-Byte auch
|
136 | brne machwert4 ;unten? - nein, weiter sammeln...
|
137 | ;Zähler unten angekommen, Wert ausgeben
|
138 |
|
139 | ldi wh,high(1000) ;Kopie für CPC
|
140 | cpi wert2,low(1000) ;Wert über 999?
|
141 | cpc wert3,wh
|
142 | brlo machwert1 ;nein, berechnen...
|
143 | lds wh,bimu+10+12 ;Bitmuster für '-' (PortA)
|
144 | lds wl,bimu+10 ;(PortB) holen
|
145 | ldi zl,zeichen+3 ;für alle 3 Stellen
|
146 | std z+0,wl ;Minuszeichen
|
147 | std z+1,wl ;eintragen
|
148 | std z+2,wl
|
149 | std z+3,wh
|
150 | std z+4,wh
|
151 | std z+5,wh
|
152 | rjmp mainloop ;fertig...
|
153 | machwert1:
|
154 | ldi zl,bimu-1 ;Z-Pointer auf 1 Adresse unter Ziffer 0
|
155 | machwert2:
|
156 | inc zl ;Index (Hunderter) hoch,
|
157 | subi wert2,low(100) ;Hundert
|
158 | sbci wert3,high(100) ;wegnehmen
|
159 | brsh machwert2 ;schon unter 0? - nein, nochmal...
|
160 | ldd wh,z+12 ;ja, Ziffer-Bitmuster PoertA
|
161 | ldd wl,z+0 ;und PortB holen
|
162 | ldi zl,zeichen ;und
|
163 | std z+6,wl ;in linke Stelle PortB
|
164 | std z+9,wh ;und PortA speichern
|
165 | subi wert2,low(-100) ;Unterlauf
|
166 | sbci wert3,high(-100) ;korregieren
|
167 | ldi zl,bimu-1 ;Z-Pointer auf 1 Adresse unter Ziffer 0
|
168 | machwert3:
|
169 | inc zl ;Index (Zehner) hoch,
|
170 | subi wert2,low(10) ;Zehn wegnehmen
|
171 | brsh machwert3 ;schon unter 0? - nein, nochmal...
|
172 | ldd wh,z+12 ;ja, Ziffer-Bitmuster PoertA
|
173 | ldd wl,z+0 ;und PortB holen
|
174 | ldi zl,zeichen ;und
|
175 | std z+7,wl ;in mittlere Stelle PortB
|
176 | std z+10,wh ;und PortA speichern
|
177 | subi wert2,low(-10) ;Unterlauf korregieren
|
178 | ldi zl,bimu ;Z-Pointer auf Adresse Ziffer 0
|
179 | add zl,wert2 ;Rest dazu
|
180 | ldd wh,z+12 ;ja, Ziffer-Bitmuster PoertA
|
181 | ldd wl,z+0 ;und PortB holen
|
182 | ldi zl,zeichen ;und
|
183 | std z+8,wl ;in rechte Stelle PortB
|
184 | std z+11,wh ;und PortA speichern
|
185 | clr wert1 ;Kumulation
|
186 | clr wert2 ;wieder bei 0
|
187 | clr wert3 ;beginnen
|
188 | ldi wl,low(skalier+257) ;Startwert
|
189 | mov sfl,wl ;für
|
190 | ldi wl,high(skalier+257) ;Skalierung (Kumulation)
|
191 | mov sfh,wl ;des Messwertes
|
192 |
|
193 | machwert4: ;Sammeln der Messwerte
|
194 | add wert1,mwl ;Low-Byte Mittelwert addieren
|
195 | adc wert2,mwh ;High-Byte mit Übertrag
|
196 | adc wert3,null ;Null mit Übertrag
|
197 | rjmp mainloop ;fertig...
|
198 |
|
199 |
|
200 | adcc: ;ISR, ADC-Messung fertig
|
201 | in srsk,sreg ;SREG sichern
|
202 | out porta,ausa ;alle Segmente an PortA
|
203 | out portb,ausb ;und PortB erstmal aus
|
204 | ldd iwl,y+9 ;Segmente für PortA holen,
|
205 | ldd iwh,y+3 ;Digits für PortA holen,
|
206 | or iwl,iwh ;Digit.Bits einkopieren (mixen)
|
207 | out porta,iwl ;und ausgeben,
|
208 | ldd iwl,y+6 ;Segmente für PortB holen,
|
209 | ld iwh,y+ ;Digits für PortB holen und Pointer hoch
|
210 | or iwl,iwh ;Digit.Bits einkopieren (mixen)
|
211 | out portb,iwl ;und ausgeben,
|
212 | cpi yl,zeichen+3 ;alle 3 Werte fertig?
|
213 | brne adcc1 ;nein...
|
214 | ldi yl,zeichen ;ja, von vorn beginnen
|
215 | adcc1:
|
216 | sub mwn,mwl ;1/256
|
217 | sbc mwl,mwh ;des Mittelwert-Inhaltes
|
218 | sbc mwh,null ;rausnehmen und wegwerfen,
|
219 | in iwl,adcl ;ADC-Wert
|
220 | in iwh,adch ;einlesen
|
221 | add mwn,iwl ;1/256 des neuen Messwertes
|
222 | adc mwl,iwh ;in den Mittelwert
|
223 | adc mwh,null ;reinlegen
|
224 | inc scheibe ;Zeitscheibe weiterdrehen
|
225 | ldi iwl,(1<<aden)|(1<<adsc)|(1<<adate)|(1<<adie)+3 ;ADC freilaufend mit
|
226 | ; out adcsra,wl ;Interrupt und Vorteiler 8 (125kHz) starten
|
227 | ; out sreg,srsk ;SREG wiederherstellen
|
228 | reti ;fertig und zurück...
|
229 |
|
230 |
|
231 | charset:;Zeichensatz L-aktiv,
|
232 | ; I RML ;I=Eingang, RML=rechts/mitte/links
|
233 | ; gcbfade. ;Segmente
|
234 | .db 0b10000000,0b000 ;0
|
235 | .db 0b10011110,0b000 ;1
|
236 | .db 0b01010000,0b000 ;2
|
237 | .db 0b00010010,0b000 ;3
|
238 | .db 0b00001110,0b000 ;4
|
239 | .db 0b00100010,0b000 ;5
|
240 | .db 0b00100000,0b000 ;6
|
241 | .db 0b10010110,0b000 ;7
|
242 | .db 0b00000000,0b000 ;8
|
243 | .db 0b00000010,0b000 ;9
|
244 | .db 0b01111110,0b000 ;-
|
245 | .db 0b11111110,0b000 ;Leer
|
246 |
|
247 | stelle: ;Digit
|
248 | ; I RML ;I=Eingang, RML=rechts/mitte/links
|
249 | .db 0b00000000,0b110 ;links
|
250 | .db 0b00000000,0b101 ;mitte
|
251 | .db 0b00000000,0b011 ;rechts
|
252 | .db 0b11111110,0b111 ;aus
|
253 |
|
254 |
|
255 |
|
256 | /*
|
257 | charset:;Zeichensatz L-aktiv,
|
258 | ; I RML ;I=Eingang, RML=rechts/mitte/links
|
259 | ; gfedcba ;Segmente
|
260 | .db 0b10000000,0b000 ;0
|
261 | .db 0b11110010,0b000 ;1
|
262 | .db 0b01001000,0b000 ;2
|
263 | .db 0b01100000,0b000 ;3
|
264 | .db 0b00110010,0b000 ;4
|
265 | .db 0b00100100,0b000 ;5
|
266 | .db 0b00000100,0b000 ;6
|
267 | .db 0b11110000,0b000 ;7
|
268 | .db 0b00000000,0b000 ;8
|
269 | .db 0b00100000,0b000 ;9
|
270 | .db 0b01111110,0b000 ;-
|
271 | .db 0b11111110,0b000 ;Leer
|
272 |
|
273 | stelle: ;Digit
|
274 | ; I RML ;I=Eingang, RML=rechts/mitte/links
|
275 | .db 0b00000000,0b110 ;links
|
276 | .db 0b00000000,0b101 ;mitte
|
277 | .db 0b00000000,0b011 ;rechts
|
278 | .db 0b11111110,0b111 ;aus
|
279 |
|
280 | */
|
281 |
|
282 |
|
283 | /*
|
284 | charset:;Zeichensatz L-aktiv, IN = Eingang, L, M, R = Digits
|
285 | ;(A7=IN A6=G A5=B A4=R A3=M A2=F A1=A A0=L B2=C B1=D B0=E)
|
286 | ; I RM L ;I=Eingang, RML=rechts/mitte/links
|
287 | ; .gb..fa. cde ;Segmente
|
288 | .db 0b01000000,0b000 ;0
|
289 | .db 0b01000110,0b011 ;1
|
290 | .db 0b00000100,0b100 ;2
|
291 | .db 0b00000100,0b001 ;3
|
292 | .db 0b00000010,0b011 ;4
|
293 | .db 0b00100000,0b001 ;5
|
294 | .db 0b00100000,0b000 ;6
|
295 | .db 0b01000100,0b011 ;7
|
296 | .db 0b00000000,0b000 ;8
|
297 | .db 0b00000000,0b001 ;9
|
298 | .db 0b00100110,0b111 ;-
|
299 | .db 0b01100110,0b111 ;Leer
|
300 |
|
301 | stelle: ;Digit (links=A0 mitte=A3 rechts=A4, H-aktiv)
|
302 | ; I RM L ;I=Eingang, RML=rechts/mitte/links
|
303 | .db 0b00000001,0b000 ;links
|
304 | .db 0b00001000,0b000 ;mitte
|
305 | .db 0b00010000,0b000 ;rechts
|
306 | .db 0b01111111,0b111 ;aus
|
307 | */
|