ASM code mod for VK3BHR counter: I'm "coding challenged" (SOLVED!!) - Page 1
Forum section: electronics / rf-microwave

author: Dom13c
author_rank: Regular Contributor
timestamp: December 27, 2020, 10:49:44 pm
content: All I needed was a low power frequency counter built around 16F628A( I had a pair laying around for 2/3 years but never got a chance to use them). So, stumbling across the web I came across the VK3BHR counter and his famous LC meter. Got the LC meter made and it works flawlessly.( For that bought first the K150 , then after asking here on EEVBlog , I bought a P@cKit3 clone. Only the I was able to program the PIC for the LC meter)But the counter's display was not up to my taste cause it used a 00.00000MHz format. So, almost in a blindfolded manner , using guesswork and looking at the comments in the code , I, somehow, got the frequency display format changed successfully to 00.000.00MHz.But this led to a problem of the suffixes like "CAL", "USB","LSB".... to be printed out of the display, i.e. last letter of them is not shown. But if I try to use the "pin 18 high = first line , pin 18 = low second line after character 8" , the MHz also goes to the second line, which is..... obvious.but I don't want that.So, I tried to modify the code further so that only the suffixes would go to the second line when PIN18 is pulled low. ( without knowing what to do to achieve that)I even tried to remove the pin 18 hi/lo condition as a whole and move those suffixes permanently to the second line. But then the suffixes don't get cleared even when I remove the jumpers to do calibration/adding IF offsets etc. Only way to do that is to restart the meter....This clearly isn't a solution.......So, if anyone can help me to mod the code , I'd feel highly appreciated.Link to the code .....https://sites.google.com/site/vk3bhr/home/fm2/sourceAlso attached the modified version of the code

author: ledtester
author_rank: Super Contributor
timestamp: December 27, 2020, 11:15:57 pm
content: QuoteFind this code:Code:CALL PutNybbtfss FIXIT ; Test input 1 = just returnCALL LINE2 ; 0 = fix bad displaymovlw mhz ; WRITE " Mhz" AT end OF LINEgoto pmsg ; includes RETURNThis is where the rightmost digit is printed followed by "MHz". The call to LINE2 is where the move to the second line is performed. If you comment out the "btfss" and "call" instructions then this move will never be made, i.e. the setting of pin 18 will be ignored.

author: ledtester
author_rank: Super Contributor
timestamp: December 28, 2020, 12:17:25 am
content: QuoteWhat about 1) creating a subroutine which clears the second line, and 2) adding calls to this routine wherever it is needed.It seems the easiest way to do (1) isCode:; in the Text Strings section add:Spaces dt " ",0 ; 16 spaces followed by a zero; new routine to clear the second line:ClearLine2 CALL LINE2movlw Spacesgoto pmsg ; return via pmsgNot sure if this will slow down the display or not.For instance, you might add it after the printing of "MHz" in which case the code fragment in my first reply would look like:Code:CALL PutNyb; commented out btfss FIXIT ; Test input 1 = just return; commented out CALL LINE2 ; 0 = fix bad displaymovlw mhz ; WRITE " Mhz" AT end OF LINECALL pmsggoto ClearLine2 ; return via ClearLine2This should work if you add a call to ClearLine2 everywhere you know only a single line is being displayed.

author: Dom13c
author_rank: Regular Contributor
timestamp: December 28, 2020, 05:32:06 pm
content: Thank you for paying attention to this apparently silly problem of mine @ledtester.with your kind help I've got that "MHz" shifting problem fixed. But can't get the "second line clear thing" fixed as I can't mention the conditions of when to perform the " ClearLine2" subroutine to our tiny PIC , via assembly.I've gone through the original code several times to make out how VK3BHR has done that , but I'm out of luck.for a moment I thought of defining a subroutine(!!!!!?I'M A NOOB)#define ClearLine2 PORTB,0x04#define ClearLine2 PORTB,0x06#define ClearLine2 PORTB,0x07i.e. when they are held low the text should be there, but when left floating(1) , the spaces should get printed on the second line............. But I can't make out how to define the pin states i.e. high /lowAnd another silly question...... going through the code( while fixing the MHz problem, as you said) I saw the line#define FIXIT PORTA,0x01( i.e pin 18 of 628A)in the comments VK3BHR wrote, "1 = good display , 0= do CRLF at "chr 8" "would it be possible for you to suggest which part of the code needs to be changed to bring this value "8" to "14" ( 14 as 00.000.00 MHz takes 13 characters on the first line ).My hope is if this simple one can be solved ( is it simple!!!!?), fixing that would be enough to meet my needs............ cause that way I won't have to edit here and there on the code and also won't have to find out how the clearing operation is done in the original code.....DOM13C#define FIXIT POTRA, 0x01

author: ledtester
author_rank: Super Contributor
timestamp: December 29, 2020, 04:35:35 am
content: Post here as an text attachment the source code you are using and I will reply with the modified code you should try.

author: Dom13c
author_rank: Regular Contributor
timestamp: December 29, 2020, 11:43:05 am
content: ;The part I talked about is in the I/O configuration section;*******************************************************************;; "Digital" Frequency display;; Crystal freq. = 4.000MHz +/- a bit;;*******************************************************************;; First, let us choose our weapon - 16F84 or 16F628;; Comment out the next line [;#define F84] if using a 16F628#ifndef F84#define F628#endif;*******************************************************************;; Some Testing Stuff(tm);;#define testing 1 ; Comment out when testing finished;#define Two_Line 1 ; Un-comment for two line displays;************************ REVISION HISTORY *************************;; FM1.000 Originally from FM3/4 9:39pm 14 May 2002; As implemented in experimental 3.5MHz receiver;;*******************************************************************;; FM1.003 Fixed? major silliness in LO-IF code; Re-wrote USB/LSB suffix code; Added #defines for crook displays; Added #defines for two line displays; Wrapped #ifdef ... endif around debugging code;;*******************************************************************;; FM1.004 Added code to allow user to fix crook display; Deleted #defines for crook displays; Pin 18 is now input. 1 = good display, 0 = crook;;*******************************************************************;; FM2.000 New Hardware! Deleted external counter & gating; Now uses the same scheme as the LC Meter, with the; third byte of the count implemented in the PIC.; Basically, the "output" of the timer register is; counted within the gate timing loop.;;*******************************************************************;; FM2.001 Discovered that I don't need to use RA0 as a gate; cos RA4 can be used as a timer input, even when; defined as an output - all that is required is to; set it high to count or low to inhibit.; Jeez, Microchip are smart arses.; I dunno why I didn't spot this long ago.; (Can't be used on the LC Meter, cos its oscillator; needs to be clamped HIGH, not low as in this case).;;*******************************************************************;; FM2.002 Added 9600 baud serial output via RA0;;*******************************************************************;; FM2.003 Rewrote RollOver subroutine to use INTCON,T0IF bit.; Incorporated two bits from OvrFlow counter; to extend range to over 80MHz.;;*******************************************************************;; FM2.004 Changed to 32 bit counting.;;*******************************************************************;; FM2.005 Added "Calibrate" mode.;;*******************************************************************;; FM2.006 Moved "divide by 4" to increase resolution of; the stored IF offsets;;*******************************************************************;; FM2.007 Moved "check for rollover" out of the inner MS400; timing loop and adjusted loop count appropriately; The aim - to improve the resolution of the software; calibration by a factor of around 13 to 15 times.;;*******************************************************************;; fm2b.007 Ported to 16F628; FM2c.007 Introduced macros; fm2.008 Renumbered;;*******************************************************************;; fm2.009 Cleaned up AM IF Offset calculation; Converted some inline code to subroutines; Created new 32 bit "copy" macro; Adjusted calibration slightly; Added a "Processor =" message;;*******************************************************************;o-----o-----o-----o-----o-----o-----o-----o-----o-----o-----o-----o;*******************************************************************;; Some frequently used code fragments; Use macros to make mistreaks consistently.;;-------------------------------------------------------------------; Select Register Bank 0bank0 macroerrorlevel +302 ; Re-enable bank warningbcf STATUS,RP0 ; Select Bank 0endm;-------------------------------------------------------------------; Select Register Bank 1bank1 macrobsf STATUS,RP0 ; Select Bank 1errorlevel -302 ; disable warningendm;-------------------------------------------------------------------; Copy a 32 bit thing from one place to anothercopy macro from,tomovf from+0,Wmovwf to+0movf from+1,Wmovwf to+1movf from+2,Wmovwf to+2movf from+3,Wmovwf to+3endm;*******************************************************************;; CPU configuration;#ifdef F84MESSG "Processor = 16F84"#define RAMStart 0x0C ; by VK3BHRprocessor 16f84include <p16f84.inc>__config _HS_OSC & _PWRTE_ON & _WDT_OFF#endif#ifdef F628MESSG "Processor = 16F628"#define RAMStart 0x20processor 16f628include <p16f628.inc>__config _HS_OSC & _PWRTE_ON & _WDT_OFF & _CP_OFF & _BODEN_ON & _LVP_OFF#endif;*******************************************************************;; I/O configuration;#define S_out PORTA,0x00 ; 9600 baud serial out#define PUFF PORTA,0x00 ; Testing counter out#define FIXIT PORTA,0x01 ; 1 = "good display"; 0 = do CRLF at "chr 8"#define ENA PORTA,0x02 ; Display "E"#define RS PORTA,0x03 ; Display "RS"#define CLAMP PORTA,0x04 ; Pull-down the timer input#define Store PORTB,0x04 ; Pin 10, 0 = Measure BFO#define Add_LO PORTB,0x05 ; Pin 11, 0 = RF := LO + IF; 1 = RF := | LO + (-IF) |#define BFO_Lo PORTB,0x06 ; Pin 12, 0 = BFO on lower freq.#define BFO_Hi PORTB,0x07 ; Pin 13, 0 = BFO on higher freq.#define Prg_FLG FLAGS,0x05#define AMflag FLAGS,0x03 ; 0 = Don't print USB/LSB suffix#define beq bz ; Motorola syntax branches#define BEQ bz#define BNE bnz#define bne bnz#define BCC bnc#define bcc bnc#define BCS bc#define bcs bc#define BRA goto#define bra goto;*******************************************************************;; file register declarations: uses only registers in bank0; bank 0 file registers begin at 0x20 in the 16F628;;*******************************************************************cblock RAMStartdbg0:4 ; Debugging stuffdbg1:4dbg2:4dbg3:4dbg4:4dbg5:4bcd:5 ; BCD, MSD firstSBflag ; 0 = Lower BFO frequency; 1 = HigherCOUNT ; Bin to BCD convert (bit count)cnt ; (BCD BYTES)CHRTEMP ; DATS/Putchr temporarypmsg_t ; Used by PMSGFLAGSS_Wtemp ; "debug" VariablesS_countD_WtempD_StempD_FSRD_hexendc#ifdef F84Part2 equ D_hex+1 ; Just tack on end#endif#ifdef F628Part2 equ 0x70 ; $70-7F Visible from all banks#endifcblock Part2COUNT1 ; Used by delay routinesCOUNT2 ; Timing (100ms)COUNT3 ; Timing (100ms)COUNT4 ; Timing (400ms)AccA:4 ; Binary, MSByte firstAccB:4 ; Intermediate frequencyHold:4 ; Used in "cal" modeendc;**********************************************************;; Begin Executable Stuff(tm);org 0GO clrwdt ; 0 << Resetclrf INTCON ; 1 No interrupts#ifdef F628movlw 0x07 ; 2 Comparator offmovwf CMCON ; 3#endifgoto START ; 4 << Interrupt.;**********************************************************;; Part of string printer;pmsub movwf PCL ; Goto Wnop ; Just in casepm_end return;**********************************************************;; Text Strings (stored in RETLWs);mhz dt " MHz ",0Spaces dt " ",0USB dt "USB",0LSB dt "LSB",0Prog dt "PRG",0Cal dt "CAL",0adv1 dt "Freq. Counter ",0 ;Dom13c edit , 6:24PM 12/24/2020MOVLW 0x28 ; move to second line of the display: DOM13C edit 11:00PM , 12/24/2020adv2 dt " DOM13C",0 ;DOM13C edit 11:00PM , 12/24/2020ovr1 dt " Over ",0ovr2 dt "Range ",0#ifdef Two_Lineadv3 dt "1234567890ABCDEF",0#endif;**********************************************************;; Main Program;START call InitIO ; INITIALISE PORTSCLRF PORTACLRF PORTBbsf S_out ; Serial output to idleCALL LCDINIT ; INITIALIZE LCD MODULEMOVLW adv1 ; Sign oncall pmsgbtfss FIXIT ; Test input 1 = just returnCALL LINE2 ; 0 = fix bad displaymovlw adv2call pmsgCALL MS512 ; Delay for about 1 sec.CALL MS512 ; 0.512 sec x 2CALL CLEAR;**********************************************************;; Check if in "Calibrate" mode;btfsc Store ; If grounded initiallygoto newbit ; then were in "cal"MOVLW 0xfd ; Set initial counterMOVWF Hold+0 ; valueMOVLW 0xff ;MOVWF Hold+1 ; for a 4 MHZ XTALMOVLW 0xbfMOVWF Hold+2MOVLW 0x00 ; UnusedMOVWF Hold+3GetCal call Measurecall Displaymovlw Cal ; Say "we're calibrating"call pmsgCALL HOME;; Adjust Cal value;cal_dn btfsc BFO_Logoto cal_upincf Hold+2,f ; Add 1bne inc_xitincf Hold+1,fbne inc_xitincf Hold+0,finc_xit goto StorCalcal_up btfsc BFO_Higoto StorCal;; Hold := Hold + (1-) ; Subtract 1;Hadd_2 movlw 0xff ; Process LS byteaddwf Hold+2,Fbcc Hadd_1 ; If no carry,do nextincf Hold+1,f ; Else roll over higherbne Hadd_1 ; bytes as appropriateincf Hold+0,f ; may roll over MSByteHadd_1 movlw 0xff ; Process next byteaddwf Hold+1,Fbcc Hadd_0 ; If no carry,do nextincf Hold+0,f ; may roll over MSByteHadd_0 movlw 0xff ; Process next byteaddwf Hold+0,F;; Time to save "Cal" value?;StorCal btfss Store ; Ready to store it?goto GetCalcall MS512 ; Delay 0.5 secbtfss Store ; De-bouncegoto GetCalcopy Hold,AccB ; Write EEPROM from AccBmovlw 0x10 ; EEADR of Cal valuecall EE_WR;**********************************************************;; Begin a new measurement cycle;newbit movlw 0x10 ; EEADR of Cal valuecall EE_RD ; in AccBcopy AccB,Hold ; Get timing "constant"call HOME ; Display readyclrf SBflag ; 0 = Lower BFO frequency; 1 = Higherbcf AMflag ; 0 = No USB/LSB suffixbcf Prg_FLGbtfsc Store ; Doing "BFO STORE"?goto GetOffscall MS512 ; Delay 0.5 secbtfsc Store ; De-bouncegoto GetOffsGetIf call Measure ; Get freq in AccA:4copy AccA,AccB ; For EEPROM Writingcall Display ; Display freq in AccAmovlw Prog ; Say "we're programming"call pmsgCALL HOMEbtfss Store ; Ready to store it?goto GetIfcall MS512 ; Delay 0.5 secbtfss Store ; De-bouncegoto GetIfbsf Prg_FLG ; Flag "to be stored"GetOffs btfss BFO_Hi ; Which Offset??goto Get2 ; Point @ EEPROMbtfss BFO_Lo ; 4 bytes eachgoto Ch2 ; BFO low link onlygoto Ch3 ; No linksGet2 btfss BFO_Logoto Ch0 ; Both linksgoto Ch1 ; BFO high link onlyCh0 movlw 0x00 ; Offset channel 0 (both links fitted)goto EndOffCh1 bsf AMflag ; We're gunna printcomf SBflag,f ; that BFO is on higher frequencymovlw 0x04 ; Offset channel 1 (BFO_Hi link fitted)goto EndOffCh2 bsf AMflag ; We're gunna print; that BFO is on lower frequencymovlw 0x08 ; Offset channel 2 (BFO_Lo link fitted)goto EndOffCh3 movlw 0x0C ; Offset channel 3 (no links fitted); goto EndOffEndOff btfsc Prg_FLG ; Storing Offset?goto Do_St ; If not, thencall EE_RD ; must be reading.goto Do_MeasDo_St call EE_WR;; Now have IF in AccB;Do_Meas call Measure ; Measure Local Osc Freq.;; Now have LO in "AccA"; and IF in "AccB";Add_Sub btfss Add_LO ; Add or Sub LO freq?goto AddLSB ; Clear = just addcall MinusA ; RF := |IF - LO|; SBflag is OKAddLSB call AplusB;; Fix overflow. If negative then make positive;btfss AccA+0,7 ; Set? (=Overflow)goto OK2go ; Clear = OK 2 printcall MinusA ; Make positive andcomf SBflag,f ; Swap USB/LSB;; Display resulting number in AccA;OK2go call Display ; display result at last;; Print suffix - USB, LSB or nuffin;btfsc AMflag ; Do we print at all?goto trySBfmovlw Spaces ; nuffin = spacesgoto EndMsgtrySBf btfsc SBflag,0 ; Which sideband?goto pLSBmovlw USB ; USB obviouslygoto EndMsgpLSB movlw LSB ; LSB; goto EndMsgEndMsg call pmsg ; Print selected trailer#ifdef Two_LineCALL LINE2 ; WRITE second LINEmovlw adv3call pmsg#endifgoto newbit ; Start next measurement;**********************************************************;; AccA := AccA + AccB;AplusB movf AccB+3,W ; Process LSBaddwf AccA+3,Fbcc Add_2 ; If no carry,do nextincf AccA+2,f ; Else roll over higherbne Add_2 ; bytes as appropriateincf AccA+1,fbne Add_2incf AccA+0,f ; may roll over MSByteAdd_2 movf AccB+2,W ; Process next byteaddwf AccA+2,Fbcc Add_1 ; If no carry,do nextincf AccA+1,f ; Else roll over higherbne Add_1 ; bytes as appropriateincf AccA+0,f ; may roll over MSByteAdd_1 movf AccB+1,W ; Process next byteaddwf AccA+1,Fbcc Add_0 ; If no carry,do nextincf AccA+0,f ; may roll over MSByteAdd_0 movf AccB+0,W ; Process next byteaddwf AccA+0,Freturn;**********************************************************;; Negate number in AccA (2's complement form);MinusA comf AccA+0,f ; Complement all bitscomf AccA+1,f ; of numbercomf AccA+2,fcomf AccA+3,fincf AccA+3,f ; Add 1bne N_xitincf AccA+2,fbne N_xitincf AccA+1,fbne N_xitincf AccA+0,fN_xit return;**********************************************************;; Divide AccA:4 by 4;;**********************************************************Div4 call Div2 ; Divide AccA:4 by 4;**********************************************************;; Divide AccA:4 by 2;;**********************************************************Div2 rrf AccA+0,frrf AccA+1,frrf AccA+2,frrf AccA+3,fbcf AccA+0,7 ; Possible bad carry in.return;**********************************************************;; Print String addressed by W; Note: Strings are in program space;pmsg movwf pmsg_t ; Temp for pointerpm1 movf pmsg_t,W ; Get current pointercall pmsubandlw 0xff ; Test returned valuebeq pm_end ; NULL = All donecall DATSincf pmsg_t,Fgoto pm1;**********************************************************;; Delay for 400ms (trimmed for actual clock freq); Check for Timer register roll over and count 'em;; Uses: W, COUUNT1, COUNT2, COUNT3 & others;;**********************************************************MS400 MOVF Hold+0,w ; 100 MS DELAY LOOPMOVWF COUNT1 ; 4 MHZ XTALMOVF Hold+1,w ; Count upMOVWF COUNT2 ; to 24 bit overflowMOVF Hold+2,wMOVWF COUNT3L3 INCFSZ COUNT3,FGOTO L3call RollOver ; Check for Timer0 RollOverINCFSZ COUNT2,FGOTO L3INCFSZ COUNT1,FGOTO L3RETLW 0;**********************************************************;; SEND A COMMAND BYTE TO LCD DISPLAY MODULE;STROBE BCF RS ; SELECT COMMAND REGISTERGOTO CM;**********************************************************;; Put a BCD nybble to display;PutNyb ANDLW 0x0F ; MASK OFF OTHER PACKED BCD DIGITADDLW 0x30 ; Convert BIN to ASCII;**********************************************************;; Put a data byte to display;DATS movwf TEMP ; Save character for LCDcall putchrmovf TEMP,wBSF RS ; SELECT DATA REGISTERCM MOVWF CHR ; STORE CHAR TO DISPLAYSWAPF CHR,W ; SWAP UPPER AND LOWER NIBBLES (4 BIT MODE)call PB_dlyMOVF CHR,W ; GET CHAR AGAIN;**********************************************************;; Put 4 bits to LCD & wait (untrimmed);PB_dly ANDLW 0x0F ; MASK OFF UPPER 4 BITSMOVWF PORTB ; SEND DATA TO DISPLAYBSF ENA ; ENA HIGHNOPBCF ENA ; ENA LOW; Fall into 200us DELAY subroutine;**********************************************************;; Delay for 200us (untrimmed);; Uses: W, COUNT1;;**********************************************************D200usDELAY MOVLW 0x42 ; DELAY 200usMOVWF COUNT1NXT5 DECFSZ COUNT1,FGOTO NXT5RETLW 0;**********************************************************;; Delay for 2ms (untrimmed);; Uses: W, COUNT2, COUNT1;;**********************************************************MS2 MOVLW 0x0A ; DELAY 2msMOVWF COUNT2LP15 call D200usDECFSZ COUNT2,FGOTO LP15RETLW 0;**********************************************************;; Delay for 512ms (untrimmed);; Uses: W, COUNT3, COUNT2, COUNT1;;**********************************************************MS512 clrw ; 0 -> 256 loops;**********************************************************;; Delay for multiples of 2ms (untrimmed);; Uses: W, COUNT3, COUNT2, COUNT1;;**********************************************************MS2xW MOVWF COUNT3LPx15 call MS2DECFSZ COUNT3,FGOTO LPx15RETLW 0;******************************************************************;; Convert 32-bit binary number at <AccA:4> into a bcd number; at <bcd:5>. Uses Mike Keitz's procedure for handling bcd; adjust. Microchip AN526;B2_BCDb2bcd movlw .32 ; 32-bitsmovwf COUNT ; make cycle counterclrf bcd+0 ; clear result areaclrf bcd+1clrf bcd+2clrf bcd+3clrf bcd+4b2bcd2 movlw bcd ; make pointermovwf FSRmovlw .5 ; Number of BCD bytes?movwf cnt ; 2 BCD digits per byte; Mike's routine:b2bcd3 movlw 0x33addwf INDF,f ; add to both nybblesbtfsc INDF,3 ; test if low result > 7andlw 0xf0 ; low result >7 so take the 3 outbtfsc INDF,7 ; test if high result > 7andlw 0x0f ; high result > 7 so oksubwf INDF,f ; any results <= 7, subtract backincf FSR,f ; point to nextdecfsz cnt,fgoto b2bcd3rlf AccA+3,f ; get another bitrlf AccA+2,frlf AccA+1,frlf AccA+0,frlf bcd+4,f ; put it into bcdrlf bcd+3,frlf bcd+2,frlf bcd+1,frlf bcd+0,fdecfsz COUNT,f ; all done?goto b2bcd2 ; no, loopreturn ; yes;*********** INITIALISE LCD MODULE 4 BIT MODE ***********************LCDINIT CALL MS512 ; Wait 0.512 sec for LCD RESETBCF RS ; REGISTER SELECT LOWBCF ENA ; ENABLE LINE LOWMOVLW 0x03 ; 1call PB_dlyCALL MS512 ; WAIT FOR DISPLAY TO CATCH UPMOVLW 0x03 ; 2call PB_dlyMOVLW 0x03 ; 3call PB_dlyMOVLW 0x02 ; Fn set 4 bitscall PB_dlyMOVLW 0x28 ; DISPLAY 2 Line , 5x7 Dot'sCALL STROBE ; Suggested by PA0EJHCALL DELAYMOVLW 0x0C ; 0x0C DISPLAY ONCALL STROBECALL DELAYMOVLW 0x06 ; 0x06 ENTRY MODE SETCALL STROBECALL DELAYMOVLW 0x01 ; 0x01 CLEAR DISPLAYCALL STROBECALL MS2RETLW 0;************ MOVE TO START OF LINE 2 *****************LINE2 MOVLW 0xC0 ; ADDRESS FOR SECOND LINE OF DISPLAYCALL STROBEgoto DELAY;************ CLEAR DISPLAY ***************************CLEAR MOVLW 0x01 ; COMMAND TO CLEAR DISPLAYCALL STROBEgoto MS2 ; LONGER DELAY NEEDED WHEN CLEARING DISPLAY;*********** MOVE TO HOME *****************************HOME call crlf ; SerialMOVLW 0x02 ; COMMAND TO HOME LCD DISPLAYCALL STROBEgoto MS2;********************************************************************; Initialise Input & Output devices;********************************************************************InitIO bank1movlw 0x37 ; Option registermovwf OPTION_REG ; Port B weak pull-up enabled; INTDEG Don't care; Count RA4/T0CKI; Count on falling edge; Prescale Timer/counter; divide Timer/counter by 256; PORTA:-movlw 0x02 ; initialise data direction; 1 = input, 0 = output;; PORTA has 5 pins 4 3 2 1 0; 0x02 = 0 0 0 0 0 0 1 0;movwf TRISA ; PORTA<0> = Serial + Debugging Out; PORTA<1> = FIXIT (input); PORTA<2> = LCD "E" Out; PORTA<3> = LCD "RS" Out; PORTA<4> = "Input" with pull-down; Actually an output.; PORTA<5:7> = not implemented in 16F84;; PORTB:-movlw 0xf0 ; initialise data direction; PORTB has 8 pins; port pin 7 6 5 4 3 2 1 0; 0xf0 = 1 1 1 1 0 0 0 0;movwf TRISB ; PORTB<0> = LCD "DB4"; PORTB<1> = "DB5"; PORTB<2> = "DB6"; PORTB<3> = "DB7"; PORTB<4> = Input; PORTB<5> = Input; PORTB<6> = Input; PORTB<7> = Inputbank0return;**********************************************************;; Measure Frequency. Stash in "AccA:4";Measure bcf CLAMP ; CLOSE GATE for safetybcf INTCON,T0IF ; Clear any previous overflowCLRF TMR0 ; RESET INTERNAL COUNT (INCLUDING PRESCALER); See page 27 Section 6.0CLRF AccA+0 ; Ready to receive 32 bit numberCLRF AccA+1CLRF AccA+2CLRF AccA+3bsf CLAMP ; OPEN GATECALL MS400 ; 400MS DELAYbcf CLAMP ; CLOSE GATE (COUNT COMPLETE)nop ; and allow time fornop ; the registers to catch upnopnopnopcall RollOver ; Final check, just in caseMOVF TMR0,WMOVWF AccA+2; Now empty the prescalerPSC1 bank1bcf OPTION_REG,T0SE ; Clock the prescalernopbsf OPTION_REG,T0SEbank0DECF AccA+3,F ; Decrement the countermovf TMR0,W ; Has TMR0 changed?xorwf AccA+2,W ; if unchanged, XOR -> 0beq PSC1; AccA : AccA+1 : AccA+2 : AccA+3 now holds 32 bit result; Rollover subroutine has set AccA+0 and AccA+1 suitably.return;**********************************************************;; Account for TMR0 overflows when counting; Check at regular intervals and handle as; necessary.;; Needs to be done at less than 936us (@ 70MHz in); intervals, or else it can lose counts.;RollOverbtfss INTCON,T0IF ; Rolled over?goto RO3 ; NoRO1 bcf INTCON,T0IF ; Yes. ACK!INCF AccA+1,f ; Count itbne RO2 ; Overflowed?incf AccA+0,f ; No need to checkRO2 return; Balance path lengthsRO3 nopnopgoto RO2;**********************************************************;; Display frequency;; Display contents of AccA+0...AccA+3 on LCD; First convert to BCD, Then ASCII (nybble at a time);; In present version, divide ACCA:4 by 4 since gate; time = 0.4 second, then ignore 2 most significant BCD digits;Display call Div4CALL B2_BCD ; CONVERT all AccA TO BCDMOVF bcd+1,W ; 10's of MHzANDLW 0x0F ; MASK OFF OTHER PACKED BCD DIGITBTFSS STATUS,Z ; IS IT A '0' ?GOTO NoBlankMOVLW 0x20 ; YES PRINT A BLANK SPACECALL DATSGOTO NxtDigNoBlank CALL PutNyb ; Display 10's of MHzNxtDig swapf bcd+2,W ; 1's of MHzCALL PutNybMOVLW '.' ; Decimal PointCALL DATSMOVF bcd+2,W ; 100's of KHzCALL PutNybSWAPF bcd+3,W ; 10's of KHzCALL PutNybMOVF bcd+3,W ; 1's of KHzCALL PutNybMOVLW '.' ; Decimal Point 1's of KHz. modified by DOM13C at 10:22 , 12/24/2020CALL DATS ;Won't lie ; but I'm stumbling in every corner of this code,;as I know nothing about programming; But lookimg at the similarities , I can at least add the features; I'm looking for(DOM13C)SWAPF bcd+4,W ; 100's of HzCALL PutNybMOVF bcd+4,W ; 10's of HzCALL PutNyb; btfss FIXIT ; Test input 1 = just return; CALL LINE2 ; 0 = fix bad displaymovlw mhz ; WRITE " Mhz" AT end OF LINEgoto pmsg ; includes RETURN;********************************************************************; Read EEPROM into "AccB" (AccB must be visible in both; W -> memory to read memory banks 0 & 1);********************************************************************EE_RD#ifdef F628bank1#endifMOVWF EEADR ; Address to read#ifdef F628bank0#endifXORLW 0x0C ; Special case (no links)BEQ AVERAGECALL EE_RMOVWF AccB+0CALL EE_RincMOVWF AccB+1CALL EE_RincMOVWF AccB+2CALL EE_RincMOVWF AccB+3RETURN;--------------------------------------------------------------------#ifdef F84EE_Rinc INCF EEADR,F ; bump addressEE_R bank1BSF EECON1,RD ; EE Readbank0MOVF EEDATA,W ; W = EEDATARETURN#endif;--------------------------------------------------------------------#ifdef F628EE_Rinc bank1INCF EEADR,F ; bump addressEE_R bank1BSF EECON1,RD ; EE ReadMOVF EEDATA,W ; W = EEDATAbank0RETURN#endif;--------------------------------------------------------------------AVERAGE movlw 0x04 ; AM - use avg BFO freq.call EE_RD ; Read in one BFO freqcopy AccB,AccA ; Into AccAmovlw 0x08 ; Then secondcall EE_RD ; into AccBcall AplusB ; Add 'emcall Div2 ; get average in AccAcopy AccA,AccB ; and in AccBreturn;********************************************************************; Write EEPROM from "AccB" (AccB must be visible in both; W -> memory to write memory banks 0 & 1);********************************************************************#ifdef F84EE_WR MOVWF EEADR ; Address to writeMOVF AccB+0,W ; Data byte #0CALL EE_WMOVF AccB+1,W ; Data byte #1CALL EE_WincMOVF AccB+2,W ; Data byte #2CALL EE_WincMOVF AccB+3,W ; Data byte #3CALL EE_WincRETURNEE_Winc INCF EEADR,F ; bump addressEE_W MOVWF EEDATAbank1BSF EECON1,WREN ; Enable WriteMOVLW 0x55 ;MOVWF EECON2 ; Write 0x55MOVLW 0xAA ;MOVWF EECON2 ; Write 0xAABSF EECON1,WR ; Set WR bit (begin write)EE_W2 BTFSC EECON1,WR ; Wait for write to finishGOTO EE_W2BCF EECON1,EEIF ; clear interruptsbank0RETURN#endif;--------------------------------------------------------------------#ifdef F628EE_WR bank1MOVWF EEADR ; Address to writeMOVF AccB+0,W ; Data byte #0CALL EE_WMOVF AccB+1,W ; Data byte #1CALL EE_WincMOVF AccB+2,W ; Data byte #2CALL EE_WincMOVF AccB+3,W ; Data byte #3CALL EE_Wincbank0RETURNerrorlevel -302 ; In Bank 2EE_Winc INCF EEADR,F ; bump addressEE_W MOVWF EEDATABSF EECON1,WREN ; Enable WriteMOVLW 0x55 ;MOVWF EECON2 ; Write 0x55MOVLW 0xAA ;MOVWF EECON2 ; Write 0xAABSF EECON1,WR ; Set WR bit (begin write)EE_W2 BTFSC EECON1,WR ; Wait for write to finishGOTO EE_W2bank0BCF PIR1,EEIF ; clear interruptsbank1RETURNerrorlevel +302#endif;********************************************************************; Testing counter;********************************************************************ctest movlw 0xfe ; MS byte of loop countmovwf COUNT3 ; Counted upward till it overflowsmovlw 0x1dmovwf COUNT2movlw 0xc0movwf COUNT1cloop bcf PUFF ; Toggle counter input oncebsf PUFFincfsz COUNT1,fgoto cloopincfsz COUNT2,fgoto cloopincfsz COUNT3,fgoto cloopreturn;***********************************************************************;; Debugging Memory & Register dump;debugMOVWF D_Wtemp ; Copy W to temp register,SWAPF STATUS,W ; Swap status to be saved into WMOVWF D_Stemp ; Save status to D_Stemp registermovf FSR,W ; Save FSRmovwf D_FSR<b

author: ledtester
author_rank: Super Contributor
timestamp: December 29, 2020, 05:42:29 pm
content: Hi Dom13c,Can you *attach* the code as a text file? See the "Attachments and other options" after the reply input text box. Thanks!

author: johnh
author_rank: Regular Contributor
timestamp: December 29, 2020, 11:15:56 pm
content: Helping handshere is the link to the project pagehttps://sites.google.com/site/vk3bhr/home/fm2And attached the source code

author: ledtester
author_rank: Super Contributor
timestamp: December 30, 2020, 02:28:58 am
content: Hi johnh, thanks for trying to help out. Unfortunately the attachment contained HTML escapes like &amp, &lt, etc.I was able to extract the asm code from the web page, but it would be nice to know what changes the OP made to their copy.Attached are two files. The first is my cleaned-up version of the original code -- hopefully it doesn't contain any errors.The second is my modified version (-v2). It will always place indicators like "USB", "LSB", "CAL" on the second line. It should also blank out those indicators when they are not being displayed.Here is a diff of the two versions:Code:--- freq-counter-orig.txt 2020-12-29 20:07:25.987769700 -0600+++ freq-counter-v2.txt 2020-12-29 20:23:18.415716800 -0600@@ -257,6 +257,7 @@adv2 dt "- VK3BHR",0ovr1 dt " Over ",0ovr2 dt "Range ",0+Blanks16 dt " ",0#ifdef Two_Lineadv3 dt "1234567890ABCDEF",0#endif@@ -846,10 +847,14 @@CALL PutNybMOVF bcd+4,W ; 10's of HzCALL PutNyb- btfss FIXIT ; Test input 1 = just return- CALL LINE2 ; 0 = fix bad displaymovlw mhz ; WRITE " Mhz" AT end OF LINE- goto pmsg ; includes RETURN+ CALL pmsg+ CALL LINE2 ; clear out second line+ movlw Blanks16+ call pmsg+ CALL LINE2 ; return cursor to start of second line+ return+;********************************************************************; Read EEPROM into "AccB" (AccB must be visible in both; W -> memory to read memory banks 0 & 1)The idea is very simple... after displaying the frequency it will always blank out the second line and place the cursor at the start of the second line.The "FIXIT" switch on pin 18 is ignored (except for the start message).Note: I do not have a PIC assembler, but I'm pretty confident it'll work.

author: Dom13c
author_rank: Regular Contributor
timestamp: December 30, 2020, 12:29:35 pm
content: Quote from: ledtester on December 29, 2020, 05:42:29 pmMY apologies for being late at replying and acting dumb....I'm posting here my modified version in text format in case the one you modified , spending your valuable time, doesn't work for the real hardware.....And thank you again and again for helping me out here......DOM13C

author: Dom13c
author_rank: Regular Contributor
timestamp: December 30, 2020, 02:36:58 pm
content: Quote from: ledtester on December 30, 2020, 02:28:58 amTHANK YOU ONCE AGAIN!!!!!@ledtester......That modified code got assembled in MPLAB V8.92 flawlessly... (except for the first time when I left Debugging option selected instead of release before assembling the code)I just added the "." after 1's of KHz value part to your modification, and hallelujah!It works up to my requirements.

author: ledtester
author_rank: Super Contributor
timestamp: December 30, 2020, 11:54:58 pm
content: Great, I'm glad it worked for you