1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
|
/*
* Fernbedienung.asm
*
* Created: 08.10.2015 14:35:11
* Author: Erich
*/
.INCLUDE "tn2313def.inc"
.EQU sbuff0, 0 ; serieller Puffer 0 bis
.EQU sbuff1, 1
.EQU sbuff2, 2
.EQU sbuff3, 3
.EQU sbuff4, 4 ; 4
.EQU lastB, 5 ; letzter Zustand von PINB
.EQU lt1p0l, 6 ; letzte Flankenposition PINB0 (Timer 1) low
.EQU lt1p0h, 7 ; dito high
.EQU lt1p1l, 8 ; dito PINB1 low
.EQU lt1p1h, 9 ; dito high
.EQU bcnt0, 10 ; Bitzähler PINB0
.EQU bcnt1, 11 ; Bitzähler PINB1
.EQU t1moml, 12 ; momentane Position Timer 1 low
.EQU t1momh, 13 ; dito high
.EQU aender, 14 ; Änderungen in PINB
rjmp RESET
reti
reti
reti
reti
reti
reti
reti
reti
rjmp TIMER0COMPA ; Timer0 Compare Match A
reti
reti
reti
reti
reti
reti
reti
RESET:
ldi r16,lo8(RAMEND) ; Stackpointer initialisieren
out SPL,r16
ldi r16,0x80
out CLKPR,r16
ldi r16,0x00
out CLKPR,r16 ; System-Vorteiler auf 1
ldi r16,0x03
out PRR,r16 ; Clocks: Timer/Counter 1 an, Timer/Counter 0 an, USI aus, ADC aus ... zum Stromsparen
ldi r16,0x00
out WDTCSR,r16 ; Watchdog aus
ldi r16,0x02
out PORTA,r16 ; 6x n.d., PORTA1 high (RS232-Sender), kein Pull-up an PORTA0 (RS232-Empfänger)
ldi r16,0x00
out PORTB,r16 ; 2x n.d., kein Pull-up an PORTB1 (IR-Empfänger 1) & PORTB0 (IR-Empfänger 0)
ldi r16,0x06
out DDRA,r16 ; Ausgänge: PORTA1 (RS232-Sender), PORTA2 (Test)
ldi r16,0x00
out DDRB,r16 ; keine Ausgänge auf PORTB
ldi r16,0x02 ; Timer0 Compare-Match-A Interrupt an
out TIMSK0,r16
ldi r16,104
out OCR0A,r16
ldi r16,0x02 ; CTC-Modus: Periode = OCR0A = 104 -> 9600 baud
out TCCR0A,r16
ldi r16,0x02 ; Vorteiler 8 für Timer 0
out TCCR0B,r16
ldi r16,0x02 ; Vorteiler 8 für Timer 1
out TCCR1B,r16
ldi r16,0x21 ; Start-Bit und
mov sbuff0,r16
ldi r16,0x15 ; 0x48 ('H') und Start-Bit und
mov sbuff1,r16
ldi r16,0x56 ; 0x61 ('a') und Start-Bit und
mov sbuff2,r16
ldi r16,0x48 ; 0x21 ('!') und Start-Bit
mov sbuff3,r16
ldi r16,0x0d ; und 0x0d (CR)
mov sbuff4,r16
in lt1p0l,TCNT1L
in lt1p0h,TCNT1H
movw lt1p1l,lt1p0l
in lastB,PINB
ldi r16,0x03
and lastB,r16
sei
MAINLOOP:
in r16,PINB
andi r16,0x03
eor r16,lastB
breq MAINLOOP ; keine Änderung
eor lastB,r16 ; Änderung übernehmen
mov aender,r16 ; Änderungen merken
in t1moml,TCNT1L
in t1momh,TCNT1H ; Zählerstand holen
movw r16,t1moml ; und kopieren
sbrs aender,0
rjmp PIN0WACKELTNICHT
sub r16,lt1p0l
sbc r17,lt1p0h ; r17:r16 = TimeDiff
movw lt1p0l,t1moml ; aktuellen Zählerstand als alten setzen
subi r16,0xb1
sbci r17,0x01 ; - 865/2 = 0x01b1 = halbes Bit
brcs RESET0 ; zu kurzes Bit -> Fehler!
subi r16,0x61
sbci r17,0x03 ; - 865 = 0x0361 = kurzes Bit
brcc KEINKURZESBIT0
clr r16 ; wird einfach gespeichert!
inc bcnt0
rjmp WEITER0
KEINKURZESBIT0:
subi r16,0x61
sbci r17,0x03 ; - 865 = 0x0361 = (noch ein) kurzes Bit (= langes Bit)
brcc RESET0 ; zu langes Bit -> Fehler
inc bcnt0
inc bcnt0
ldi r16,0x01 ; wird doppelt gespeichert!
WEITER0:
clc
sbrs lastB,0 ; alten Pinzustand
sec ; nach C
lds r17,(0x0060) ; das erste der insgesamt vier Bytes von empfangenen Bits
rol r17
sts (0x0060),r17
lds r17,(0x0061)
rol r17
sts (0x0061),r17
lds r17,(0x0062)
rol r17
sts (0x0062),r17
lds r17,(0x0063)
rol r17
sts (0x0063),r17
brcs RESET0 ; es kamen mehr als 32 Bits an -> Fehler!
subi r16,0x01
brcc WEITER0
ldi r16,0x1a
cp bcnt0,r16
brcs ENDE0 ; noch keine 26 klein-Bits angekommen -> Ende
ldi r16,0x1c
cp bcnt0,r16
brcc RESET0 ; mehr als 27 klein-Bits angekommen -> Fehler!
sbrs lastB,0 ; jetziger Zustand ist high?
rjmp ENDE0 ; nein -> dann ist es auch nicht fertig!
lds r16,(0x0063) ; das letzte Byte
ori r16,0x40 ; die übrigen Bits (also die Bits, die eben nicht empfangen wurden)
sts (0x0063),r16 ; des zuerst "empfangenen" Bytes werden alternierend auf 1 gesetzt
ldi r26,0x60
ldi r27,0x00 ; Startadresse in den Speicher,
mov r16,bcnt0 ; Bitanzahl in r16
rcall VERSENDEN ; und ab durch die serielle Schnittstelle
RESET0:
ldi r16,0x05 ; Startbit + '01'=0 (also 0. Empfänger)
sts (0x0060),r16
ldi r16,0x00
sts (0x0061),r16
sts (0x0062),r16
sts (0x0063),r16 ; empfangene Bits initialisieren
clr bcnt0 ; Bit-Zähler auf 0 setzen
ENDE0:
PIN0WACKELTNICHT:
sbrs aender,1
rjmp MAINLOOP
movw r16,t1moml ; Zählerstand rücksichern
sub r16,lt1p1l
sbc r17,lt1p1h ; r17:r16 = TimeDiff
movw lt1p1l,t1moml ; aktuellen Zählerstand als alten setzen
subi r16,0xb1
sbci r17,0x01 ; - 865/2 = 0x01b1 = halbes Bit
brcs RESET1 ; zu kurzes Bit -> Fehler!
subi r16,0x61
sbci r17,0x03 ; - 865 = 0x0361 = kurzes Bit
brcc KEINKURZESBIT1
clr r16 ; wird einfach gespeichert!
inc bcnt1
rjmp WEITER1
KEINKURZESBIT1:
subi r16,0x61
sbci r17,0x03 ; - 865 = 0x0361 = (noch ein) kurzes Bit (= langes Bit)
brcc RESET1 ; zu langes Bit -> Fehler
inc bcnt1
inc bcnt1
ldi r16,0x01 ; wird doppelt gespeichert!
WEITER1:
clc
sbrs lastB,1 ; alten Pinzustand
sec ; nach C
lds r17,(0x0064) ; das erste der insgesamt vier Bytes von empfangenen Bits
rol r17
sts (0x0064),r17
lds r17,(0x0065)
rol r17
sts (0x0065),r17
lds r17,(0x0066)
rol r17
sts (0x0066),r17
lds r17,(0x0067)
rol r17
sts (0x0067),r17
brcs RESET1 ; es kamen mehr als 32 Bits an -> Fehler!
subi r16,0x01
brcc WEITER1
ldi r16,0x1a
cp bcnt1,r16
brcs ENDE1 ; noch keine 26 klein-Bits angekommen -> Ende
ldi r16,0x1c
cp bcnt1,r16
brcc RESET1 ; mehr als 27 klein-Bits angekommen -> Fehler!
sbrs lastB,1 ; jetziger Zustand ist high?
rjmp ENDE1 ; nein -> dann ist es auch nicht fertig!
lds r16,(0x0067) ; das letzte Byte
ori r16,0x40 ; die übrigen Bits (also die Bits, die eben nicht empfangen wurden)
sts (0x0067),r16 ; des zuerst "empfangenen" Bytes werden alternierend auf 1 gesetzt
ldi r26,0x64
ldi r27,0x00 ; Startadresse in den Speicher,
mov r16,bcnt1 ; Bitanzahl in r16
rcall VERSENDEN ; und ab durch die serielle Schnittstelle
RESET1:
ldi r16,0x03 ; Startbit + '10'=0 (also 1. Empfänger)
sts (0x0064),r16
ldi r16,0x00
sts (0x0065),r16
sts (0x0066),r16
sts (0x0067),r16 ; empfangene Bits initialisieren
clr bcnt1 ; Bit-Zähler auf 0 setzen
ENDE1:
PIN1WACKELTNICHT:
rjmp MAINLOOP
TIMER0COMPA:
push r16
in r16,SREG
push r16
sbrc sbuff0,0
sbi PORTA,1
sbrs sbuff0,0
cbi PORTA,1
; clc ; so werden die Daten zyklisch gesendet
; sbrc r0,0
sec
ror sbuff4
ror sbuff3
ror sbuff2
ror sbuff1
ror sbuff0
pop r16
out SREG,r16
pop r16
reti ; TIMER0COMPA
WARTEAUFSENDBUFFER: ; wartet, bis der Sende-Puffer leer ist
ldi r16,0xff
cp sbuff4,r16
brne WARTEAUFSENDBUFFER
cp sbuff3,r16
brne WARTEAUFSENDBUFFER
cp sbuff2,r16
brne WARTEAUFSENDBUFFER
cp sbuff1,r16
brne WARTEAUFSENDBUFFER
cp sbuff0,r16
brne WARTEAUFSENDBUFFER
ret ; WARTEAUFSENDBUFFER
VERSENDEN: ; versendet r16/2+1 Bit Manchester-kodierte Daten
; aus DRAM, Adresse r27:r26 (=X), base64-kodiert
movw r18,r26 ; Speicheradresse merken
sbrc r16,0
rjmp VERSENDENNICHTSCHIEBEN
sec
ld r17,X
rol r17
st X+,r17
ld r17,X
rol r17
st X+,r17
ld r17,X
rol r17
st X+,r17
ld r17,X
rol r17
st X+,r17
movw r26,r18
VERSENDENNICHTSCHIEBEN:
lsr r16
ldi r17,0x0d
cpse r16,r17 ; nicht 26 halb-Bits?
ret ; -> Fehler!
; ld r18,X+
; ld r18,X+
; ld r18,X+
; ld r17,X+
; clr r16
; rjmp AUSLESESCHLEIFENENDE
ldi r20,0x03
ALTERNIERENDTESTSCHLEIFE:
ld r16,X+
mov r17,r16
lsr r16
eor r16,r17
andi r16,0x55
ldi r17,0x55
cpse r16,r17 ; Bits alternierend?
ret ; nein -> Ende!
subi r20,0x01
brcs ALTERNIERENDTESTSCHLEIFEENDE
rjmp ALTERNIERENDTESTSCHLEIFE
ALTERNIERENDTESTSCHLEIFEENDE:
movw r26,r18
clr r18
clr r17
clr r16
ldi r19,0x10 ; 16 Bits zu lesen (13 reale Bits + 3 Geistbits)
AUSZENSCHLEIFE:
ld r20,X+
ldi r21,0x04 ; 4 Bits je Byte
INNENSCHLEIFE:
ror r20
ror r20
rol r18
rol r17
rol r16
subi r19,0x01
breq AUSLESESCHLEIFENENDE
subi r21,0x01
brne INNENSCHLEIFE
rjmp AUSZENSCHLEIFE
AUSLESESCHLEIFENENDE:
; die zu sendenden 18 Bit Informationen liegen in r16(2):r17(8):r18(8)
rol r18
rol r17
rol r16
rol r18
rol r17
rol r16
lsr r18
lsr r18
rol r17
rol r16
rol r17
rol r16
lsr r17
lsr r17
rcall TOBASE64
push r16
mov r16,r17
rcall TOBASE64
push r16
mov r16,r18
rcall TOBASE64
push r16
; die zu sendenden Zeichen liegen auf dem Stack (3., 2., 1.)
rcall WARTEAUFSENDBUFFER
cli
clc
; aus logistischen Gründen füllen wir den Puffer von hinten nach vorne
ldi r16,0x0d ; 0x0d (CR)
mov sbuff4,r16
pop r17
ldi r16,0x40
sec
ror r17
ror r16
ror r17
ror r16
mov sbuff3,r17
pop r17
swap r17
mov r18,r17
andi r18,0x0f
or r16,r18
mov sbuff2,r16
andi r17,0xf0
ori r17,0x04
pop r18
clr r16
clc
rol r18
rol r16
sec
rol r18
rol r16
or r16,r17
mov sbuff1,r16
mov sbuff0,r18
sei
VERSENDENENDE:
ret ; VERSENDEN
TOBASE64: ; konvertiert Bit 0-5 von r16 in base64
; 0-25: A-Z: +0x41 (=-0xbf)
; 26-51: a-z: +0x47 (=-0xb9)
; 52-61: 0-9: -0x04
; 62: +: -0x13
; 63: /: -0x10
andi r16,0x3f ; zur Sicherheit
cpi r16,26
brcc NICHT0BIS25
subi r16,0xbf
ret ; TOBASE64
NICHT0BIS25:
cpi r16,52
brcc NICHT26BIS51
subi r16,0xb9
ret ; TOBASE64
NICHT26BIS51:
cpi r16,62
brcc NICHT52BIS61
subi r16,0x04
ret ; TOBASE64
NICHT52BIS61:
cpi r16,63
brcc NICHT62
subi r16,0x13
ret ; TOBASE64
NICHT62:
subi r16,0x10
ret ; TOBASE64
|