;=============================================
; DigiScal.asm
; Цифровая шкала с возможностью
; записи промежуточной частоты
; Денисов А.Ю. Тамбов 1999
;=============================================
	LIST	p=16F84
       __CONFIG 03FF1H
;=============================================
				   ; timing loop values
				   ; must be from 1 to 255!!!
T1	    equ       .67	   ; rough timing loop
T2	    equ       .221	   ; fine timing loop
				   ; values for 4 000 kHz
;=============================================
;
IndF	    equ        00h	   ; Indirect addr. register
Timer0	    equ        01h	   ; TMR0 register
OptionR     equ        01h	   ; Option register - RP0=1
PC	    equ        02h	   ; Program counter
Status	    equ        03h	   ; Status register
FSR	    equ        04h	   ; Pointer register
PortA	    equ        05h	   ; Port A
TrisA	    equ        05h	   ; Tris A - RP0=1
PortB	    equ        06h	   ; Port B
TrisB	    equ        06h	   ; Tris B - RP0=1
EEData	    equ        08h	   ; EEPROM Data
EECon1	    equ        08h	   ; EECON1 - RP0=1
EEAdr	    equ        09h	   ; EEPROM Address
EECon2	    equ        09h	   ; EECON2 - RP0=1

IntCon	    equ        0Bh	   ;
;
KeyBuf	    equ        0Ch	   ; буфер клавиатуры
KeyWait     equ        0Dh	   ; ожидание клавиатуры
Count	    equ        0Eh	   ; временный счетчик
Count1	    equ        0Fh	   ; еще один
;
LED0	    equ       010h	   ;
LED1	    equ       011h	   ;
LED2	    equ       012h	   ;
LED3	    equ       013h	   ; ячейки
LED4	    equ       014h	   ; индикатора
LED5	    equ       015h	   ;
LED6	    equ       016h	   ;
LED7	    equ       017h	   ;
;
Temp	    equ       018h	   ; временный регистр
LEDIndex    equ       019h	   ; указатель LED

TimerL	    equ       01ah	   ; младший байт счетчика частоты
TimerM	    equ       01bh	   ; средний байт счетчика частоты
TimerH	    equ       01ch	   ; старший байт счетчика частоты

IF_L	    equ       01dh	   ; младший байт ПЧ
IF_M	    equ       01eh	   ; средний байт ПЧ
IF_H	    equ       01fh	   ; старший байт ПЧ
;
;=============================================
;
W	    equ        0	   ; destination is accumulator
F	    equ        1	   ; register
;
;=============================================
; Flag bits:
CF	    equ        0	   ; Carry
DC	    equ        1	   ; DC
ZF	    equ        2	   ; Zero
;
RP0	    equ        5
;=============================================
	    org        2100h

	    ; частота ПЧ по умолчанию
	    DE	       008h,064h,070h	; 5.5 мгц
;
	    DE	       0h,0h,0h 	; резерв
	    DE	    "Copyright (C) 1999 Alexander Y Denisov"

;
;=============================================
;
	    org        0
	    goto    Start
;
;=============================================
; Проверка клавиатуры
;=============================================
;
Inkey
	    clrf       PortA	   ; RA0..RA3 = 0

	    bsf        Status,RP0
	    movlw      b'00010011'
	    movwf      TrisA	   ; RA0,RA1,RA4 input
	    bcf        Status,RP0  ;

	    movf       PortA,w
	    andlw      b'00000011'
	    return
;
;=============================================
KeyQuery    ; опрос клавиатуры
	    call       Inkey
	    addwf      PC,f
	    goto       Fun	   ; режим установки ПЧ
	    goto       plusIF	   ; плюс ПЧ
	    goto       minusIF	   ; минус ПЧ
	    goto       Go1	   ; и все по новой.
;
Fun
	    incf       KeyWait,f
	    btfss      KeyWait,3
	    goto       Go

	    movlw      0
	    movwf      KeyWait
Function
	    call       Inkey
	    addwf      PC,f
	    goto       Function    ; ждем отжатия клавиш
	    nop
	    nop
	    nop
	    movf       TimerL,w
	    movwf      IF_L
	    movf       TimerM,w
	    movwf      IF_M
	    movf       TimerH,w
	    movwf      IF_H
	    call       Bin2LCD
	    goto       Edt
;
;=============================================
;
FunOff
	    call       Inkey
	    addwf      PC,f
	    goto       Fun1
	    goto       NextFun	   ; ничего не нажато
	    goto       NextFun	   ; ничего не нажато
	    goto       NextFun	   ; ничего не нажато
Fun1
	    incf       KeyWait,f
	    btfss      KeyWait,7
	    goto       Edt	   ; next 8xLED
Fun11
	    call       Inkey
	    addwf      PC,f
	    goto       Fun11	   ; ждем отжатия клавиш
	    goto       WrtMem	   ; запись в память
	    goto       WrtMem	   ; запись в память
	    goto       WrtMem	   ; запись в память
;
;=============================================
; Перекодирование двоичного в код LCD
;=============================================
;
Bin2LCD
	    bcf        Status,0    ; clear the carry bit
	    movlw      .24
	    movwf      Count
	    clrf       LED3
	    clrf       LED2
	    clrf       LED1
	    clrf       LED0
loop16
	    rlf        TimerL,f
	    rlf        TimerM,f
	    rlf        TimerH,f
	    rlf        LED0,f
	    rlf        LED1,f
	    rlf        LED2,f
	    rlf        LED3,f
;
	    decfsz     Count,f
	    goto       adjDEC

	    swapf      LED3,w
	    andlw      0Fh
	    movwf      LED7

	    movfw      LED3
	    andlw      0Fh
	    movwf      LED6

	    swapf      LED2,w
	    andlw      0Fh
	    movwf      LED5

	    movfw      LED2
	    andlw      0Fh
	    movwf      LED4

	    swapf      LED1,w
	    andlw      0Fh
	    movwf      LED3

	    movfw      LED1
	    andlw      0Fh
	    movwf      LED2

	    swapf      LED0,w
	    andlw      0Fh
	    movwf      LED1

	    movfw      LED0
	    andlw      0Fh
	    movwf      LED0

	    return
;
adjDEC
	    movlw      LED0
	    movwf      FSR
	    call       adjBCD
;
	    movlw      LED1
	    movwf      FSR
	    call       adjBCD
;
	    movlw      LED2
	    movwf      FSR
	    call       adjBCD
;
	    movlw      LED3
	    movwf      FSR
	    call       adjBCD
;
	    goto       loop16
;
adjBCD
	    movlw      3
	    addwf      0,W
	    movwf      Count1
	    btfsc      Count1,3  ; test if result > 7
	    movwf      0
	    movlw      30
	    addwf      0,W
	    movwf      Count1
	    btfsc      Count1,7  ; test if result > 7
	    movwf      0	 ; save as MSD
;
	    retlw      0
;
;=============================================
; Преобразование BCD -> 7 сегментный код
;=============================================

LCDTable
	    addwf      PC,F	   ; W + PC -> PC
	    retlw      b'00111111' ; ..FEDCBA = '0'
	    retlw      b'00000110' ; .....CB. = '1'
	    retlw      b'01011011' ; .G.ED.BA = '2'
	    retlw      b'01001111' ; .G..DCBA = '3'
	    retlw      b'01100110' ; .GF..CB. = '4'
	    retlw      b'01101101' ; .GF.DC.A = '5'
	    retlw      b'01111101' ; .GFEDC.A = '6'
	    retlw      b'00000111' ; .....CBA = '7'
	    retlw      b'01111111' ; .GFEDCBA = '8'
	    retlw      b'01101111' ; .GF.DCBA = '9'
	    retlw      b'01110001' ; .GFE...A = 'F'
;
;=============================================
;Main program
;
Start
	    bsf        Status,RP0

	    movlw      b'00010000' ; RA0..RA3 outputs
	    movwf      TrisA	   ; RA4 input

	    movlw      b'00000000' ; RB0..RB7 outputs
	    movwf      TrisB

	    clrwdt		   ;
	    movlw      b'00100111' ; Prescaler -> Timer0,
	    movwf      OptionR	   ; 1:256, rising edge
	    bcf        Status,RP0  ;

	    clrf       Count	   ; указатели
	    clrf       LEDIndex

	    clrf       LED0	   ; индикаторы
	    clrf       LED1
	    clrf       LED2
	    clrf       LED3
	    clrf       LED4
	    clrf       LED5
	    clrf       LED6
	    clrf       LED7

	    clrf       TimerL	   ; ячейки счета
	    clrf       TimerM
	    clrf       TimerH

;=============================================
;Преобразование bin => BCD => код для индикаторов
;
Go
	    bcf        EECon1,2    ; запрещение записи
	    movlw      0
	    movwf      EEAdr
	    bsf        Status,RP0
	    bsf        EECon1,0
	    bcf        Status,RP0  ;
	    movf       EEData,w
	    movwf      IF_H

	    movlw      1
	    movwf      EEAdr
	    bsf        Status,RP0
	    bsf        EECon1,0
	    bcf        Status,RP0  ;
	    movf       EEData,w
	    movwf      IF_M

	    movlw      2
	    movwf      EEAdr
	    bsf        Status,RP0
	    bsf        EECon1,0
	    bcf        Status,RP0  ;
	    movf       EEData,w
	    movwf      IF_L

	    call       Bin2LCD
;
;=============================================
; Регистры LED0..LED7 заполнены значениями, готовимся
; измерять и отображать
;=============================================
;
	    clrf       IntCon	   ; clear overflow bite
	    clrf       TimerH	   ; старший байт измерения
	    clrf       Timer0	   ; собственно таймер
	    clrf       LEDIndex    ; указатель цифры
;
	    movlw      .60	   ; начальное значение счетчика
	    movwf      Count	   ; 60 -> Count
;
;=============================================
; Начало измерения и индикации:  RA3 set input
;=============================================
;
	    movlw      b'00000000' ; 0 во все порты
	    movwf      PortA
;
	    bsf        Status,RP0
	    movlw      b'00011000' ; RA0..RA2 output,RA3..RA4 input
	    movwf      TrisA	   ; RA4 input
	    bcf        Status,RP0  ;
;
;=============================================
; 7-step cycle of digits
;=============================================
;
LEDCycle    movlw      LED0
	    addwf      LEDIndex,W  ; LED1 + LEDIndex -> W

	    movwf      FSR	   ; W -> FSR
	    movf       IndF,W	   ; LED(0..6) -> W
	    call       LCDTable    ; W -> семисегментный код

	    movwf      Temp	   ; точка есть?
	    movlw      5
	    bsf        Status,ZF
	    subwf      LEDIndex,W
	    btfss      Status,ZF
	    goto       NoDot
	    bsf        Temp,7
NoDot	    movf       Temp,W
	    movwf      PortB	   ; вывод цифры в PortB

	    movf       LEDIndex,W  ; LEDIndex -> W
	    movwf      PortA	   ; вывод позиции в PortA
;
;=============================================
; Проверка TMR0 на переполнение
;=============================================
;
	    btfss      IntCon,2
	    goto       DoNothing
	    incf       TimerH,F
	    bcf        IntCon,2
	    goto       O_K
DoNothing   nop
	    nop
	    nop
;
;=============================================
; The first timing loop
;=============================================
O_K
	    movlw      T1
	    movwf      Temp
Pause
	    decfsz     Temp,F
	    goto       Pause

;=============================================
;
	    incf       LEDIndex,F
	    movlw      7	   ; is 7th?
	    bcf        Status,ZF
	    subwf      LEDIndex,W
	    btfss      Status,ZF
	    goto       LEDCycle    ; след. цифра
	    nop
;
	    clrf       LEDIndex
	    decfsz     Count,F
	    goto       LEDCycle    ; next 7xLED
	    nop

;=============================================
; The second timing loop
;=============================================

	    movlw      T2
	    movwf      Temp

EndPause    decfsz     Temp,F
	    goto       EndPause
	    nop

;=============================================
; Завершение измерения
;=============================================
Nx
	    clrw
	    movwf      PortB	   ; RB0..RB7 = 0
	    movwf      PortA	   ; RA0..RA3 = 0

	    bsf        Status,RP0
	    movlw      b'00010000'
	    movwf      TrisA	   ; RA4 input
	    bcf        Status,RP0  ;
	    nop
	    nop
;=============================================
; Последняя проверка TMR0 на переполнение
;=============================================
	    btfss      IntCon,2
	    goto       Analyse
	    bcf        IntCon,2
	    incf       TimerH,F
;=============================================
; Анализ содержимого предварительного делителя
;=============================================
Analyse
	    nop
	    movf       Timer0,W    ; средний байт счетчика
	    movwf      TimerM	   ; TMR0 -> TimerM

	    clrf       TimerL
CountIt
	    incf       TimerL,F
	    bsf        PortA,3	   ; _| false impulz
	    nop
	    bcf        PortA,3	   ;	|_
	    nop
	    movf       Timer0,W    ; actual Timer0 -> W
	    bcf        Status,ZF
	    subwf      TimerM,W
	    btfsc      Status,ZF
	    goto       CountIt
	    incf       TimerL,F
	    comf       TimerL,F
	    incf       TimerL,F
	    incf       TimerL,F    ; младший байт счетчика
	    goto       KeyQuery
minusIF
	    comf    IF_L,f
	    incf    IF_L,f
	    btfsc   Status,ZF
	    decf    IF_M,f
	    comf    IF_M,f
	    btfsc   Status,ZF
	    decf    IF_H,f
	    comf    IF_H,f
;
	    movf    IF_L,w
	    addwf   TimerL,f
	    btfsc   Status,CF
	    incf    TimerM,f
	    movf    IF_M,w
	    addwf   TimerM,f
	    btfsc   Status,CF
	    incf    TimerH,f
	    movf    IF_H,w
	    addwf   TimerH,f
	    btfsc   Status,CF	; результат отрицательный?
	    goto    Go1 	; нет
	    btfsc   Status,CF	; а не ноль?
	    goto    Go1 	; нет
	    comf    TimerL,f	; преобразование
	    incf    TimerL,f
	    btfsc   Status,ZF
	    decf    TimerM,f
	    comf    TimerM,f	; отрицательного
	    btfsc   Status,ZF
	    decf    TimerH,f
	    comf    TimerH,f	; результата
Go1
	    movlw      0
	    movwf      KeyWait
	    goto       Go
plusIF
	    movf    IF_L,w
	    addwf   TimerL,f
	    btfsc   Status,CF

	    incf    TimerM,f
	    movf    IF_M,w
	    addwf   TimerM,f
	    btfsc   Status,CF
	    incf    TimerH,f
	    movf    IF_H,w
	    addwf   TimerH,f
	    goto    Go1
Edt
	    clrf       IntCon	   ; clear overflow bite
	    movlw      0ah
	    movwf      LED7	   ; признак режима
;=============================================
; 8-step cycle of digits
;=============================================
;
	    movlw      b'00000000' ;
	    movwf      PortA
;
	    bsf        Status,RP0
	    movlw      b'00010000' ; RA0..RA3 output,RA4 input
	    movwf      TrisA	   ;
	    bcf        Status,RP0  ;
	    clrf       LEDIndex    ; указатель цифры
EdtCycle
	    movlw      LED0
	    addwf      LEDIndex,W  ; LED1 + LEDIndex -> W

	    movwf      FSR	   ; W -> FSR
	    movf       IndF,W	   ; LED(0..6) -> W
	    call       LCDTable    ; W -> семисегментный код

	    movwf      Temp	   ; точка есть?
	    movlw      5
	    bsf        Status,ZF
	    subwf      LEDIndex,W
	    btfss      Status,ZF
	    goto       NoDot1
	    bsf        Temp,7
NoDot1	    movf       Temp,W
	    movwf      PortB	   ; вывод цифры в PortB

	    movf       LEDIndex,W  ; LEDIndex -> W
	    movwf      PortA	   ; вывод позиции в PortA
;
;=============================================
; Timing loop
;=============================================
	    movlw      .255
	    movwf      Temp
Pause1
	    decfsz     Temp,F
	    goto       Pause1

;=============================================
;
	    incf       LEDIndex,F
	    btfss      LEDIndex,3
	    goto       EdtCycle    ; след. цифра
;
	    clrf       LEDIndex
	    goto       FunOff
;
NextFun
	    movlw      0	   ; выход из цикла редактирования
	    movwf      KeyWait
	    goto       Edt	   ; next 8xLED
;
WrtMem	    ;	   запись в EEPROM

	    movlw      0
	    movwf      IntCon	   ; запрещение прерываний
	    movwf      EEAdr
	    movf       IF_H,w
	    movwf      EEData
	    bsf        Status,RP0
	    bsf        EECon1,2    ; разрешение записи
	    movlw      055h
	    movwf      EECon2
	    movlw      0AAh
	    movwf      EECon2
	    bsf        EECon1,1
wr1
	    btfss      EECon1,4
	    goto       wr1
	    bcf        EECon1,4
	    bcf        Status,RP0

	    movlw      1
	    movwf      EEAdr
	    movf       IF_M,w
	    movwf      EEData
	    bsf        Status,RP0
	    bsf        EECon1,2    ; разрешение записи
	    movlw      055h
	    movwf      EECon2
	    movlw      0AAh
	    movwf      EECon2
	    bsf        EECon1,1
wr2
	    btfss      EECon1,4
	    goto       wr2
	    bcf        EECon1,4
	    bcf        Status,RP0

	    movlw      2
	    movwf      EEAdr
	    movf       IF_L,w
	    movwf      EEData
	    bsf        Status,RP0
	    bsf        EECon1,2    ; разрешение записи
	    movlw      055h
	    movwf      EECon2
	    movlw      0AAh
	    movwf      EECon2
	    bsf        EECon1,1
wr3
	    btfss      EECon1,4
	    goto       wr3
	    bcf        EECon1,4
	    bcf        Status,RP0
;
	    goto       Go1
;
;=============================================
	    end
Hosted by uCoz