inter.asm


1
.NOLIST 
2
.INCLUDE "m8def.inc"
3
.LIST
4
5
        .DEF temp1   =   r16
6
        .DEF temp2   =   r17        
7
        .DEF alt   =   r18    ;alter Zustand(Drehgeber) allgemein
8
        .DEF cnt   =   r19    ;der Zähler(Drehgeber) allgemein
9
        .DEF pos   =   r20    ;Position(Drehgeber) allgemein
10
        .DEF spg   =   r21    ;Spannung der mini-PV-module
11
  
12
  
13
  .DEF Maske  =  r2    ;Maske für Drehgeber allgemein
14
  .DEF Teiler  =  r3    ;Teiler für Drehgeber allgemein
15
  .DEF pos_klein  =  r4    ;Position der Kleinanlage (auf 3,6 Grad genau) 
16
  .DEF pos_PV  =  r5    ;Position der PV-Anlage
17
  .DEF cnt_klein  =  r6    ;der Zähler--klein
18
  .DEF cnt_PV  =  r7    ;der Zähler--PV
19
  .DEF alt_PV  =  r8    ;alter Zustand Drehgeber-PV-Anlage
20
  .DEF alt_klein  =  r9    ;alter Zustand Drehgeber-Kleinanlage
21
  .DEF sec4  =  r10
22
  .DEF wind  =  r11
23
  .DEF myflag   =  r12    ;Bit 0 - Intervall Nachführung
24
            ;Bit 1 - Intervall Kleinanlage
25
            ;Bit 6 - alter Zustand Windmesser
26
            ;Bit 7 - Intervall Windmesser (4s)
27
  
28
  .def prescaler   =   r22
29
  .def sec  =   r23
30
  .def min  =   r24
31
  .def hour  =   r25
32
  ;.def day   =   r26
33
  
34
  ;Konstanten
35
  
36
  .EQU Kanal_spg  =   0b11000000  ;Kanal für ADC,Spannung-module
37
  .EQU Kanal_wind  =   0b11000001  ;Kanal für ADC, Windrichtung
38
  .EQU Teiler_klein =   4    ;Prescaler Drehgeber
39
  .EQU Teiler_PV   =   4    ;Prescaler Drehgeber
40
  .EQU Maske_klein=  0b00001100  ;Maske für Drehgeber-Anschluß
41
  .EQU Maske_PV   =  0b00110000
42
  .EQU MaxWind   =   100    ;maximale windgeschwindigkeit
43
  .EQU xtal  =   16000000  ;Taktfrequenz
44
  .EQU debounce   =   256    ;
45
  .EQU remainder   =   xtal - xtal / debounce * debounce
46
  .EQU wind_int  =  4  
47
  .EQU nachfue_int=  15
48
  .EQU sichpos_int=  30
49
  
50
51
.CSEG
52
  .ORG 0x00        ;Reset Handler
53
    RJMP init
54
    
55
;  .ORG  INT0addr      ; External Interrupt0 Vector Address
56
;    RETI
57
    
58
  .ORG  INT1addr      ; External Interrupt1 Vector Address
59
    RJMP windcount
60
    
61
;  .ORG  OC2addr       ; Output Compare2 Interrupt Vector Address
62
;    RETI
63
    
64
;  .ORG  OVF2addr      ; Overflow2 Interrupt Vector Address
65
;    RETI
66
    
67
;  .ORG  ICP1addr      ; Input Capture1 Interrupt Vector Address
68
;    RETI
69
    
70
  .ORG  OC1Aaddr      ; Output Compare1A Interrupt Vector Address
71
    RJMP Timer1
72
    
73
;  .ORG  OC1Baddr      ; Output Compare1B Interrupt Vector Address
74
;    RETI
75
;    
76
;  .ORG  OVF1addr      ; Overflow1 Interrupt Vector Address
77
;    RETI
78
    
79
;  .ORG  OVF0addr      ; Overflow0 Interrupt Vector Address
80
;    RETI
81
    
82
;  .ORG  SPIaddr       ; SPI Interrupt Vector Address
83
;    RETI
84
    
85
;  .ORG  URXCaddr      ; USART Receive Complete Interrupt Vector Address
86
;    RETI
87
    
88
;  .ORG  UDREaddr      ; USART Data Register Empty Interrupt Vector Address
89
;    RETI
90
    
91
;  .ORG  UTXCaddr      ; USART Transmit Complete Interrupt Vector Address
92
;    RETI
93
    
94
;  .ORG  ADCCaddr      ; ADC Interrupt Vector Address
95
;    RETI
96
    
97
;  .ORG  ERDYaddr      ; EEPROM Interrupt Vector Address
98
;    RETI
99
    
100
;  .ORG  ACIaddr       ; Analog Comparator Interrupt Vector Address
101
;    RETI
102
    
103
;  .ORG    TWIaddr          ; Irq. vector address for Two-Wire Interface
104
;    RETI
105
    
106
;  .ORG  SPMaddr       ; SPM complete Interrupt Vector Address
107
;    RETI
108
    
109
  ;.ORG  SPMRaddr       ; SPM complete Interrupt Vector Address
110
  ;  RETI
111
    
112
    
113
windcount:          ;wird bei Interrupt-Auslösung
114
    push temp1
115
    mov temp1, wind
116
    INC temp1      ;an PD3 ausgeführt
117
    mov wind, temp1
118
    pop temp1
119
    RETI
120
      
121
Timer1:
122
  push temp1
123
  in  temp1, sreg
124
;************************************************************************/
125
;*      Insert Key Debouncing Here      */
126
;************************************************************************/
127
128
  ldi  temp2, high( xtal / debounce - 1 )
129
  out  ocr1ah, temp2
130
  ldi  temp2, low( xtal / debounce - 1 )
131
  out  ocr1al, temp2
132
133
  dec  prescaler
134
  brne  _oci1
135
136
  ldi  prescaler, debounce
137
  INC  sec
138
    
139
  ldi  temp2, high( xtal / debounce + remainder - 1 )
140
  out  ocr1ah, temp2
141
  ldi  temp2, low( xtal / debounce + remainder - 1 )
142
  out  ocr1al, temp2
143
_oci1:
144
  out  sreg, temp1
145
  pop temp1
146
  reti
147
148
149
150
151
152
  
153
init:  
154
;********************************* stackpointer initialisieren
155
156
        ldi temp1, LOW(RAMEND)      ; LOW-Byte der untersten RAM-adresse
157
  out SPL, temp1
158
  ldi temp1, HIGH(RAMEND)           ; HIGH-Byte der obersten RAM-Adresse
159
  out SPH, temp1
160
  
161
;********************************* AD-Wandler  16MHz / 200kHz = 80 mind.
162
  
163
  ldi  temp1,0b00000111    
164
  out  ADCSR,temp1        
165
  
166
  cbi  ADCSR,ADIE      
167
  
168
  sbi  ADCSR,ADEN      ;AD einschalten/aktivieren  
169
    
170
    
171
;********************************************************* Ein-Ausgange festlegen  
172
  
173
  
174
  ldi TEMP1,0b11110010           ;0=input, 1=output 
175
  out DDRD,TEMP1               
176
                      
177
  ldi TEMP1,0b10001000           ; pull-up resistors(1) on inputs 
178
   out PORTD,TEMP1                
179
        
180
        ldi temp1, 0b00111111          ;Port B 
181
  out DDRB, temp1
182
183
  ldi temp1, 0b00000000          ;Port C 
184
  out DDRC, temp1
185
        
186
187
188
;*************************************************************************** RTC
189
190
  ldi  temp1, 1<<WGM12^1<<CS10
191
  out  TCCR1B, temp1
192
193
  ldi  temp1, high( xtal / debounce - 1 )
194
  out  ocr1ah, temp1
195
  ldi  temp1, low( xtal / debounce - 1 )
196
  out  ocr1al, temp1
197
  out  tcnt1l, temp1
198
  ldi  prescaler, debounce
199
200
  ldi  temp1, 1<<OCIE1A
201
  out  TIMSK, temp1
202
203
;******************************************************************* externe Interrupts
204
  ldi temp1, 0b00001010  ;INT0 und INT1 konfigurieren-fallende Flanke
205
  out MCUCR, temp1
206
  
207
  ldi temp1, 0b11000000  ;INT0 und INT1 aktivieren
208
  out GICR, temp1
209
210
  
211
  sei
212
213
;******************************************************************* Hauptprogramm
214
hauptprog:
215
216
NOP
217
218
;******* Drehgeber einmal einlesen
219
220
ldi temp1, Maske_klein        ;Maske festlegen
221
MOV Maske, temp1 
222
IN temp1,PINC                     ;einmal den aktuellen PortZustand laden
223
ANDI temp1,Maske_klein        ;Drehgeber-Bits maskieren
224
RCALL schieben01        ;und in 01-Position schieben
225
MOV alt_klein, temp1
226
227
ldi temp1, Maske_PV        ;und nochmal für anderen Drehgeber
228
MOV Maske, temp1
229
IN temp1,PINC                     
230
AND temp1, Maske    
231
RCALL schieben01    
232
MOV alt_PV, temp1
233
234
235
clr pos_klein          ;Position beider Drehgeber reset
236
clr pos_PV
237
clr cnt_klein
238
clr cnt_PV
239
240
rcall lcd_init            ;Display initialisieren
241
rcall lcd_clear           ;Display löschen
242
    
243
ldi  sec, 0          ;RTC mit 0 laden
244
ldi  min, 0
245
ldi   hour,0
246
247
rjmp main
248
249
;************************************************************ Sicherheitsposition
250
sichpos:
251
  SBIC PORTD,7        ;Notrelais schon an ??
252
  rjmp notrelais_an
253
  rjmp main
254
255
notrelais_an:
256
  CBI PORTD, 7        ;Notrelais an PD7 einschalten (0)
257
  
258
259
  
260
  
261
262
;****************** Normalfall
263
main:  
264
265
;Intervalle
266
267
cpi sec, wind_int
268
BREQ myflag7
269
;cpi min, nachfue_int
270
;BREQ myflag0
271
rjmp second
272
273
myflag7:MOV temp1, myflag
274
  SBR temp1, 7
275
  MOV myflag, temp1
276
  rjmp second
277
  
278
myflag0:MOV temp1, myflag
279
  SBR temp1, 0
280
  MOV myflag, temp1  
281
  rjmp second
282
283
;****RTC      
284
second:  
285
  cpi  sec, 60        ;----second
286
  breq  minute
287
  rjmp  main_weiter
288
  
289
minute: clr sec          ;minute
290
  inc min
291
  cpi min, 60
292
  breq hour
293
  rjmp main_weiter
294
  
295
hour:   clr min          ;hour
296
  inc hour
297
  cpi hour, 24
298
  breq day
299
  rjmp main_weiter
300
  
301
day:  clr hour        ;day
302
  nop
303
  rjmp main_weiter
304
  
305
306
307
308
main_weiter:  
309
  
310
    RCALL windmessung    ;windrichtg/geschw
311
    RCALL kleinanlage    ;Beste Position bestimmen
312
    ;RCALL nachfuehrung    ;zu bestem Wert nachführen
313
    ;RCALL speichern    ;Werte speichern
314
    ;RCALL ausgeben      ;Anzeige am LCD
315
    ;RCALL messen
316
    
317
    RJMP main
318
    
319
320
    
321
    
322
    
323
    
324
    cpi spg,MaxWind    ;Windgeschw. zu groß ?
325
    BRSH sichpos
326
    
327
    ;LDI temp1, 0x00    ;verzögerung abgelaufen ?? dann vergleich und evtl abschalten
328
    ;cpi temp1, sichpos_int
329
    BRLO sichpos_aus
330
    rjmp main
331
        
332
sichpos_aus:
333
    SBI PORTD, 7      ;Notrelais an PD7 ausschalten (1)
334
          rjmp main
335
    
336
  
337
338
339
340
341
342
343
344
;******************************************************************* ADC-Wandlung
345
analog_digital:      
346
347
;Single-Mode    
348
349
Main_Single:  sbi  ADCSR,ADSC    ;Start Wandlung
350
            ;das ADSC-Flag löscht sich
351
            ;selbst nach der Wandlung
352
            ;man kann es auch für busy? verwenden
353
354
AD_busy_:  sbis  ADCSR,ADIF    ;Flag, busy?
355
    rjmp  AD_busy_    ;springt raus, wenn fertig
356
    
357
    
358
    
359
Lesen_Single:  in  temp1,ADCL    ;Das Ergebnis steht in temp1,temp2  
360
    in  temp2,ADCH  
361
362
;Sollten nur 8 Bit = 256 Schritte notwendig sein, dann wie folgt:
363
364
;Auf256_:  ror  temp2      ;xxxxxxxN  c=N
365
;    ror  temp1      ;Nnnnnnnn  c=n
366
;    ror  temp2      ;xxxxxxxx  c=N
367
;    ror  temp1      ;NNnnnnnn  c=n
368
    
369
;    mov spg, temp1      ;Das Ergebnis steht in spg
370
    
371
ret
372
373
374
;******************************************************************** Nachführung
375
nachfuehrung:
376
377
  sbrs myflag, 0        ;intervall abgelaufen ?
378
  ret          ;zurück, wenn nicht
379
  
380
    
381
;**************** Werte für Drehgeber_PV zuweisen
382
    ;Maske    ---welcher Drehgeber wird verwendet
383
    ;alt    ---alter Drehgeber-zustand  
384
    ;cnt    --- alter counter-stand
385
    ;Teiler    ---Teiler
386
    ;pos    ---position des Drehgebers
387
  
388
  
389
  
390
    ldi temp1, Maske_PV
391
    mov Maske, temp1    
392
    mov alt, alt_PV    
393
    mov cnt, cnt_PV    
394
    ldi temp1, Teiler_PV
395
    mov Teiler, temp1    
396
    mov pos, pos_PV
397
        
398
    RCALL position      ;position bestimmen
399
    
400
    mov pos_PV, pos
401
    mov cnt_PV, cnt
402
    mov alt_PV, alt
403
          
404
  cp pos_klein, pos_PV      ;Positionsvergleich
405
  BRNE weiter2        ;gleich ?
406
  clr temp1        ;wenn ja, dann rechts- und linkslauf ausschalten
407
  out portD, temp1      ;ansonsten zu weiter2
408
  ret
409
weiter2:
410
  BRLO links
411
  BRSH rechts
412
  
413
  
414
  
415
links:  
416
  SBIS portD,4        ;schon an ??
417
  rjmp an_links
418
  ret
419
an_links:
420
  ldi temp1, 0b00010000           ;Relais für linkslauf anschalten
421
  out portD, temp1
422
  ret
423
  
424
  
425
  
426
  
427
rechts:
428
  SBIS portD,5        ;schon an ??
429
  rjmp an_rechts
430
  ret  
431
an_rechts:
432
  ldi temp1, 0b00100000           ;Relais für rechtslauf anschalten
433
  out portD, temp1
434
  ret
435
436
  
437
;******************************************************************* Kleinanlage
438
kleinanlage:
439
440
  sbrs myflag, 1        ;intervall abgelaufen ?
441
  rjmp wischer_aus
442
  rjmp messen
443
  
444
wischer_aus:
445
  CBI PORTD, 7        ;wischermotor ausschalten
446
  RET
447
  
448
messen:  
449
;Spannungsmessung der RWE-Schott mini-Solarmodule
450
;mit
451
;Leerlaufpannung  ;4,9V
452
;Lastspannung max  :3,6V
453
;Pmax      ;0,1W
454
;Kurzschlussstrom  ;35mA
455
;Laststrom max    :27mA
456
;
457
;Eingang ADC0 an PC0
458
459
  ldi  temp1,Kanal_spg      ;Kanal für ADC auswählen           ;
460
  out  ADMUX,temp1      ;
461
  rcall analog_digital      ;Wandlung durchführen
462
          
463
            ;Ergebnis in ADCL,ADCH
464
          
465
;**************** Werte für Drehgeber_klein zuweisen
466
    ;Maske    ---welcher Drehgeber wird verwendet
467
    ;alt    ---alter Drehgeber-zustand  
468
    ;cnt    --- alter counter-stand
469
    ;Teiler    ---Teiler
470
    ;pos    ---position des Drehgebers
471
472
473
    ldi temp1, Maske_klein
474
    mov Maske, temp1    
475
    mov alt, alt_klein    
476
    mov cnt, cnt_klein    
477
    ldi temp1, Teiler_klein
478
    mov Teiler, temp1    
479
    mov pos, pos_klein
480
        
481
    RCALL position      ;position bestimmen
482
    
483
    mov pos_klein, pos
484
    mov cnt_klein, cnt
485
    mov alt_klein, alt          
486
  
487
  SBIS portD,6        ;wischer schon an ??
488
  rjmp wischer_an
489
  ret
490
491
wischer_an:
492
  SBI PORTD, 6          ;wischer anschalten
493
  RET
494
  
495
496
;****************************************************************** Windmessung
497
windmessung:
498
;************ Geschwindigkeit
499
500
  ;nop
501
  ;ret
502
  
503
  SBRS myflag, 7        ; vier Sekunden vergangen ?
504
  RET
505
  rjmp calc
506
calc:
507
  lsr wind        ;wind/4= Hz, da pro Sekunde
508
  lsr wind
509
  RCALL ausgeben
510
  clr wind
511
  
512
  MOV temp1, myflag      ;Reset des 4-Sekunden Zählers
513
  CBR temp1, 7
514
  MOV myflag, temp1
515
  
516
  RET
517
  RJMP windrichtung
518
  
519
520
521
522
;************ windrichtung
523
524
windrichtung:
525
  ldi  temp1,Kanal_wind    ;Kanal für ADC auswählen           ;
526
  out  ADMUX,temp1      ;
527
528
  RCALL analog_digital      ;Wandlung durchführen
529
            ;Ergebnis in temp1,temp2
530
        
531
  ;vergleich mit Tabelle-------für Richtungsangabe
532
  
533
  
534
  RET
535
536
;;;;windmessung ENDE
537
538
;*********************************************************** Speichern der Daten
539
speichern:
540
  sbrs myflag, 0        ;intervall abgelaufen ?
541
  rjmp abspeichern
542
  ret
543
544
abspeichern:
545
  
546
  ;Zeit + höchste Windgeschw + Richtg+ beste Pos+Spg
547
  
548
  ;clr flag
549
  
550
  nop
551
  
552
ret
553
554
555
;****************************************************************** Display/UART
556
ausgeben:
557
  rcall lcd_home
558
  
559
  hex2bcd:
560
    push sec
561
    mov sec, myflag
562
    push r17
563
    push r18
564
    ldi  r18, -1 + '0'
565
  _bcd1:  inc  r18
566
    subi  sec, 100
567
    brcc  _bcd1
568
    ldi  r17, 10 + '0'
569
  _bcd2:  dec  r17
570
    subi  sec, -10
571
    brcs  _bcd2
572
    subi  sec, -'0'
573
  ;ret
574
  
575
  mov temp1,r18
576
  rcall lcd_data
577
  
578
  mov temp1,r17
579
  rcall lcd_data
580
  
581
  mov temp1,sec
582
  rcall lcd_data
583
  
584
  pop r18
585
  pop r17
586
  pop sec
587
    
588
  ;------------
589
  
590
  ;rcall lcd_secondline
591
  ldi  ZH,high(2*ausgabe)     ;Lade oberen Teil der 
592
             ;ByteAdresse in ZH
593
  ldi  ZL,low(2*ausgabe)      ;Lade unteren Teil der 
594
             ;ByteAdresse in ZL
595
  rcall lcd_out        ;Text ausgeben
596
597
  ret
598
599
    
600
;********************************************************************** Tabellen
601
602
ausgabe:        
603
 .db " Anzeige funktioniert!",0
604
 
605
 
606
 .NOLIST
607
 .INCLUDE "routines.asm"
608
 .INCLUDE "position.asm"
609
 .LIST