-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIVC_Tracer.asm
1715 lines (1579 loc) · 46.5 KB
/
IVC_Tracer.asm
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
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;------------------------------------------------------------------------------
; Автоматическое снятие ВАХ солнечного модуля
;
; (C) 2017-2020 Vitaliy Zinoviev
; https://github.com/nf-zvv/IVC_Tracer
;
; Hardware:
; PinBoard II rev.3 by DiHalt
;
; Compile:
; avrasm2.exe -S labels.tmp -fI -W+ie -C V2E -o IVC_Tracer.hex -d IVC_Tracer.obj
; -e IVC_Tracer.eep -m IVC_Tracer.map -l IVC_Tracer.lst IVC_Tracer.asm
;
; Burn flash via JTAG:
; avrdude -c jtag1 -P com4 -b 115200 -p m16 -U flash:w:IVC_Tracer.hex
;
; History
; =======
; 04.12.18 Заменен АЦП на MCP3204, написаны соответствующие подпрограммы
; 06.12.18 Добавлена проверка наличия в EEPROM корректного числа
; 01.03.20 Вывод значений тока и напряжения изучамого ФЭП в натуральных единицах
; 01.03.20 Упрощен и улучшен код для работы с EEPROM
; 02.03.20 Добавлена возможность прямого (от ХХ к КЗ) и обратного (от КЗ к ХХ)
; хода ЦАП при автоматическом снятии ВАХ
;
;------------------------------------------------------------------------------
#define F_CPU (11059200)
;.DEVICE ATmega16A
.NOLIST
.include "m16Adef.inc"
.include "macro.asm"
.include "eeprom_macro.asm"
.include "LCD4_macro.inc"
.include "uart_macro.asm"
.LIST
.LISTMAC ; Включить разворачивание макросов
;------------------------------------------------------------------------------
; Глобальные регистры
;
; r2 - нулевой регистр
; r7 - используется энкодером
;------------------------------------------------------------------------------
; Нулевой регистр
.def __zero_reg__ = r2
; Используется энкодером
.def __enc_reg__ = r7
.equ true = 1
.equ false = 0
; Флаги
.equ enc_left_spin = 0
.equ enc_right_spin = 1
.equ btn_press = 2
.equ btn_long_press = 3
.equ update = 4
;-------------------------------------------
.equ UART_IN_FULL = 0 ; Приемный буфер UART полон
;.equ UART_OUT_FULL = 1 ; Буфер отправки UART полон
.equ UART_STR_RCV = 2 ; Получена строка по UART
.equ UART_CR = 3 ; Флаг получения кода CR (0x0D) возврат каретки
;-------------------------------------------
;.equ adc_ok = 6
;.equ need_adc = 5
;.equ ADS1115_RDY = 6
;-------------------------------------------
; Размеры буферов UART (255 max)
.equ MAXBUFF_IN = 64 ; Размер входящего буфера
.equ IVC_MAX_RECORDS = 100
;-------------------------------------------
; Таймер T0 |
;-------------------------------------------|
; время до переполнения таймера в милисекундах
#define period_T0 1
; вычисление начального значения
#define start_count_T0 (0x100-(period_T0*F_CPU/(64*1000)))
; настройка предделителя 64
#define T0_Clock_Select (0<<CS02)|(1<<CS01)|(1<<CS00)
;-------------------------------------------
; Таймер T1 |
;-------------------------------------------|
; время до переполнения таймера в милисекундах
#define period_T1 500
; вычисление начального значения
#define start_count_T1 (0x10000-(period_T1*F_CPU/(1024*1000)))
;-------------------------------------------
; LED |
;-------------------------------------------|
.equ LED_PORT = PORTB
.equ LED_PIN = 3
;-------------------------------------------
; DAC |
;-------------------------------------------|
.equ DAC_CS_PORT = PORTB
.equ DAC_CS_DDR = DDRB
.equ DAC_CS = 4
;-------------------------------------------
; HW SPI |
;-------------------------------------------|
.equ SPI_PORT = PORTB
.equ SPI_DDR = DDRB
.equ SPI_PIN = PINB
.equ SPI_SS = 4
.equ SPI_MOSI = 5
.equ SPI_MISO = 6
.equ SPI_SCK = 7
;-------------------------------------------
; BUTTON |
;-------------------------------------------|
.equ BUTTON_PORT = PORTD
.equ BUTTON_DDR = DDRD
.equ BUTTON_PIN = PIND
.equ BUTTON = PD7
;-------------------------------------------
; Encoder |
;-------------------------------------------|
.equ ENC_A = PC6
.equ ENC_B = PC7
.equ ENC_PORT = PORTC
.equ ENC_DDR = DDRC
.equ ENC_PIN = PINC
;-----------------------------------
; Подключение LCD1602 к МК ATmega16 |
;-----------------------------------|
; МК | LCD |
;-----------------------------------|
; PB0 ( 1 выв.) | RS ( 4 выв.) |
; PB1 ( 2 выв.) | RW ( 5 выв.) |
; PB2 ( 3 выв.) | E ( 6 выв.) |
; PA7 (33 выв.) | D7 (14 выв.) |
; PA6 (34 выв.) | D6 (13 выв.) |
; PA5 (35 выв.) | D5 (12 выв.) |
; PA4 (36 выв.) | D4 (11 выв.) |
;-----------------------------------
#define Default_DAC_STEP 0x0005 ; 5
#define Default_IVC_DAC_START 0x0744 ; 1860
#define Default_IVC_DAC_END 0x092e ; 2350
#define Default_IVC_DAC_STEP 0x000a ; 10
#define Default_CH0_DELTA 0x09c1 ; 2497
#define Default_ADC_V_REF 0x1372 ; 4978
#define Default_ACS712_KI 0x00b9 ; 185
#define Default_RESDIV_KU 0x0001 ; 1
#define Default_VAH_DELAY 0x0032 ; 50
;===================================EEPROM=====================================
.eseg
.org 0x100
EEPROM_TEST: .db 0 ; для проверки, если равно 0xFF, то EEPROM чиста и надо проинициализировать
E_DAC_STEP: .dw Default_DAC_STEP
E_IVC_DAC_START: .dw Default_IVC_DAC_START
E_IVC_DAC_END: .dw Default_IVC_DAC_END
E_IVC_DAC_STEP: .dw Default_IVC_DAC_STEP
E_CH0_DELTA: .dw Default_CH0_DELTA
E_ADC_V_REF: .dw Default_ADC_V_REF
E_ACS712_KI: .dw Default_ACS712_KI
E_RESDIV_KU: .dw Default_RESDIV_KU
E_VAH_DELAY: .dw Default_VAH_DELAY
;====================================DATA======================================
.dseg
DAC: .byte 2
DAC_STEP: .byte 2
;------------------------
ButtonCounter: .byte 2 ; количество тиков при нажатой кнопке энкодера
Flags: .byte 1 ; флаги для энкодера
UART_Flags: .byte 1 ; флаги для UART
;------------------------
IVC_DAC_START: .byte 2
IVC_DAC_END: .byte 2
IVC_DAC_STEP: .byte 2
;------------------------
; Калибровка
CH0_DELTA: .byte 2
ADC_V_REF: .byte 2
ACS712_KI: .byte 2
RESDIV_KU: .byte 2
;------------------------
VAH_DELAY: .byte 2
;------------------------
; Zero-ended string
STRING: .byte 30
;------------------------
IVC_ARRAY: .byte 2*2*IVC_MAX_RECORDS
;------------------------
;====================================CODE======================================
.cseg
.org 0000
rjmp RESET
.include "vectors_m16.inc"
;==============================================================================
; Обработчики прерываний
; Interrupt Handlers
;==============================================================================
;------------------------------------------------------------------------------
; Обработчик UART
;------------------------------------------------------------------------------
.include "uart_irq.asm"
;------------------------------------------------------------------------------
; Прерывание таймера T0 по переполнению
; Обслуживание энкодера и кнопки
; Переполнение таймера каждую 1 мс
;------------------------------------------------------------------------------
OVF0_IRQ:
push r16
in r16,SREG
push r16
push r17
push r24
push r25
; переинициализация таймера
ldi r16,start_count_T0
OutReg TCNT0,r16
;sbi PORTB,1 ; тестовый СД вкл.
; поучение текущего состояния энкодера
in r16,ENC_PIN
andi r16,(1<<ENC_A)|(1<<ENC_B)
swap r16
lsr r16
lsr r16
; если предыдущее состояние равно текущему - выходим
mov r17,__enc_reg__ ; загружаем последовательность состояний
andi r17,0b00000011 ; отделяем только последнее
cp r17,r16 ; сравниваем
breq OVF0_IRQ_EXIT ; не изменилось - выходим
; если же состояние изменилось
lsl __enc_reg__ ; два раза
lsl __enc_reg__ ; сдвигаем
or __enc_reg__,r16 ; добавляем новое состояние на освободившееся место
; сравниваем получившуюся последовательность
mov r17,__enc_reg__
cpi r17,0b11100001
brne next_spin
; установка флага
lds r16,Flags
ori r16,(1<<enc_left_spin)
sts Flags,r16
clr __enc_reg__
next_spin:
cpi r17,0b11010010
brne OVF0_IRQ_EXIT
; установка флага
lds r16,Flags
ori r16,(1<<enc_right_spin)
sts Flags,r16
clr __enc_reg__
OVF0_IRQ_EXIT:
;cbi PORTB,1 ; тестовый СД выкл.
;--------------------------- Обработка нажатия на кнопку ---------------------------
; До тех пор, пока флаг btn_long_press не сброшен, игнорируем нажание
lds r16,Flags
sbrc r16,btn_long_press
rjmp ovf0_exit ; если флаг установлен, то выходим
; считываем состояние кнопки
sbis BUTTON_PIN,BUTTON
rjmp int1_low ; если кнопка нажата, переходим на int1_low
; если кнопка не нажата (или уже отпущена?)
lds r24,ButtonCounter+0
lds r25,ButtonCounter+1
;ldi r16,0
;ldi r17,0
;cp r24,r16
;cpc r25,r17
;breq ovf0_exit
ldi r16,200
ldi r17,0
cp r24,r16
cpc r25,r17
brlo too_little_ticks ; мало удерживали кнопку
; итак, набралось достаточно тиков
; считаем это коротким нажатием
; устанавливаем флаг короткого нажатия
lds r16,Flags
ori r16,(1<<btn_press)
sts Flags,r16
; и обнуляем ButtonCounter:
too_little_ticks:
; если набралось до 164 тиков:
; недостаточно долго держали,
; либо ложное срабатывание
; обнуляем ButtonCounter
;clr r16
sts ButtonCounter+0,__zero_reg__
sts ButtonCounter+1,__zero_reg__
rjmp ovf0_exit
int1_low:
; если кнопка нажата (INT1=0), то ButtonCounter++
lds r24,ButtonCounter+0
lds r25,ButtonCounter+1
ldi r16,low(1000)
ldi r17,high(1000)
cp r24,r16
cpc r25,r17
brsh long_button_press ; набралось много тиков (длинное нажатие)
; если недостаточно, просто увеличиваем счетчик и выходим
adiw r24,1
sts ButtonCounter+0,r24
sts ButtonCounter+1,r25
rjmp ovf0_exit
long_button_press:
; устанавливаем флаг длинного нажатия
; (удержание кнопки нажатой)
; возведение флага
lds r16,Flags
ori r16,(1<<btn_long_press)
sts Flags,r16
; обнуляем ButtonCounter
sts ButtonCounter+0,__zero_reg__
sts ButtonCounter+1,__zero_reg__
ovf0_exit:
pop r25
pop r24
pop r17
pop r16
out SREG,r16
pop r16
reti
;------------------------------------------------------------------------------
; Обработчик переполнения таймера T1
; Запрос на обновление времени из RTC
;------------------------------------------------------------------------------
OVF1_IRQ:
push r16
in r16,SREG
push r16
;----------------
; Усанавливаем флаг
lds r16,Flags
ori r16,(1<<update)
sts Flags,r16
; переинициализация таймера
ldi r16,high(start_count_T1)
OutReg TCNT1H,r16
ldi r16,low(start_count_T1)
OutReg TCNT1L,r16
;----------------
pop r16
out SREG,r16
pop r16
reti
;==============================================================================
; EEPROM code
;==============================================================================
;------------------------------------------------------------------------------
; Инициализация EEPROM
;------------------------------------------------------------------------------
EEPROM_PRELOAD:
ldi r16,low(EEPROM_TEST) ; Загружаем адрес ячейки EEPROM
ldi r17,high(EEPROM_TEST) ; из которой хотим прочитать байт
rcall EERead ; (OUT: r18)
cpi r18,0xFF
breq EEPROM_INIT ; если равно 0xFF - память пуста, надо инициализировать
ret ; иначе - выходим
EEPROM_INIT:
ldi r16,low(EEPROM_TEST)
ldi r17,high(EEPROM_TEST)
clr r18
rcall EEWrite
EEPROM_WRITE_WORD E_DAC_STEP,Default_DAC_STEP
EEPROM_WRITE_WORD E_IVC_DAC_START,Default_IVC_DAC_START
EEPROM_WRITE_WORD E_IVC_DAC_END,Default_IVC_DAC_END
EEPROM_WRITE_WORD E_IVC_DAC_STEP,Default_IVC_DAC_STEP
EEPROM_WRITE_WORD E_CH0_DELTA,Default_CH0_DELTA
EEPROM_WRITE_WORD E_ADC_V_REF,Default_ADC_V_REF
EEPROM_WRITE_WORD E_ACS712_KI,Default_ACS712_KI
EEPROM_WRITE_WORD E_RESDIV_KU,Default_RESDIV_KU
EEPROM_WRITE_WORD E_VAH_DELAY,Default_VAH_DELAY
ret
;------------------------------------------------------------------------------
; Восстановление переменных из EEPROM в RAM
;------------------------------------------------------------------------------
EEPROM_RESTORE_VAR:
EEPROM_READ_WORD E_DAC_STEP,DAC_STEP
EEPROM_READ_WORD E_IVC_DAC_START,IVC_DAC_START
EEPROM_READ_WORD E_IVC_DAC_END,IVC_DAC_END
EEPROM_READ_WORD E_IVC_DAC_STEP,IVC_DAC_STEP
EEPROM_READ_WORD E_CH0_DELTA,CH0_DELTA
EEPROM_READ_WORD E_ADC_V_REF,ADC_V_REF
EEPROM_READ_WORD E_ACS712_KI,ACS712_KI
EEPROM_READ_WORD E_RESDIV_KU,RESDIV_KU
EEPROM_READ_WORD E_VAH_DELAY,VAH_DELAY
ret
;==============================================================================
; Main code
;==============================================================================
RESET:
; Stack init
ldi r16, low(RAMEND)
out SPL, r16
ldi r16, high(RAMEND)
out SPH, r16
; Обнуление памяти и регистров (объем кода: 80 байт прошивки)
.include "coreinit.inc"
; Нулевой регистр
clr __zero_reg__
; Аналоговый компаратор выключен
ldi r16,1<<ACD
out ACSR,r16
; Port A Init
ldi r16,0b11110000
out DDRA,r16
ldi r16,0b00000000
out PORTA,r16
; Port B Init
ldi r16,0b11111111
out DDRB,r16
ldi r16,0b00000000
out PORTB,r16
; Port C Init
ldi r16,0b00000011
out DDRC,r16
ldi r16,0b11000011
out PORTC,r16
; Port D Init
ldi r16,0b00000010
out DDRD,r16
ldi r16,0b11000100
out PORTD,r16
sts Flags,__zero_reg__
sts UART_Flags,__zero_reg__
;---------------------
; Инициализация UART
;---------------------
USART_INIT
;---------------------
; Инициализация индикатора
INIT_LCD
; Инициализация SPI
rcall SPI_INIT
; Инициализация АЦП
rcall ADC_INIT
; Инициализация ЦАП
rcall DAC_INIT
;------------------------------------------------------------------
; Инициализация таймера Т0
;------------------------------------------------------------------
; Переполнение таймера каждую 1 мс
;clr r16
;out TCCR0,r16
; инициализация начального значения таймера
ldi r16,start_count_T0
OutReg TCNT0,r16
; разрешение прерывания таймера T0 по переполнению
InReg r16,TIMSK
ori r16,(1<<TOIE0)
OutReg TIMSK,r16
; Настройка предделителя 64
ldi r16,T0_Clock_Select
OutReg TCCR0,r16
;------------------------------------------------------------------
;------------------------------------------------------------------
; Инициализация таймера Т1
;------------------------------------------------------------------
; инициализация начального значения таймера
; от этого значения таймер будет считать до переполнения
ldi r16,high(start_count_T1)
OutReg TCNT1H,r16
ldi r16,low(start_count_T1)
OutReg TCNT1L,r16
; разрешение прерывания таймера по переполнению
InReg r16,TIMSK
ori r16,(1<<TOIE1)
OutReg TIMSK,r16
; Включить таймер Т1
ldi r16,5 ; Установка предделителя 1024
OutReg TCCR1B,r16
;------------------------------------------------------------------
; Инициализация интерпретатора команд UART
call UART_PARSER_INIT
; Восстановить переменные из EEPROM
rcall EEPROM_PRELOAD
rcall EEPROM_RESTORE_VAR
sei ; Разрешить прерывания
; Отправить 'Start' в UART
;rcall UART_START
; Начальные значения
sts ButtonCounter+0,__zero_reg__
sts ButtonCounter+1,__zero_reg__
; Начальные значения
sts DAC+0,__zero_reg__
sts DAC+1,__zero_reg__
;------------------------------------------------------------------------------
; Главный цикл. Проверяем флаги
;------------------------------------------------------------------------------
main:
lds r16,Flags
sbrc r16,enc_left_spin
rcall DEC_DAC
lds r16,Flags
sbrc r16,enc_right_spin
rcall INC_DAC
lds r16,Flags
sbrc r16,btn_long_press
rcall BTN_LONG_PRESS_EVENT
lds r16,Flags
sbrc r16,btn_press
rcall BTN_PRESS_EVENT
lds r16,Flags
sbrc r16,update
rcall UPDATE_ALL
lds r16,UART_Flags
sbrc r16,UART_STR_RCV
rcall UART_RX_PARSE
; на всякий случай от переполнения входного буфера
lds r16,UART_Flags
sbrc r16,UART_IN_FULL
rcall UART_RX_PARSE
rjmp main
;------------------------------------------------------------------------------
; Кратковременное нажалие на кнопку
;------------------------------------------------------------------------------
BTN_PRESS_EVENT:
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << btn_press)
sts Flags,r16
sei
rcall SCREEN_0
rcall SCREEN_1
rcall SCREEN_2
rcall SCREEN_3
; Показать меню
; 1. Шаг энкодера для ЦАП
; 2. Начальное значение ЦАП для АСВАХ
; 3. Конечное значение ЦАП для АСВАХ
; 4. Шаг ЦАП для АСВАХ
; Калибровочные коэффициенты
ret
;------------------------------------------------------------------------------
; Шаг энкодера для ЦАП
;------------------------------------------------------------------------------
SCREEN_0:
LCDCLR ; очистка экрана
LCD_COORD 4,0 ; курсор
; Вывести строку на дисплей
ldi ZL,low(DAC_step_const*2)
ldi ZH,high(DAC_step_const*2)
rcall FLASH_CONST_TO_LCD
LCD_COORD 5,1 ; курсор
WR_DATA '<'
lds XL,DAC_STEP+0
lds XH,DAC_STEP+1
rcall DEC4_TO_LCD
WR_DATA '>'
;ldi r16,100
;rcall WaitMiliseconds
; обработка событий
SCREEN_0_EVENT_LOOP:
lds r16,Flags
sbrc r16,enc_left_spin
rcall DEC_DAC_STEP
sbrc r16,enc_right_spin
rcall INC_DAC_STEP
sbrc r16,btn_press
rjmp SCREEN_0_EXIT
rjmp SCREEN_0_EVENT_LOOP
SCREEN_0_EXIT:
ldi r16,low(E_DAC_STEP+0)
ldi r17,high(E_DAC_STEP+0)
lds r18,DAC_STEP+0
rcall EEWrite
ldi r16,low(E_DAC_STEP+1)
ldi r17,high(E_DAC_STEP+1)
lds r18,DAC_STEP+1
rcall EEWrite
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << btn_press)
sts Flags,r16
sei
LCDCLR ; очистка экрана
ret
;------------------------------------------------------------------------------
; Начальное значение ЦАП для АСВАХ
;------------------------------------------------------------------------------
SCREEN_1:
LCDCLR ; очистка экрана
LCD_COORD 0,0 ; курсор
; Вывести строку на дисплей
ldi ZL,low(IVC_DAC_start_const*2)
ldi ZH,high(IVC_DAC_start_const*2)
rcall FLASH_CONST_TO_LCD
LCD_COORD 5,1 ; курсор
WR_DATA '<'
lds XL,IVC_DAC_START+0
lds XH,IVC_DAC_START+1
rcall DEC4_TO_LCD
WR_DATA '>'
;ldi r16,100
;rcall WaitMiliseconds
; обработка событий
SCREEN_1_EVENT_LOOP:
lds r16,Flags
sbrc r16,enc_left_spin
rcall DEC_IVC_DAC_START
sbrc r16,enc_right_spin
rcall INC_IVC_DAC_START
sbrc r16,btn_press
rjmp SCREEN_1_EXIT
rjmp SCREEN_1_EVENT_LOOP
SCREEN_1_EXIT:
ldi r16,low(E_IVC_DAC_START+0)
ldi r17,high(E_IVC_DAC_START+0)
lds r18,IVC_DAC_START+0
rcall EEWrite
ldi r16,low(E_IVC_DAC_START+1)
ldi r17,high(E_IVC_DAC_START+1)
lds r18,IVC_DAC_START+1
rcall EEWrite
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << btn_press)
sts Flags,r16
sei
LCDCLR ; очистка экрана
ret
;------------------------------------------------------------------------------
; Конечное значение ЦАП для АСВАХ
;------------------------------------------------------------------------------
SCREEN_2:
LCDCLR ; очистка экрана
LCD_COORD 0,0 ; курсор
; Вывести строку на дисплей
ldi ZL,low(IVC_DAC_end_const*2)
ldi ZH,high(IVC_DAC_end_const*2)
rcall FLASH_CONST_TO_LCD
LCD_COORD 5,1 ; курсор
WR_DATA '<'
lds XL,IVC_DAC_END+0
lds XH,IVC_DAC_END+1
rcall DEC4_TO_LCD
WR_DATA '>'
;ldi r16,100
;rcall WaitMiliseconds
; обработка событий
SCREEN_2_EVENT_LOOP:
lds r16,Flags
sbrc r16,enc_left_spin
rcall DEC_IVC_DAC_END
sbrc r16,enc_right_spin
rcall INC_IVC_DAC_END
sbrc r16,btn_press
rjmp SCREEN_2_EXIT
rjmp SCREEN_2_EVENT_LOOP
SCREEN_2_EXIT:
ldi r16,low(E_IVC_DAC_END+0)
ldi r17,high(E_IVC_DAC_END+0)
lds r18,IVC_DAC_END+0
rcall EEWrite
ldi r16,low(E_IVC_DAC_END+1)
ldi r17,high(E_IVC_DAC_END+1)
lds r18,IVC_DAC_END+1
rcall EEWrite
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << btn_press)
sts Flags,r16
sei
LCDCLR ; очистка экрана
ret
;------------------------------------------------------------------------------
; Шаг ЦАП для АСВАХ
;------------------------------------------------------------------------------
SCREEN_3:
LCDCLR ; очистка экрана
LCD_COORD 0,0 ; курсор
; Вывести строку на дисплей
ldi ZL,low(IVC_DAC_step_const*2)
ldi ZH,high(IVC_DAC_step_const*2)
rcall FLASH_CONST_TO_LCD
LCD_COORD 5,1 ; курсор
WR_DATA '<'
lds XL,IVC_DAC_STEP+0
lds XH,IVC_DAC_STEP+1
rcall DEC4_TO_LCD
WR_DATA '>'
;ldi r16,100
;rcall WaitMiliseconds
; обработка событий
SCREEN_3_EVENT_LOOP:
lds r16,Flags
sbrc r16,enc_left_spin
rcall DEC_IVC_DAC_STEP
sbrc r16,enc_right_spin
rcall INC_IVC_DAC_STEP
sbrc r16,btn_press
rjmp SCREEN_3_EXIT
rjmp SCREEN_3_EVENT_LOOP
SCREEN_3_EXIT:
ldi r16,low(E_IVC_DAC_STEP+0)
ldi r17,high(E_IVC_DAC_STEP+0)
lds r18,IVC_DAC_STEP+0
rcall EEWrite
ldi r16,low(E_IVC_DAC_STEP+1)
ldi r17,high(E_IVC_DAC_STEP+1)
lds r18,IVC_DAC_STEP+1
rcall EEWrite
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << btn_press)
sts Flags,r16
sei
LCDCLR ; очистка экрана
ret
;------------------------------------------------------------------------------
; IVC_DAC_START
;------------------------------------------------------------------------------
DEC_IVC_DAC_START:
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << enc_left_spin)
sts Flags,r16
sei
lds r24,IVC_DAC_START+0 ; уменьшаемое
lds r25,IVC_DAC_START+1
lds r26,DAC_STEP+0 ; вычитаемое
lds r27,DAC_STEP+1
cp r24,r26
cpc r25,r27
brlo DEC_IVC_DAC_START_TO_ZERO
rcall DECREMENT2 ; результат в r25:r24
rjmp DEC_IVC_DAC_START_SET
DEC_IVC_DAC_START_TO_ZERO:
; если уменьшаемое меньше вычитаемого, то просто обнуляем уменьшаемое
clr r24
clr r25
DEC_IVC_DAC_START_SET:
sts IVC_DAC_START+0,r24
sts IVC_DAC_START+1,r25
LCD_COORD 6,1 ; курсор
lds XL,IVC_DAC_START+0
lds XH,IVC_DAC_START+1
rcall DEC4_TO_LCD
DEC_IVC_DAC_START_EXIT:
ret
;------------------------------------------------------------------------------
INC_IVC_DAC_START:
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << enc_right_spin)
sts Flags,r16
sei
lds r24,IVC_DAC_START+0
lds r25,IVC_DAC_START+1
lds r26,DAC_STEP+0
lds r27,DAC_STEP+1
; Прибавляем шаг к текущему значению ЦАП
rcall INCREMENT2 ; результат в r25:r24
; Проверяем, не превышает ли результат 4096
ldi r26,low(4096)
ldi r27,high(4096)
cp r24,r26
cpc r25,r27
brlo INC_IVC_DAC_START_SET
; если превышает, то принудительно устанавливаем 4095
ldi r24,low(4095)
ldi r25,high(4095)
INC_IVC_DAC_START_SET:
; Сохраняем результат
sts IVC_DAC_START+0,r24
sts IVC_DAC_START+1,r25
; Выводим значение на дисплей
LCD_COORD 6,1 ; курсор
lds XL,IVC_DAC_START+0
lds XH,IVC_DAC_START+1
rcall DEC4_TO_LCD
INC_IVC_DAC_START_EXIT:
ret
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; IVC_DAC_END
;------------------------------------------------------------------------------
DEC_IVC_DAC_END:
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << enc_left_spin)
sts Flags,r16
sei
lds r24,IVC_DAC_END+0 ; уменьшаемое
lds r25,IVC_DAC_END+1
lds r26,DAC_STEP+0 ; вычитаемое
lds r27,DAC_STEP+1
cp r24,r26
cpc r25,r27
brlo DEC_IVC_DAC_END_TO_ZERO
rcall DECREMENT2 ; результат в r25:r24
rjmp DEC_IVC_DAC_END_SET
DEC_IVC_DAC_END_TO_ZERO:
; если уменьшаемое меньше вычитаемого, то просто обнуляем уменьшаемое
clr r24
clr r25
DEC_IVC_DAC_END_SET:
sts IVC_DAC_END+0,r24
sts IVC_DAC_END+1,r25
LCD_COORD 6,1 ; курсор
lds XL,IVC_DAC_END+0
lds XH,IVC_DAC_END+1
rcall DEC4_TO_LCD
DEC_IVC_DAC_END_EXIT:
ret
;------------------------------------------------------------------------------
INC_IVC_DAC_END:
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << enc_right_spin)
sts Flags,r16
sei
lds r24,IVC_DAC_END+0
lds r25,IVC_DAC_END+1
lds r26,DAC_STEP+0
lds r27,DAC_STEP+1
; Прибавляем шаг к текущему значению ЦАП
rcall INCREMENT2 ; результат в r25:r24
; Проверяем, не превышает ли результат 4096
ldi r26,low(4096)
ldi r27,high(4096)
cp r24,r26
cpc r25,r27
brlo INC_IVC_DAC_END_SET
; если превышает, то принудительно устанавливаем 4095
ldi r24,low(4095)
ldi r25,high(4095)
INC_IVC_DAC_END_SET:
; Сохраняем результат
sts IVC_DAC_END+0,r24
sts IVC_DAC_END+1,r25
; Выводим значение на дисплей
LCD_COORD 6,1 ; курсор
lds XL,IVC_DAC_END+0
lds XH,IVC_DAC_END+1
rcall DEC4_TO_LCD
INC_IVC_DAC_END_EXIT:
ret
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; IVC_DAC_STEP
;------------------------------------------------------------------------------
DEC_IVC_DAC_STEP:
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << enc_left_spin)
sts Flags,r16
sei
lds r24,IVC_DAC_STEP+0 ; уменьшаемое
lds r25,IVC_DAC_STEP+1
lds r26,DAC_STEP+0 ; вычитаемое
lds r27,DAC_STEP+1
cp r24,r26
cpc r25,r27
brlo DEC_IVC_DAC_STEP_TO_ZERO
rcall DECREMENT2 ; результат в r25:r24
rjmp DEC_IVC_DAC_STEP_SET
DEC_IVC_DAC_STEP_TO_ZERO:
; если уменьшаемое меньше вычитаемого, то просто обнуляем уменьшаемое
clr r24
clr r25
DEC_IVC_DAC_STEP_SET:
sts IVC_DAC_STEP+0,r24
sts IVC_DAC_STEP+1,r25
LCD_COORD 6,1 ; курсор
lds XL,IVC_DAC_STEP+0
lds XH,IVC_DAC_STEP+1
rcall DEC4_TO_LCD
DEC_IVC_DAC_STEP_EXIT:
ret
;------------------------------------------------------------------------------
INC_IVC_DAC_STEP:
; сброс флага
cli
lds r16,Flags
andi r16,~(1 << enc_right_spin)
sts Flags,r16
sei
lds r24,IVC_DAC_STEP+0
lds r25,IVC_DAC_STEP+1
lds r26,DAC_STEP+0
lds r27,DAC_STEP+1
; Прибавляем шаг к текущему значению ЦАП
rcall INCREMENT2 ; результат в r25:r24
; Проверяем, не превышает ли результат 4096
ldi r26,low(4096)
ldi r27,high(4096)
cp r24,r26
cpc r25,r27
brlo INC_IVC_DAC_STEP_SET
; если превышает, то принудительно устанавливаем 4095
ldi r24,low(4095)
ldi r25,high(4095)
INC_IVC_DAC_STEP_SET:
; Сохраняем результат
sts IVC_DAC_STEP+0,r24
sts IVC_DAC_STEP+1,r25
; Выводим значение на дисплей
LCD_COORD 6,1 ; курсор
lds XL,IVC_DAC_STEP+0
lds XH,IVC_DAC_STEP+1
rcall DEC4_TO_LCD
INC_IVC_DAC_STEP_EXIT:
ret
;------------------------------------------------------------------------------