K(готово) / Документ Microsoft Word
.docxlist p = 16f628
# Include <p16f628.inc>
__CONFIG _CP_OFF & _WDT_ON & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _MCLRE_ON & _LVP_OFF
# Define IDAT PORTB, 0; керування сигналом DI
# Define ICLC PORTB, 1; керування сигналом SK
# DEFINE VHOD PORTB, 2; ВХІД ВІД РОЗПОДІЛЬНИКА
# DEFINE BANK0 BCF STATUS, RP0; ВКЛЮЧЕННЯ БАНКУ 0
# DEFINE BANK1 BSF STATUS, RP0; ВКЛЮЧЕННЯ БАНКУ 1
CARRY equ 0X00
CBLOCK 0X20
CNT1; МОЛОДШИй ОСЕРЕДОК ЛІЧИЛЬНИКА ДОВЖИНИ ІМПУЛЬСУ
CNT2; СТАРШий ОСЕРЕДОК ЛІЧИЛЬНИКА ДОВЖИНИ ІМПУЛЬСУ
CNTZ1; молодших і старших ОСЕРЕДКУ ЛІЧИЛЬНИКА ЧАСУ
CNTZ2; ЗАТРИМКИ ПЕРЕД вимірі довжини ІМПУЛЬСУ
ACCaLO; ЗМІННІ ВИКОРИСТОВУЮТЬСЯ підпрограми СКЛАДАННЯ
ACCaHI
ACCaHH
ACCbLO
ACCbHI
ACCbHH
ACCcLO; ЗМІННІ ВИКОРИСТОВУЮТЬСЯ підпрограми РОЗПОДІЛУ
ACCcHI
ACCdLO
ACCdHI
ACCdHH
temp
sign
count
H_byte
L_byte
R0; ЗМІННІ ВИКОРИСТОВУЮТЬСЯ підпрограми
R1; ПЕРЕТВОРЕННЯ В ДВОІЧНОДЕСЯТІЧНИЙ ВИД
R2
RBYTE
HSD; ЗМІННІ ВИКОРИСТОВУЮТЬСЯ підпрограми ЗАТРИМКИ
SD
LSD
Flags
ENDC
ORG 0X00; ВЕКТОР СКИДАННЯ
GOTO START
ORG 0X04; ВЕКТОР ПЕРЕРИВАННЯ
GOTO INTER
INTER RETURN; ПІДПРОГРАМА ОБРОБКИ ПЕРЕРИВАННЯ
; (ПЕРЕРИВАННЯ НЕ ВИКОРИСТОВУЮТЬСЯ)
; Початкові налаштування
START CLRF PORTB; обнулили ПОРТ B
BANK1
MOVLW B'00000100 '; RB2 - ВХІД, РЕШТА ВИХІД
MOVWF TRISB
BANK0
CLRF TMR0; ОЧИЩЕННЯ предделітеля І TMR0
BANK1
CLRWDT; ОЧИЩЕННЯ предделітеля І WDT
MOVLW B'11111110 '; коеф. РОЗПОДІЛУ 1:64
MOVWF OPTION_REG; предделітеля ПІД'ЄДНАНО До WDT
BANK0
CALL OCHIST; звернення до підпрограм ОЧИЩЕННЯ ДИСПЛЕЯ
NACH CLRWDT; ОЧИЩЕННЯ предделітеля І WDT
CALL FRSCR; виводити на дисплей
CALL CMETER; ВИМІРИ ПЕРІОДУ Іпульс
; ТІЛО ПРОГРАМИ ПЕРЕТВОРЕННЯ І ВИВЕДЕННЯ НА ІНДИКАТОР
MOVF CNT2, W
movwf ACCaHI
MOVF CNT1, W; ЗАВАНТАЖЕННЯ: ACCa = CNT
movwf ACCaLO
; DIV = 4476276/CNT
movlw 0X44
movwf ACCbHH
movlw 0X4D
movwf ACCbHI
movlw 0X74; ЗАВАНТАЖЕННЯ: ACCb = 4476276
movwf ACCbLO
CALL DIVIS
; BCD
MOVF ACCbHI, W
movwf H_byte
MOVF ACCbLO, W
movwf L_byte
call B2_BCD
MOVF CNTZ1, W; CNTZ ---> ACCa
MOVWF ACCaLO
MOVF CNTZ2, W
MOVWF ACCaHI
MOVF CNT1, W; CNT ---> ACCb
MOVWF ACCbLO
MOVF CNT2, W
MOVWF ACCbHI
CALL ADDIT; ДОДАВАННЯ - РЕЗУЛЬТАТ У ACCa
CLRF ACCbHI; 0006H ---> ACCb
MOVLW 0X06
MOVWF ACCbLO
CALL DBL_MPYS; Множення - РЕЗУЛЬТАТ У ACCb, ACCc (32біт)
MOVF ACCcLO, W; РЕЗУЛЬТАТ МНОЖЕННЯ ---> ACCa
MOVWF ACCaLO
MOVF ACCcHI, W
MOVWF ACCaHI
MOVF ACCbLO, W
MOVWF ACCaHH
MOVLW 0X0C; ПРИ 0C4B03 У ACCB - ОНОВЛЕННЯ індикатором КОЖНІ 0,9 СЕК
MOVWF ACCbHH
MOVLW 0X4B
MOVWF ACCbHI
MOVLW 0X03
MOVWF ACCbLO
CALL D_SUB; РЕЗУЛЬТАТ У ACCb
MOVLW D'016 '
MOVWF ACCaLO
CLRF ACCaHI
; РОЗПОДІЛ попередній результат
CALL DIVIS; НА 16, РЕЗУЛЬТАТ У ACCb
MOVF ACCbLO, W; ПОПЕРЕДНІЙ РЕЗУЛЬТАТ ---> HSD, LSD
MOVWF LSD
MOVF ACCbHI, W
MOVWF HSD
CALL DELAY
GOTO NACH
CMETER CLRF CNT1; обнулення лічильника
CLRF CNT2
CLRF CNTZ1
CLRF CNTZ2
BTFSS VHOD
GOTO SIG0; ВХ = 0
NOP
SIG1 INCFSZ CNTZ1, F; ЗБІЛЬШЕННЯ МОЛОДШОГО РОЗРЯДУ ЛІЧИЛЬНИКА НА 1 І
GOTO LOOP7; ПЕРЕВІРКА ЙОГО НА ЗАНАДТО
INCF CNTZ2, F; ЗБІЛЬШЕННЯ СТАРШОГО РОЗРЯДУ
LOOP7 BTFSC VHOD; ПОШУК ОТР. ФРОНТУ
GOTO SIG1; НІ
NOP
LOOP3 INCFSZ CNT1, F; ЗБІЛЬШЕННЯ МОЛОДШОГО РОЗРЯДУ ЛІЧИЛЬНИКА НА 1 І
GOTO LOOP8; ПЕРЕВІРКА ЙОГО НА ЗАНАДТО
INCF CNT2, F; ЗБІЛЬШЕННЯ СТАРШОГО РОЗРЯДУ
LOOP8 BTFSS VHOD; ВВАЖАТИ ПОКИ ОТР. СИГНАЛ
GOTO LOOP3
NOP
LOOP4 INCFSZ CNT1, F; ЗБІЛЬШЕННЯ МОЛОДШОГО РОЗРЯДУ ЛІЧИЛЬНИКА НА 1 І
GOTO LOOP9; ПЕРЕВІРКА ЙОГО НА ЗАНАДТО
INCF CNT2, F; ЗБІЛЬШЕННЯ СТАРШОГО РОЗРЯДУ
LOOP9 BTFSC VHOD; ВВАЖАТИ ПОКИ ПОЛОЖЕННЯ. СИГНАЛ
GOTO LOOP4
RETURN
SIG0 INCFSZ CNTZ1, F; ЗБІЛЬШЕННЯ МОЛОДШОГО РОЗРЯДУ ЛІЧИЛЬНИКА НА 1 І
GOTO LOOP1; ПЕРЕВІРКА ЙОГО НА ЗАНАДТО
INCF CNTZ2, F; ЗБІЛЬШЕННЯ СТАРШОГО РОЗРЯДУ
LOOP1 BTFSS VHOD; ПОШУК ПОЛОЖЕННЯ. ФРОНТУ
GOTO SIG0; НІ
NOP
LOOP2 INCFSZ CNT1, F; ЗБІЛЬШЕННЯ МОЛОДШОГО РОЗРЯДУ ЛІЧИЛЬНИКА НА 1 І
GOTO LOOP5; ПЕРЕВІРКА ЙОГО НА ЗАНАДТО
INCF CNT2, F; ЗБІЛЬШЕННЯ СТАРШОГО РОЗРЯДУ
LOOP5 BTFSC VHOD; ВВАЖАТИ ПОКИ ПОЛОЖЕННЯ. СИГНАЛ
GOTO LOOP2
NOP
LOOP6 INCFSZ CNT1, F; ЗБІЛЬШЕННЯ МОЛОДШОГО РОЗРЯДУ ЛІЧИЛЬНИКА НА 1 І
GOTO LOOP10; ПЕРЕВІРКА ЙОГО НА ЗАНАДТО
INCF CNT2, F; ЗБІЛЬШЕННЯ СТАРШОГО РОЗРЯДУ
LOOP10 BTFSS VHOD; ВВАЖАТИ ПОКИ ОТР. СИГНАЛ
GOTO LOOP6
RETURN
FRSCR MOVLW 0XAA
CALL INDC
MOVLW 0XAA
CALL INDC
MOVLW 0XAA
CALL INDC
MOVF R1, W
CALL INDC
SWAPF R1, W
CALL INDC
MOVF R2, W
CALL INDC
SWAPF R2, W
CALL INDC
MOVLW 0XAA
CALL INDC
MOVLW 0XAA
CALL INDC
MOVLW 0XAA
CALL INDC
RETURN
INDC bsf ICLC; CLK в неактивний стан
andlw 0xF0
movwf temp; збережемо поки ...
SWAPF temp, F
movlw 0Ah
xorwf temp, w; temp = 10 (тобто "ПУСТО")
btfsc STATUS, Z; W не дорівнює 10
goto mwyw; в W тепер 0, тобто BLANK (порожньо)
movf temp, w; відновили W
andlw 0fh; define Z (= 0?)
btfsc STATUS, Z
movlw .10; (1010) - це відображається як 0
mwyw movwf temp; якщо замінили 0 на 10 то змінимо і temp
rlf temp, f; необхідний біт (старший першим) в розряд 4 (--- В: ----)
call bitlcd; висновок біта з розряду 4 temp на DI (bit3)
rlf temp, f; зсув для наступного біта (2)
call bitlcd
rlf temp, f; next - bit1
call bitlcd
rlf temp, f; last - bit0
call bitlcd
call mks4; пауза між символами не менше 5 мкс
goto mks4; ... і вихід
bitlcd bsf ICLC; неактивний стан ICLC
btfss temp, 4; виодіт ІЗ 4 БІТА TEMP
goto lowbit
bsf IDAT
goto outclk
lowbit bcf IDAT
outclk call mks4; пауза не менше 2 мкс для встановлення даних
bcf ICLC; стробирование даних
call mks4; довжина стробу не менше 2 мкс (Кварц = 4MHz)
; Clk хоч в 0 хоч в 1 залишай, але без повторюваного
; Виведення на дисплей - він, через кілька секунд переходить в режим
; Внутрішнього таймера (?)
goto mks4
; CLK залишається в 0 (вбудований в LCD таймер як би не включено)
;
; Затримка трохи більше норми
; Виявилося важливо!
; При 1 "nop" - були збої індикатора
mks4 nop
nop
return
OCHIST MOVLW 0X00; ПІДПРОГРАМА ОЧИЩЕННЯ ДИСПЛЕЯ
MOVWF R1; ВИВОДИТЬ:
MOVWF R2; ___ 0 0 0 0 ___
RETURN
; ПІДПРОГРАМА складання двох байтовими ЧИСЕЛ:
; ДОДАВАННЯ: ACCb (16 bits) + ACCa (16 bits) -> ACCa (16 bits)
; ВИКОНАННЯ:
; Program Memory: 07
; Clock Cycles: 08
ADDIT movf ACCbLO, w
addwf ACCaLO, F; add lsb
btfsc STATUS, CARRY; add in carry
incf ACCaHI, F
movf ACCbHI, w
addwf ACCaHI, F; add msb
retlw 0
; ПІДПРОГРАМА РОЗПОДІЛУ
; ************************************************* ******************;
; РОЗПОДІЛ: ACCb (24 bits) / ACCa (16 bits) -> ACCb (24 bits) with
; ЗАЛИШОК У ACCc (16 bits)
; (A) занести дільник У ACCaHI & ACCaLO (24 bits)
; (B) занести ділимо У ACCbHH & ACCbHI & ACCbLO (16 bits)
; (C) CALL D_div
; (D) 24 бітної РЕЗУЛЬТАТ У ACCbHH & ACCbHI & ACCbLO
; (E) 16 бітної ЗАЛИШОК ACCcHI & ACCcLO
; ВИКОНАННЯ:
; Clock Cycles: 540
; ************************************************* ******************;
DIVIS call setup
clrf ACCcHI
clrf ACCcLO
dloop bcf STATUS, C
rlf ACCdLO, F
rlf ACCdHI, F
rlf ACCdHH, F
rlf ACCcLO, F
rlf ACCcHI, F
movf ACCaHI, W
subwf ACCcHI, W; ПЕРЕВІРКА a> c
btfss STATUS, Z
goto nochk
movf ACCaLO, W
subwf ACCcLO, W; if msb equal then check lsb
nochk btfss STATUS, C; carry set if c> a
goto nogo
movf ACCaLO, W; c-a into c
subwf ACCcLO, F
btfss STATUS, C
decf ACCcHI, F
movf ACCaHI, W
subwf ACCcHI, F
bsf STATUS, C; shift a 1 into b (result)
nogo rlf ACCbLO, F
rlf ACCbHI, F
rlf ACCbHH, F
decfsz temp, F; loop untill all bits checked
goto dloop
retlw 0
setup movlw .24; for 24 shifts
movwf temp
movf ACCbHI, W; ACCb -> ACCd
movwf ACCdHI
movf ACCbLO, W
movwf ACCdLO
movf ACCbHH, W
movwf ACCdHH
clrf ACCbHH
clrf ACCbHI
clrf ACCbLO
retlw 0
; ПІДПРОГРАМА ПЕРЕТВОРЕННЯ В ДВОІЧНОДЕСЯТІЧНИЙ ВИД
; ПЕРЕТВОРЕННЯ 16 бітних числа на десяткове Запаковані ЧИСЛО У 5 РОЗРЯДІВ
; ВИКОНАННЯ:
; Program Memory: 35
; Clock Cycles: 885
B2_BCD bcf STATUS, 0
movlw .16
movwf count
clrf R0
clrf R1
clrf R2
loop16 rlf L_byte, F
rlf H_byte, F
rlf R2, F
rlf R1, F
rlf R0, F
decfsz count, F
goto adjDEC
RETLW 0
adjDEC movlw R2
movwf FSR
call adjBCD
movlw R1
movwf FSR
call adjBCD
movlw R0
movwf FSR
call adjBCD
goto loop16
adjBCD movlw 3
addwf 0, W
movwf temp
btfsc temp, 3; test if result> 7
movwf 0
movlw 30
addwf 0, W
movwf temp
btfsc temp, 7; test if result> 7
movwf 0; save as MSD
RETLW 0
DELAY NOP
DELAY1 NOP
NOP
NOP
NOP
MOVLW 0X00
SUBWF LSD, W
BTFSC STATUS, Z
GOTO DELAY2
NOP
NOP
NOP
NOP
NOP
DECF LSD, F
GOTO DELAY1
DELAY2 MOVLW D'255 '
MOVWF SD
DELAY4 NOP
DECFSZ SD, F
GOTO DELAY4
MOVLW D'255 '
MOVWF SD
DELAY5 NOP
DECFSZ SD, F
GOTO DELAY5
MOVLW D'255 '
MOVWF SD
DELAY6 NOP
DECFSZ SD, F
GOTO DELAY6
NOP
NOP
NOP
NOP
NOP
MOVLW D'255 '
MOVWF SD
DELAY7 NOP
DECFSZ SD, F
GOTO DELAY7
MOVLW 0X00
SUBWF HSD, W
BTFSC STATUS, Z
GOTO DELAY3
DECF HSD, F
GOTO DELAY2
DELAY3 RETURN
; ************************************************* ******************
; ВІДНІМАННЯ Двухбайтовое ЧИСЕЛ (ACCb - ACCa -> ACCb)
D_SUB call neg_A; СНАЧАЛО 0-ACCa; ПОТІМ ДОДАВАННЯ
; ************************************************* ******************
; ДОДАВАННЯ Двухбайтовое ЧИСЕЛ (ACCb + ACCa -> ACCb)
D_add1 movf ACCaLO, W
addwf ACCbLO, F; add lsb
btfsc STATUS, C; add in carry
incf ACCbHI, F
movf ACCaHI, W
addwf ACCbHI, F; add msb
btfsc STATUS, C
incf ACCbHH, F
movf ACCaHH, W
addwf ACCbHH, F
retlw 0
neg_A comf ACCaLO, F; (-ACCa -> ACCa)
incf ACCaLO, F
btfsc STATUS, Z
decf ACCaHI, F
comf ACCaHI, F
btfsc STATUS, Z
decf ACCaHH, F
comf ACCaHH, F
retlw 0
; Множення: ACCb (16 bits) * ACCa (16 bits) -> ACCb, ACCc (32 bits)
; Program Memory: 033
; Clock Cycles: 333
; ДОДАВАННЯ ДВОХ байтовими ЧИСЕЛ (ACCb + ACCa -> ACCb)
D_add MOVF ACCaLO, W
ADDWF ACCbLO, F
BTFSC STATUS, C
INCF ACCbHI, F
MOVF ACCaHI, W
ADDWF ACCbHI, F
retlw 0
; ************************************************* ******************
; Двухбайтовое Множення (16x16 -> 32)
; (ACCb * ACCa -> ACCb, ACCc): РЕЗУЛЬТАТ 32 БІТА - старше слово
; У ACCb (ACCbHI, ACCbLO) і молодший СЛОВО У ACCc (ACCcHI, ACCcLO).
DBL_MPYS
call setup1
mloop rrf ACCdHI, F
rrf ACCdLO, F
btfsc STATUS, C
call D_add
rrf ACCbHI, F
rrf ACCbLO, F
rrf ACCcHI, F
rrf ACCcLO, F
decfsz temp, F
goto mloop
retlw 0
setup1 movlw .16
movwf temp
movf ACCbHI, W
movwf ACCdHI
movf ACCbLO, W
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO
retlw 0
END