;********************************************************************
; FreqC_57.asm - description
; -------------------
;begin : Mon April 18,2016
;copyright : (C) 2016 by Michael Masterson
;********************************************************************
;
;This program is free software: you can redistribute it and/or modify
;it under the terms of the GNU General Public License as published by
;the Free Software Foundation, either version 3 of the License, or
;(at your option) any later version.
;
;This program is distributed in the hope that it will be useful,
;but WITHOUT ANY WARRANTY; without even the implied warranty of
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;GNU General Public License for more details.
;
;You should have received a copy of the GNU General Public License
;along with this program. If not, see .
;
;********************************************************************
; FreqC_57.asm Config=3F62h 12.288MHz HS clock Uses Timer 0 CODE From FreqC_51.asm
; adds PwrDet
; Gate is RB0, normally logic '0' output, becomes input when gate is open
; Int RC I/O Pins; Enable PWRT,MCLR,BODEN
; Supports initialise LCD
; display counter value in MHz , 32 bits State=0 only
; Set (not clr) RB1 during Gate closed
;Supported: DVM, Chg/Bat detect
; Better UHF resolution 200msec gate; LCD write speed
list p=16F628A
radix hex
__config H'3F62'
; errorlevel -302 ; Disable bank switch warning
indf equ 0x00
tmr0 equ 0x01 ;tmr0 register
pcl equ 0x02
status equ 0x03 ;IRP=b7;RP1=b6,RP0=b5, Z=b2;DC=b1;C=b0
fsr equ 0x04
porta equ 0x05
portb equ 0x06
pclath equ 0x0A
intcon equ 0x0B ;define intcon register
tmr0l equ 0x0E ; this will be clocked out of prescaler
t1con equ 0x10 ;
tmr2 equ 0x11
t2con equ 0x12
ccpr1L equ 0x15
ccp1con equ 0x17
cmcon equ 0x1F
trans equ 0x20 ;0x20-0x6F are GPR's
numbit equ 0x21
value0 equ 0x22 ;general purpose. Used in S/W timers
value1 equ 0x23
count equ 0x24
tmr0of equ 0x25 ;timer 0 overflow
fhi equ 0x26
bufl equ 0x27 ;tmr0l>>bufl (from prescaler)
bufh equ 0x28 ;tmr0>>bufh
bufo equ 0x29 ; tmr0of>>buf0
bufu equ 0x2A ; will be clr later, not used yet
flags equ 0x2B ;<0>=allowing zeroes flag before dec pt
;<1>=display dec point only for 6th digit
;<2>=Ext/Int DC
startup equ 0x2C ;startup,0='0' initially. set after first pass.
;0x30 Hz,0x31 Tens>>0x39 for BCD LSD>>MSD
digitctr equ 0x3A
shiftctr equ 0x3B
nibbleU equ 0x3C
nibbleL equ 0x3D
dvm equ 0x3E ;dvm= 0x00 to 0x0F (temp), 0=NG; ,1=LO ,2=OK ,3=HI
trisa equ 0x85
trisb equ 0x86
pie1 equ 0x8C
pr2 equ 0x92
vrcon equ 0x9F
goto initial
nop
nop
nop
bcf intcon,7 ;clr GIE. Here Interrupts are vectored
initial clrf ccp1con ;CCP module off ************* INITIAL***************
clrf porta
clrf portb
clrf intcon
clrf bufl
clrf bufh
clrf bufo
clrf bufu
clrf startup
movlw 0x07 ;Turn comparators off
movwf cmcon
banksel 0x80 ;***** BANK 1 *****
movlw 0xE7 ;1110 0111 No PU,Intedg=1,T0CS=1,T0SE=0,PSA=0,Prescale=256
movwf 0x81 ; OPTION_REG
movlw 0x30 ;port a-write 0011 0000
movwf trisa ;
movlw 0xC8 ;port b-write 1100 1000 b7=PGD,b6=PGC, b5=R/S,b4=E,b3=Band,b2=/UHF,b1=VHF,b0=Gate
movwf trisb ;
banksel 0x00 ;***** BANK 0 *****
call LCDinit ;initialize LCD Modes
start ;************Top Of Mainline Prog ********
call p1
call Line1
BandTest
btfss portb,3 ;test RB3 for VHF/VHF UHF='1' VHF='0'
goto Vpre
Upre
bcf portb,2
Vpre
bsf portb,1 ;turn on VHF
call wait5
call wait5 ; ~10msec @12.288MHz Brings up prescalars
Timer0 ; ************************* TIMER0 **************************
movlw 0x07 ;setup timer0. 256:1 Prescale, Asynch, T0CKI ,
clrf tmr0 ;clear tmr0 and Prescaler
clrf tmr0of ;clear overflow counter
clrf tmr0l ;clear prescale transfer register
bsf portb,0 ;set port b,1 gate WAS CLR
banksel 0x80 ;***** BANK 1 *****
bsf trisb,0 ;change to input, open gate now.
banksel 0x00 ;***** BANK 0 *****
call waitL
banksel 0x80 ;***** BANK 1 *****
bcf trisb,0 ;change to output, close gate now.
banksel 0x00 ;***** BANK 0 *****
call Tmr0Test ;test last time for tmr0of
clrf bufu ; clear upper byte for now; not used
movf tmr0of,0 ;transfer timr0of>bufo
movwf bufo
movf tmr0,0 ;tmr0>>bufh
movwf bufh
clrf bufl ;temp
call getcount ;go with bufh; return with bufl
bcf portb,1 ;VHF Pre Off
bsf portb,2 ;UHF Pre Off
btfss startup,0 ;skip over next if first pass is done
goto Splash
call DecDisp
call MHz
call Line2
call Band
call DCdet
call DVM
goto Hang
Splash
call Intro
call p1
Hang
call pause
call pause
call pause
bsf startup,0 ;OK been thru it once, now set to run
goto start
;waitL routine routine ~.234.08961millisec @ 12.288MHz, 719109 Inst.Cycles
; with value1 initialized to 0x93, 99.14388ms, 304570 cycles
waitL
clrf value0
movlw 0x93 ; 0x93 for 0.1 sec; 0x27 for 0.2sec
btfsc portb,3
movlw 0x27
movwf value1
waitL2 ;outer loop
incfsz value1,1 ;inc value1, skip if 0
goto waitL3
goto setfudge
waitL3 ;inner loop
call Tmr0Test
incfsz value0,1 ;inc value0, skip if 0
goto waitL3
movlw 0xF9
movwf value0
waitL2t ;delay 256 loops
incfsz value0,1
goto waitL2t
goto waitL2
setfudge ; this section trims value to 307200 or 614400 IC's
movlw 0xAF ; 0xae for 0.1 sec; 0x56 for 0.2 sec
btfsc portb,3
movlw 0x57
movwf value0
fudge
incfsz value0,1
goto fudge
; nop ;was used before
; nop
return
Tmr0Test ;Test tmr0 overflow most often!
btfss intcon,2 ;test tmr0 overflow flag
goto Delay1
incf tmr0of,1
bcf intcon,2 ;clr tmr0 overflow flag
return
Delay1
nop
return
DecDisp ; ******************* DecDisp **********************
btfsc portb,3 ; test for VHF then skip
call Shift3x ;for UHF
call DoubleDabble ;return with digits 0x31>>0x39 digits 1-9
movlw 0x09
movwf digitctr ;Initialize Digit Counter, 9 Digits
clrf flags ; clear zeroes (b0), dec point (b1) flag
movlw 0x39 ;to the MSD
movwf fsr
DispLoop ; ****************** DispLoop***********************
movf digitctr,0 ;to w Test for 6th
sublw 0x06
btfss status,2 ;test Z for digitctr=6 (decimal point)
goto FirstNib ;display all numbers
bsf flags,0 ;set the flag allowing zeroes flag before dec pt
bsf flags,1 ; set the flag to display dec point only for 6th digit
FirstNib
btfsc flags,0 ;test for zero is OK (flags,0='1')
goto Nibbles ;all values OK, including zero
movf indf,0 ;to w
sublw 0x00 ;test for Zed
btfss status,2
goto Nibbles ;it isn't zero, so display
movlw 0x20 ;spa
call qst
goto DecDigitctr
Nibbles
bsf flags,0 ;zero is OK now.
btfss portb,3 ; skip if UHF and check for digit#1
goto Nibble1
movf digitctr,0
sublw 0x01
btfsc status,2 ;if 1 then don't display!
return ;
Nibble1
movlw 0x30
movwf nibbleU ;Upper Nibble 0x30
movf indf,0 ;>>w Lower Nibble 'N'
addwf nibbleU,0 ;0x30+0x0N>>w
call qst
btfss flags,1 ;do we do DecPt?
goto DecDigitctr
DecPt
movlw 0x2E ;decimal point
call qst
bcf flags,1 ;dec point done. clr flag
DecDigitctr
decfsz digitctr,1
goto DigitDec
return
DigitDec
decf fsr
goto DispLoop
LCDinit ;************************* LCDinit *******************************
bcf portb,5 ;RS=0 write cmd
movlw 0x02 ;4-bit
call est
movlw 0x02 ;FunctionSet
call est
movlw 0x0C ;was 0x08
call est
movlw 0x00 ;Display on,cursor on &blink not now!
call est
movlw 0x0C ;was 0x0F,
call est
movlw 0x00 ;Entry mode
call est
movlw 0x06
call est
return
Line1 ;************************* Line1 *******************************
bcf portb,5 ;RS=0 write cmd
movlw 0x00 ;Clear Display
call est
movlw 0x01
call est
movlw 0x08 ;Line 1, Left
call est
movlw 0x00
call est
bsf portb,5 ;RS=1 write chr
return
Line2 ;Displays Band [VHF/UHF] and Battery [OK/Low]'0'=0x30 '1'=0x31
bcf portb,5 ;RS=0 write cmd
movlw 0x0C ;Line 2, Left
call est
movlw 0x00
call est
bsf portb,5 ;RS=1 write chr
return
MHz ;*************************** MHz *******************************
movlw 0x20 ;space
call qst
movlw 0x4D ;M
call qst
movlw 0x48 ;H
call qst
movlw 0x7A ;z
call qst
return
Band ; *************************BAND********************************
movlw 0x42 ;B
call qst
movlw 0x61 ;a
call qst
movlw 0x6E ;n
call qst
movlw 0x64 ;d
call qst
movlw 0x3A ; :
call qst
btfss portb,3 ; skip if UHF
goto V
movlw 0x55 ;U
call qst
H movlw 0x48 ;H
call qst
movlw 0x46 ;F
call qst
movlw 0x20 ;spa
call qst
return
V movlw 0x56 ;V
call qst
goto H
Int ; ************** Int: ********
movlw 0x49 ;I
call qst
movlw 0x6E ;n
call qst
movlw 0x74 ;t
call qst
movlw 0x3A ;:
call qst
return
Ext ; ************** Ext: ********
movlw 0x45 ;E
call qst
movlw 0x78 ;x
call qst
movlw 0x74 ;t
call qst
movlw 0x3A ;:
call qst
return
Intro ; *************************Intro********************************
movlw 0x48 ;H
call qst
movlw 0x49 ;I
call qst
movlw 0x20 ;spa
call qst
movlw 0x64 ;d
call qst
movlw 0x65 ;e
call qst
movlw 0x20 ;spa
call qst
movlw 0x57 ;W
call qst
movlw 0x4E ;N
call qst
movlw 0x32 ;2
call qst
movlw 0x41 ;A
call qst
movlw 0x20 ;spa
call qst
movlw 0x76 ;v
call qst
movlw 0x35 ;5
call qst
movlw 0x2E ;.
call qst
movlw 0x37 ;7
call qst
return
est ;************************* est *******************************
movwf porta
call wait5 ;~5msec @ 12.288MHz
bsf portb,4
call wait5 ;~5msec @ 12.288MHz
bcf portb,4
return
qst ;******** qst like fst, but better! Takes only 1 byte: enter w ******
movwf nibbleU ;save here
movwf nibbleL ;and here
swapf nibbleU,0 ;swap >w
andlw 0x0F ;mask higher nibble
movwf porta ;send upper nibble
call wait3 ;~0.75msec @ 12.288MHz
bsf portb,4 ;E
call wait3 ;~0.75msec @ 12.288MHz
bcf portb,4 ;E
movf nibbleL,0 ;>>w
andlw 0x0F
movwf porta
call wait3 ;~0.75msec @ 12.288MHz
bsf portb,4 ;E
call wait3 ;~0.75msec @ 12.288MHz
bcf portb,4 ;E
return
DoubleDabble ;enter with 0x27-0x28-0x29-0x2A binary, leave with BCD
movlw 0x20
movwf shiftctr ;initialize shift counter 16x
ClearDigits
movlw 0x09
movwf digitctr ;Digit Counter
movlw 0x31
movwf fsr
ClearLoop
clrf indf
decfsz digitctr,1
goto IncFsrC
goto DDloop
IncFsrC
incf fsr
goto ClearLoop
DDloop
call Test5 ;first check digits for >=5..then shift
call Left1
decfsz shiftctr,1
goto DDloop
return
Left1
movlw 0x27
movwf fsr
bcf status,0 ;clr C
rlf indf ;LSB
incf fsr ;0x28
rlf indf
incf fsr ;0x29
rlf indf
incf fsr ;0x2A
rlf indf ;now C has first digit load
ShiftBCD
movlw 0x09
movwf digitctr ;Digit Counter
movlw 0x31
movwf fsr
NextShift
rlf indf
bcf status,0 ; Clear C
btfsc indf,4
bsf status,0 ;Set C instead
movlw 0x0F ;mask value
andwf indf,1
decfsz digitctr,1
goto IncFsr
return
IncFsr
incf fsr
goto NextShift
Test5 ;enter 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39
movlw 0x09
movwf digitctr ;Digit Counter
movlw 0x31
movwf fsr
NextTest
movf indf,0 ;>>to w
movwf value0 ;also save in value0 for later
sublw 0x04
btfsc status,0 ; if clr,add 3
goto TestEnd
movlw 0x03
addwf value0,0 ; add and move to w
movwf indf
TestEnd
decfsz digitctr
goto incfsr
return ;done Test5
incfsr
incf fsr
goto NextTest
;getcount, toggles the RA0 pin to shift out the value in the
;pre-scaler. The number of toggles is kept in count. If the value
;in tmr0 increments, then the low 8 bit value = !count + 1.
;Low byte>>bufl , high in bufh (formerly tmr0).
getcount
movf bufh,0 ;tmr0=bufh value>>w
movwf fhi ;save in fhi might be able to delete fhi,count
clrf count ;keep track of the toggles
toggle
incf count,1 ;increment
banksel 0x80 ;***** BANK 1 *****
bcf 0x81,4 ;toggle T0SE
nop
bsf 0x81,4
banksel 0x00 ;***** BANK 0 *****
movf tmr0,0 ;see if tmr0 incremented
subwf fhi,0
btfsc status,2 ;Z=0 then skip
goto toggle ;no then toggle again
comf count,1 ;else complement count
incf count,0 ;and increment>>w
movwf bufl ;save in bufl
return
Shift3x ;enter with 0x27-0x28-0x29-0x2A binary. Exit shifted left 3x
movlw 0x03 ;3x
movwf shiftctr
Shift1x
movlw 0x27
movwf fsr
bcf status,0 ;clr C
rlf indf ;LSB
incf fsr ;0x28
rlf indf
incf fsr ;0x29
rlf indf
incf fsr ;0x2A
rlf indf
decfsz shiftctr,1
goto Shift1x
return
DCdet ;DC Chg/Bat Detect
banksel 0x80 ;***** Bank 1 ******
movlw 0x32 ; 0x30 default ;port a-write 0011 0010 A1 Digital Input
movwf trisa
banksel 0x00 ;***** Bank 0 ******
call wait1
bcf flags,2 ;clr the DC Ext flag
btfsc porta,1
bsf flags,2
banksel 0x80 ;***** Bank 1 ******
movlw 0x30 ; 0x30 default ;port a-write 0011 0000 A1 Digital Input
movwf trisa
banksel 0x00 ;***** Bank 0 ******
btfss flags,2
goto IntCall
call Ext
return
IntCall call Int
return
DVM ; detect DC value >> dvm. Setup cmcon then return to normal
movlw 0x10 ;initialize dvm
movwf dvm
movlw 0x12 ;default is 0x07
movwf cmcon
banksel 0x80 ;***** Bank 1 ******
movlw 0x31 ; 0x30 default ;port a-write 0011 0001
movwf trisa
banksel 0x00 ;***** Bank 0 ******
call wait5
dvmloop
decf dvm ;initial is now 0x0F
movlw 0xA0 ;to setup vrcon reference
addwf dvm,0 ;sum in w
banksel 0x80 ;***** Bank 1 ******
movwf vrcon ; to vrcon
banksel 0x00 ;***** Bank 0 ******
call wait5 ;~5msec @12.288MHz
btfsc cmcon,6 ;b6=CM1Vout. '1'=RA0>Vref. '0'=RA0Vref
sublw 0x00 ;IF Then Z=1
btfss status,2
goto dvmloop ;else drop to restore
restore
banksel 0x00 ;***** Bank 0 ******
movlw 0x07 ;default is 0x07
movwf cmcon
banksel 0x80 ;***** Bank 1 ******
movlw 0x30 ; 0x30 default ;port a-write 0011 0000
movwf trisa
banksel 0x00 ;***** Bank 0 ******
dispdvm ;enter N=dvm=(0x00-0x0F). If N<=0x09 then 0x20,0x3N.
;If dvm>0x09 then 0x31,0x3(N-0x0A).
movf dvm,0 ;>>w
sublw 0x09 ;if w<=0x39 then C=1, else C=0
btfss status,0 ; test C
goto teens
movlw 0x20 ;spa
call qst
movlw 0x30
addwf dvm,0
call qst
return
teens
movlw 0x31 ;'1'
call qst
movlw 0x26
addwf dvm,0
call qst
return
pause clrf 0x22 ;two nested timing loops 196msec@4MHz 63.8msec@12.288MHz
pause1 incfsz 0x22,1 ;inc 0x22, skip if 0
goto pause2
return
pause2 incfsz 0x23,1 ;inc 0x23,skip if 0
goto pause2
goto pause1
p1 movlw 0xF0 ;stabilize clock 63.8ms*8=510ms @ 12.288MHz
movwf 0x24
p2 call pause
incfsz 0x24,1
goto p2
return
;wait1 routine ~0.77msec@4MHz---OK, 0.25ms @ 12.288MHz
wait1 clrf 0x22 ;timing loop
wait2 incfsz 0x22,1 ;inc 0x22, skip if result=0
goto wait2
return
;wait3 routine ~2.31 msec@4MHz ~0.75msec @ 12.288MHz
wait3 call wait1
call wait1
call wait1
return
;wait5 routine ~5 msec@12MHz
wait5 call wait3
call wait3
call wait3
call wait3
call wait3
call wait3
call wait3
return
end