Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

assembly code with 16 memory locations, only need 2 locations

Status
Not open for further replies.
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
   addlw   0x30
   call   LCDChar

   movf   BCDUi, W       ;Want this to print a zero if it gets here
   andlw   0x0F
   addlw   0x30
   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
 
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
addlw 0x30
call LCDChar

movf BCDUi, W ;Want this to print a zero if it gets here
andlw 0x0F
addlw 0x30
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,
 
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          |
        movwf   zeromask        ;  "                              |
;
;  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                       |
        bsf     zeromask,4      ; leading zero suppression off    |
        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         |
        bsf     zeromask,4      ; change mask to '0' (0x30)       |
        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:
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:
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.
 
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...
 
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.
 
Hi All
Thank you for all your helpful advice.
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:
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
    addwf   F0
    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
    addwf   F1
    btfss   STATUS, C
    goto    FrqUp2Done
    incf    F2
    btfsc   STATUS, Z
    incf    F3
FrqUp2Done
    movf    StepHi, W
    addwf   F2
    btfsc   STATUS, C
    incf    F3
;
;  check upper limit (must define or equ an 'uplimit' constant)
;
        radix   dec
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:
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
 
Not at this time. Sorry! I'm still studying the program and adding comments to help me understand it a little better.
 
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
 
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)
    addwf    CurrentMem, W
    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
;-----------------------------
 
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

  • 9850_rot.asm
    28.5 KB · Views: 269
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top