;******************************************************************** ; 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