# assembly code with 16 memory locations, only need 2 locations

#### Cyber

##### New Member
It would probably be a good idea for you to try and figure out the leading zero issue and let us know what you have tried first (translation: I am too lazy to go through all the code right now). I would suggest, however, that this section is a good place to start:

Code:
   swapf   BCDUi, W
andlw   0x0F
btfsc   STATUS, Z
movlw   0xF0           ;Modify to print a space in place of 0
call   LCDChar

movf   BCDUi, W       ;Want this to print a zero if it gets here
andlw   0x0F
call   LCDChar
(0x30 is ascii for zero and 0x20 is ascii for a space, it may be as simple as changing the first addlw 0x30 to addlw 0x20 )
Hi DrG
I have just tried your above modification, sorry to report it did not remove the leading zeros.
When I get a chance over the weekend I will look into it further.
Thank You

#### Cyber

##### New Member
Code [ASM]:

Code (ASM):
DispFreq
movf F0, W
movwf A0
movf F1, W
movwf A1
movf F2, W
movwf A2
movf F3, W
movwf A3

call BinToBCD

movlw LINE1
call LCDCmd ;Use leading zero blanking on first two digits
movlw " "
call LCDChar ;Preset first two to spaces
movlw " "
call LCDChar

movf BCDUi ;Test for Both MS digits = 00
btfsc STATUS, Z
goto NoMSDs

movlw LINE1 ;If not, reposition at start
call LCDCmd
swapf BCDUi, W
andlw 0x0F
btfsc STATUS, Z
movlw 0xF0 ;Modify to print a space in place of 0
call LCDChar

movf BCDUi, W ;Want this to print a zero if it gets here
andlw 0x0F
call LCDChar

Hi DrG.

I have just realised that the above part of the original code does in fact remove the first 2 leading zeros.
I did not notice it before because I did not take the frequency up that high before.
It will actually go up to 42949.67295 KHz.

I Still want to remove the other leading zeros.
I have tried a few modifications in this part of the code without success,

#### Cyber

##### New Member
Can I assume you would want to suppress leading zero digits up to the 'ones' digit in front of the decimal point? If so, you might modify the "DispFreq" subroutine to support using a mask variable, perhaps something like this;

Code:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;   display frequency, suppress leading zeros                     ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DispFreq
movf    F0,W            ;
movwf   A0              ;
movf    F1,W            ;
movwf   A1              ;
movf    F2,W            ;
movwf   A2              ;
movf    F3,W            ;
movwf   A3              ;
call    BinToBCD        ;
movlw   LINE1           ;
call    LCDCmd          ; line 1, column 0
;
;  prep for leading zero suppression.  a 0 value will print as
;  a space until a non-zero value changes the mask to '0' which
;  will then print 0..9 values as ascii '0'..'9'
;
movlw   ' '             ; suppress leading zeros          |
;
;  print frequency  'nnnnn.nnnnn kHz'
;
swapf   BCDUi,W         ;                                 |
call    PutDigit        ; 1st digit                       |
movf    BCDUi,W         ;                                 |
call    PutDigit        ; 2nd digit                       |
swapf   BCDVi,W         ;                                 |
call    PutDigit        ; 3rd digit                       |
movf    BCDVi,W         ;                                 |
call    PutDigit        ; 4th digit                       |
swapf   BCDHi,W         ;                                 |
call    PutDigit        ; 5th digit                       |
movlw   "."             ;                                 |
call    LCDChar         ; '.'                             |
movf    BCDHi,W         ;                                 |
call    PutDigit        ; 1st decimal place               |
swapf   BCDMe,W         ;                                 |
call    PutDigit        ; 2nd decimal place               |
movf    BCDMe,W         ;                                 |
call    PutDigit        ; 3rd decimal place               |
swapf   BCDLo,W         ;                                 |
call    PutDigit        ; 4th decimal place               |
movf    BCDLo,W         ;                                 |
call    PutDigit        ; 5th decimal place               |
movlw   " "             ;                                 |
call    LCDChar         ;                                 |
movlw   "k"             ;                                 |
call    LCDChar         ;                                 |
movlw   "H"             ;                                 |
call    LCDChar         ;                                 |
movlw   "z"             ;                                 |
call    LCDChar         ;                                 |
movlw   " "             ;                                 |
call    LCDChar         ;                                 |
return                  ;                                 |
PutDigit
andlw   0x0F            ; use lower nibble                |
skpz                    ; a zero? yes, skip, else         |
iorwf   zeromask,W      ; WREG = ' ' or '0'..'9'          |
goto    LCDChar         ;                                 |

Hi Mike
I have tried your code sugestions and it will not build because I have not define zeromask.
I am not sure how to correctly define zeromask.

Last edited:

#### Cyber

##### New Member
Can anyone help me set a maximum frequency please.

The frequency will actually go up to 42949.67295 KHz.

Can anyone see where this can be modified in the code. or if this is possible.
Full code is in the first post.

Last edited:

#### Dan Soze

##### Member
Can anyone see where this can be modified in the code. or if this is possible.
After looking at the code you posted and the code from the original authors' web site my opinion is the implementation too idiosyncratic.

Even for an ancient controller like the PIC16F627A the hardware design is inefficient and causes the code to be clumsy. It seems to me that is would take less time to rewrite the application from a clearly drafted implementation specification rather than fix this ball of spaghetti code.

I would suggest that you should start from an Arduino + AD9850 module project and avoid any entanglements with Microchip PIC controllers. Especially a dinosaur like the PIC16F627A.

#### Mike - K8LH

##### Well-Known Member
Hi Mike
I have tried your code sugestions and it will not build because I have not define zeromask.
I am not sure how to correctly define zeromask.
You insert it into the 'cblock' (near the bottom of the program) where all the other variables are defined...

#### DrG

##### Active Member
Hi DrG.

I have just realised that the above part of the original code does in fact remove the first 2 leading zeros.
I did not notice it before because I did not take the frequency up that high before.
It will actually go up to 42949.67295 KHz.

I Still want to remove the other leading zeros.
I have tried a few modifications in this part of the code without success,
Glad that at least it was a start. I'm not sure, but I don't see any simple solutions for the modifications you want to do - at least not without spending a lot of time to understand the code completely. You may want to write the author and see if he has any suggestions.

#### Cyber

##### New Member
Hi All
Before I asked the questions on this forum, I tried to contact the author of the code but did not receive a reply.

I have one last mod I would like to try to do.
The code saves the frequency to eeprom memory when the "MemButton" is pressed for more than 1 second.
I would like the code to look at the rotary encode for any movement, then save the new frequency after a 5 seconds.

1. Check for any movement of the rotary encoder.
2. If it does move start a timer for 5 seconds.
3. Reset the timer to zero every time the rotary encoder moves again.
4. If the timer reaches the 5 seconds.
5. Save new frequency.

Rotary encoder = RotI PORTB, 0 = RotQ PORTB, 1

I have tried to modify the following part of the code without success, is this the correct area of the code.
Code:
org 4    ;Interrupt routine, every time RotI goes low to high
movwf   Wreg            ;Save W
swapf   STATUS , W      ; nb.  movwf does not affect any STATUS bits
movwf   StsReg          ;Stave STATUS, without affecting it

btfss   INTCON, INTF
goto    OtherInt

clrf    TMR0            ;Reset every pulse.
bcf     INTCON, T0IF    ; gives 4.1ms delay before T0IF is set

bcf     Updated         ;Force an update on next timeout

bcf     INTCON , INTE   ;Disable interrupt until routine is completed
bcf     INTCON , INTF   ;Clear interrupt flag
btfss   RotQ            ;Reverse these if tuning direction is wrong
call   FreqUp
btfsc   RotQ
call   FreqDn

bsf    INTCON , INTE   ;Re enable the interrupt
goto    CarryOnInt
;................
;.......................
MainLoop
btfss MemButton
goto DoMemory

btfsc Button
goto NoButton

call Delay50
btfsc Button
goto NoButton

clrf ButtCount ;Button pressed for 1s stores freq
SavLoop
call Delay50
incf ButtCount
movlw d'
20'
subwf ButtCount, W
btfsc STATUS, C
goto SaveFreqs
btfss Button
goto SavLoop

decf ButtonPress
movlw 7
btfsc ButtonPress, 7 ;Test for underflow
movwf ButtonPress ;Cycles round 7 - 0

;...........

Last edited:

#### Mike - K8LH

##### Well-Known Member
Can anyone help me set a maximum frequency please.

The frequency will actually go up to 42949.67295 KHz.

Can anyone see where this can be modified in the code. or if this is possible.
Full code is in the first post.
You might check for upper limit at the end of the FreqUp routine and simply "goto FreqDn" if you're over the limit, effectively cancelling out the FreqUp operation. Perhaps something like this;

Code:
FreqUp
movf    StepLo, W
btfss   STATUS, C
goto    FrqUp1Done       ;if FreqMe already = 0 and no overflow then
incf    F1           ;  an error occurs here without the jump out
btfsc   STATUS, Z       ; Test for overflow after above increment
incf    F2           ;
btfsc   STATUS, Z
incf    F3           ;
FrqUp1Done
movf    StepMe, W
btfss   STATUS, C
goto    FrqUp2Done
incf    F2
btfsc   STATUS, Z
incf    F3
FrqUp2Done
movf    StepHi, W
btfsc   STATUS, C
incf    F3
;
;  check upper limit (must define or equ an 'uplimit' constant)
;
uplimit equ     1000001         ; 10000.01-Hz upper limit

movlw   uplimit>>24     ; upper limit 'uh'                |00
subwf   F3,W            ;                                 |00
skpz                    ; equal? yes, skip, else          |00
goto    upcheck         ; banch, check for '<' or '>'     |00
movlw   uplimit>>16     ; upper limit 'ul'                |00
subwf   F2,W            ;                                 |00
skpz                    ; equal? yes, skip, else          |00
goto    upcheck         ; branch, check for '<' or '>'    |00
movlw   uplimit>>8      ; upper limit 'hi'                |00
subwf   F1,W            ;                                 |00
skpz                    ; equal? yes, skip, else          |00
goto    upcheck         ; branch, check for '<' or '>'    |00
movlw   uplimit         ; upper limit 'lo'                |00
subwf   F0,W            ;                                 |00
upcheck skpnc                   ; C = 0 ('<')? yes, skip, else    |B0
goto    FreqDn          ; branch (undo FreqUp op')        |B0
return                  ;                                 |B0
You could impose an upper frequency limit for each memory, too, but the code would be more complex.

Don't be afraid to hit the "like" button if you find this information helpful.

Cheerful regards, Mike

Last edited:

#### Cyber

##### New Member
Hi MIKE - K8LH
Thanks for the advice, I will give it a try as soon as I have time to play.

Any Ideas about the other question in post #28
about saving the frequency to eeprom after the rotary encoder has been turned, so I dont have to press a button to save the frequency

#### Mike - K8LH

##### Well-Known Member
Not at this time. Sorry! I'm still studying the program and adding comments to help me understand it a little better.

#### Cyber

##### New Member
Hi. Mike - K8LH

Fantastic work Mike Thank You.
I have just tried your mod for maximum frequency and it does limit the frequency to 10.00000 KHz.

Just the auto save to eeprom to sort out now

Thank You

#### Cyber

##### New Member
Hi.
I would like to add an auto save to eeprom to the following code.
Auto save the frequency 5 seconds after the rotary encoder has been adjusted, So far all my efforts have failed.

In the existing code, the the frequency is saved if you press and hold a button for more than 1 second.

Press "Button" for more than 1 second to save frequency to eeprom. See code below.

Then there is the "SaveFreqs" routine that saves to eeprom. See code below.

There is an interupt that looks at the rotary encoder movement, perhaps this could be used, then add a 5 second delay before saving to eeprom. See code below.

All help would be very much appreciated. The full code and link to the project are in the first post.

This is the interupt routine that looks for movement of the rotary encoder movement :-
Code:
 org 4     ;Interrupt routine, every time RotI goes low to high
movwf   Wreg            ;Save W
swapf   STATUS , W      ; nb.  movwf does not affect any STATUS bits
movwf   StsReg          ;Stave STATUS, without affecting it

btfss   INTCON, INTF
goto    OtherInt

clrf    TMR0            ;Reset every pulse.
bcf     INTCON, T0IF    ; gives 4.1ms delay before T0IF is set

bcf     Updated         ;Force an update on next timeout

bcf     INTCON , INTE   ;Disable interrupt until routine is completed
bcf     INTCON , INTF   ;Clear interrupt flag
btfss   RotQ            ;Reverse these if tuning direction is wrong
call    FreqUp
btfsc   RotQ
call    FreqDn

bsf     INTCON , INTE   ;Re enable the interrupt
goto    CarryOnInt
Press "Button" for more than 1 second to save frequency to eeprom.
Code:
MainLoop
btfss    MemButton
goto    DoMemory

btfsc   Button
goto    NoButton

call    Delay50
btfsc   Button
goto    NoButton

clrf    ButtCount          ;Button pressed for 1s stores freq
SavLoop
call    Delay50
incf    ButtCount
movlw   d'20'
subwf   ButtCount, W
btfsc   STATUS, C
goto    SaveFreqs
btfss   Button
goto    SavLoop

decf    ButtonPress
movlw    7
btfsc    ButtonPress, 7    ;Test for underflow
movwf    ButtonPress    ;Cycles round 7 - 0

Code:
;..........
SaveFreqs
movlw    LOW(StFreq)
movwf    Whi
movf    F3, W
call    StoreEE
incf    Whi
movf    F2, W
call    StoreEE
incf    Whi
movf    F1, W
call    StoreEE
incf    Whi
movf    F0, W
call    StoreEE

movlw    LINE1
call    LCDCmd

movlw   " "
call    LCDChar
movlw   " "
call    LCDChar
movlw   "-"
call    LCDChar
movlw   "-"
call    LCDChar
movlw   " "
call    LCDChar
movlw   "S"
call    LCDChar
movlw   "A"
call    LCDChar
movlw   "V"
call    LCDChar
movlw   "E"
call    LCDChar
movlw   "D"
call    LCDChar
movlw   " "
call    LCDChar
movlw   "-"
call    LCDChar
movlw   "-"
call    LCDChar
movlw   " "
call    LCDChar
movlw   " "
call    LCDChar

ButtWait
btfss   Button
goto    ButtWait
call    DispFreq

goto    MainLoop
;-----------------------------

#### Cyber

##### New Member
Hi.

More than a year has past and I am back with the same problem, Please see post #33:-

I would like to add an auto save to eeprom to the following code.
(The full code is attached and a link to complete project is in post#10)
Auto save the frequency, 5 seconds after the rotary encoder has been adjusted, So far all my efforts have failed.

In the existing .Asm code, the the frequency is saved if you press and hold a button for more than 1 second.

Press "Button" for more than 1 second to save frequency to eeprom. See code below.

Then there is the "SaveFreqs" routine that saves to eeprom. See code below.

There is an interrupt that looks at the rotary encoder movement, perhaps this could be used, then add a 5 second delay before saving to eeprom. See code below.

All help would be very much appreciated. The full code and link to the project are in the first post.

#### Attachments

• 28.5 KB Views: 0
Last edited: