Hallo users,
Für eine Geschwindigkeitsmessung/Berechnung brauche ich eine Division.
Nähmlich den Radumfang von 216.769893cm durch die gemessene Zeit
200.7040ms das Resultat wird alle 1 sec per UART gesendet...
Meine momentaner testcode zur division:
1 ;Register
2
3 .def mcover = r16 ; Mainclock overflow bei 1 sec (255)
4 .def t1 = r17 ; temp Register
5 .def stat = r18 ; Statusregister
6 .def z2 = r19 ; Timer für Warteschleifen
7 .def z3 = r20 ; Impulszähler
8 .def zeichen = r21 ; UART senderegister
9 .def mcl = r24 ; Mainclock low
10 .def mch = r25 ; Mainclock high
11
12
13 ;Konstanten
14 .equ PD = PORTD
15 .equ DD = DDRD
16
17 .equ PB = PORTB
18 .equ DB = DDRB
19
20 .equ F_CPU = 4000000 ; Systemtakt in Hz
21 .equ BAUD = 9600 ; Baudrate
22
23
24
25
26 ; Berechnungen
27 .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden
28 .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
29 .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille
30
31 .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
32 .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
33 .endif
34
35 ;Vektoren
36 .org 0x0000
37 rjmp configurations
38 .org 0x0004
39 rjmp timer2_overflow
40
41 ;Interrupts
42
43
44
45 timer2_overflow:
46
47 cpi mcl,low(15625)
48 brsh highbit
49 rjmp next_i
50 highbit:
51 cpi mch,high(15625)
52 brsh one_second_done
53 rjmp next_i
54 one_second_done:
55 ldi stat,1
56 cbi PB,1
57 cpi mcover,255 ; Maximal 255 sekunden (4.25 min)
58 breq mcover_zero
59 inc mcover
60 rjmp set_zero
61 mcover_zero:
62 clr mcover
63 inc mcover
64 set_zero:
65 ldi mcl,low(1) ; Mainclock zähler auf 1
66 ldi mch,high(0)
67 sbi PB,1
68 next_i:
69 adiw mcl,1
70 reti
71
72 ;Sprungprgramme:
73
74
75 lcd_number16:
76 ; Million
77
78 ; Million
79
80 lcd_100mil:
81
82 ldi t1, '0'-1
83 lcd_mil100:
84 inc t1
85 subi R26,low(100000000)
86 sbci R27,BYTE2(100000000)
87 sbci R28,BYTE3(100000000)
88 sbci R29,BYTE4(100000000)
89 brcc lcd_mil100
90 subi R26,low(-100000000)
91 sbci R27,BYTE2(-100000000)
92 sbci R28,BYTE3(-100000000)
93 sbci R29,BYTE4(-100000000)
94 mov zeichen,t1
95 rcall serout
96
97
98 lcd_10mil:
99
100 ldi t1, '0'-1
101 lcd_mil10:
102 inc t1
103 subi R26,low(10000000)
104 sbci R27,BYTE2(10000000)
105 sbci R28,BYTE3(10000000)
106 sbci R29,BYTE4(10000000)
107 brcc lcd_mil10
108 subi R26,low(-10000000)
109 sbci R27,BYTE2(-10000000)
110 sbci R28,BYTE3(-10000000)
111 sbci R29,BYTE4(-10000000)
112 mov zeichen,t1
113 rcall serout
114
115 lcd_mil:
116
117 ldi t1, '0'-1
118 lcd_mil1:
119 inc t1
120 subi R26,low(1000000)
121 sbci R27,BYTE2(1000000)
122 sbci R28,BYTE3(1000000)
123 sbci R29,BYTE4(10000000)
124 brcc lcd_mil1
125 subi R26,low(-1000000)
126 sbci R27,BYTE2(-1000000)
127 sbci R28,BYTE3(-1000000)
128 sbci R29,BYTE4(-10000000)
129 mov zeichen,t1
130 rcall serout
131
132
133
134 ; Hunderttausender
135 lcd_ht:
136
137 ldi t1, '0'-1
138
139 lcd_ht1:
140 inc t1
141 subi R26,low(100000)
142 sbci R27,BYTE2(100000)
143 sbci R28,BYTE3(100000)
144 brcc lcd_ht1
145 subi R26,low(-100000)
146 sbci R27,BYTE2(-100000)
147 sbci R28,BYTE3(-100000)
148 mov zeichen,t1
149 rcall serout
150
151 zt:
152 ; ** Zehntausender **
153 ldi t1, '0'-1
154 lcd_number1:
155 inc t1
156 subi R26, low(10000)
157 sbci R27, high(10000)
158 sbci R28, BYTE3(10000)
159 brcc lcd_number1
160 subi R26, low(-10000)
161 sbci R27, high(-10000)
162 sbci R28, BYTE3(-10000)
163 mov zeichen,t1
164 rcall serout
165
166
167 ; ** Tausender **
168 ldi t1, '0'-1
169 lcd_number2:
170 inc t1
171 subi R26, low(1000)
172 sbci R27, high(1000)
173 brcc lcd_number2
174 subi R26, low(-1000)
175 sbci R27, high(-1000)
176 mov zeichen,t1
177 rcall serout
178
179
180 ; ** Hunderter **
181 ldi t1, '0'-1
182 lcd_number3:
183 inc t1
184 subi R26, low(100)
185 sbci R27, high(100)
186 brcc lcd_number3
187 subi R26, (-100)
188 mov zeichen,t1 ; + 100 High-Byte nicht mehr erforderlich
189 rcall serout
190
191
192 ; ** Zehner **
193 ldi t1, '0'-1
194 lcd_number4:
195 inc t1
196 subi R26, 10
197 brcc lcd_number4
198 subi r26, -10
199 mov zeichen,t1
200 rcall serout
201
202
203 ; ** Einer **
204 ldi t1, '0'
205 add t1, R26
206 mov zeichen,t1
207 rcall serout
208
209 ldi zeichen,0x7C
210 rcall serout
211
212 serout:
213
214 sbis UCSRA,UDRE ; Warten bis UDR für das nächste
215 ; Byte bereit ist
216 rjmp serout
217 out UDR, zeichen
218 ret ; zurück zum Hauptprogramm
219
220
221 divi:
222
223 divid_init:
224
225 push R24
226 push R25
227 push R26
228 push R27
229
230 push R28
231 push R29
232 push R30
233 push R31
234
235 ldi R24,low(216769893)
236 ldi R25,BYTE2(216769893)
237 ldi R26,BYTE3(216769893)
238 ldi R27,BYTE4(216769893)
239
240
241 ldi R28,low(2007040)
242 ldi R29,BYTE2(2007040)
243 ldi R30,BYTE3(2007040)
244 ldi R31,BYTE4(2007040)
245
246 ldi t1,'0'-1
247
248 div_1:
249 inc t1
250 sub R24,R28
251 sbc R25,R29
252 sbc R26,R30
253 sbc R27,R31
254 brcc div_1
255 mov R26,t1
256 clr R27
257 clr R28
258 clr R29
259 rcall lcd_number16
260
261 pop R31
262 pop R30
263 pop R29
264 pop R28
265
266 pop R27
267 pop R26
268 pop R25
269 pop R24
270
271
272 ldi stat,0
273 rjmp main
274
275 brucke:
276 rjmp divi
277
278
279 configurations:
280
281 ldi t1,HIGH(RAMEND) ;Stackpointer HIGH
282 out SPH,t1
283
284 ldi t1,LOW(RAMEND) ;Stackpointer LOW
285 out SPL,t1
286
287 ldi t1,0x00 ;PortD als Eingang
288 out DD,t1
289
290 ldi t1,0xFF ;Pullups PortD aktivieren
291 out PD,t1
292
293 ldi t1,0xFF ;PortB als Ausgang
294 out DB,t1
295
296 ldi t1,0xFF ;PortB Pullups deaktiviert
297 out PB,t1
298
299 ldi t1,(1<<ISC01)|(1<<ISC00) ; Interrupt auf steigende flanke
300 out MCUCR,t1
301
302 ldi t1, HIGH(UBRR_VAL)
303 out UBRRH, t1
304 ldi t1, LOW(UBRR_VAL)
305 out UBRRL, t1
306
307 ldi t1,(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0) ;Senden aktivieren UART
308 out UCSRC,t1
309
310 sbi UCSRB,TXEN
311
312
313 ldi t1,(0<<CS22)|(0<<CS21)|(1<<CS20) ; Timer2 teiler 1
314 out TCCR2,t1
315
316 ldi t1,(1<<TOIE2) ; Interrupt bei Timer Interrupt
317 out TIMSK,t1
318
319 ldi mcl,low(1) ; Mainclock zähler mit 1 vorladen
320 ldi mch,high(0)
321
322 sei ; Aktiviere Interrupts
323
324 main:
325 cpi stat,1
326 breq brucke
327 rjmp main
Nun zum eigentlichen Problem. Bei der Ausgabe beim UART ist der Wert um
48 zu hoch. Also anstatt 108 bekomme ich 156. Bis jetzt habe ich noch
nicht nachvollziehen können ,WO sich diese 48 dazuaddieren...
Hab schon gedacht das der Timer mir die Zahlen durcheinander bringt, da
ich die selben Register verwende, aber ist auch ohne Aktivierten Timer
so.
Man könnte zwar jedes mal 48 subtrahieren, das wäre das Resultat auch
korrekt, möchte aber schon wissen, woran es liegt...
mfg Wukas
von
Nase (Gast)
24.07.2016 13:30
Lukas G. schrieb:
> das Resultat wird alle 1 sec per UART gesendet...
Am Rande: Geht es dir explizit darum, in Assembler zu programmieren?
Falls nicht, würde ich das angesichs der geforderten atemberaubenden
Performance von 1 Übertragung/Sekunde in drei Zeilen C verpacken,
einschließlich printf().
von
Yalu X.
(yalu )
(Moderator )
24.07.2016 13:31
Lukas G. schrieb:
> ldi t1,'0'-1
Der ASCII-Code von '0' ist 48.
Dämmert was? :)
Yalu X. schrieb:
> Der ASCII-Code von '0' ist 48.
>
> Dämmert was? :)
Jep, es lag daran. War ja echt trivial. Sch wieder was gelernt...
Danke vielmals
mfg Lukas
Nase schrieb:
> Am Rande: Geht es dir explizit darum, in Assembler zu programmieren?
Nein, aber ich habe mehr Erfahrung mit Assembler aus als mit C
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.