1. 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.
    Dismiss Notice

assembly code with 16 memory locations, only need 2 locations

Discussion in 'Microcontrollers' started by Cyber, Jul 1, 2018.

  1. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    Hi
    I am new to PIC Assembly coding, But have been using Arduino for a few years now.
    Any help with the following would be very much appreciated, and help me to understand the code.

    I have download a freely available .asm file for a signal generator and have the project working on a breadboard layout.

    I am now wanting to adapt the code to my requirements.
    I have got stuck on the following:

    The code has 16 memory location for the frequency. Memory locations set from "MemButton" press steps through the 16 stored frequencies.
    I only need 2 frequency memory locations, and the MemButton to toggle between the 2 memory locations.

    This is the part of the code regarding the MemButton:-

    Code (Asm):


            LIST P=16F627A
            INCLUDE "p16F627A.inc"
            errorlevel  2

            __config    0x3F50     ;   ..1101010000  LV Programming off , INTOSC I/O on A6/7, MCLRE tied to Vcc

        #define         DDSreset          PORTA, 0
        #define         FData          PORTA, 1       ;DDS Data on port A
        #define         FQud            PORTA, 2
        #define         WClk            PORTA, 3

            #define         NLED            PORTA, 4
        #define        LCDE        PORTA, 6
        #define        LCDRS        PORTA, 7

        #define        LCDPORT        PORTB        ;B4-7

            #define         RotI            PORTB, 0    ;Drives interrupt
            #define         RotQ            PORTB, 1
            #define         Button          PORTB, 2
        #define        MemButton        PORTB, 3

            #define         Updated        Flags, 0   ;Set after synth update

        PLL     =     0


        LINE1         =    0x80        ;Address of start of each each line of text on
        LINE2         =    0x80 + d'64'    ;  the LCD module, + command for setting it
        LINE3         =    0x80 + d'16'
        LINE4         =    0x80 + d'80'

            LCDHINIBBLE =       1   ;0 for LCD on Port bits 0-3, 1 for bits 4-7

        STEP1    =    1        ;0.01
        STEP2    =    d'10'        ;0.1Hz
        STEP3    =    d'100'        ;1Hz  
        STEP4    =    d'1000'
        STEP5    =    d'10000'
        STEP6    =    d'100000'    ;1kHz    ;>6 bits allowed here
        STEP7    =    d'1000000'    ;10kHz    ; " "  "
        STEP8    =    d'10000000'    ;100kHz    ; " "  "    

        CHARMARK =     "^"  

      org 0x2100

    FREQCONST      de 0x00,0x00,0x57,0xF5,0xFF,0x86        ;Tuning step / Fclock * 2^ 64,   0.01Hz, 125MHz
    ;FREQCONST      de 0x00,0x04,0x4B,0x82,0xFA,0x10        ;Tuning step / Fclock * 2^ 64,   0.01Hz, 10MHz

    StFreq        de    0x00, 0xD1, 0xCE, 0xF0    ;137.5kHz    Turn on value
            de    0x02, 0xFD, 0x13, 0x60    ;501.4kHz
    ;        de    0x0A, 0xFF, 0x3F, 0x20    ;1.845MHz
    ;        de    0x16, 0x81, 0xB8, 0x00    ;3.776
    ;        de    0x1F, 0x83, 0x52, 0x60    ;5.287
    ;        de    0x2A, 0x9E, 0x08, 0xC0    ;7.15
    ;        de    0x3C, 0x0E, 0xC1, 0x80    ;10.076
    ;        de    0x55, 0x2B, 0x48, 0xA0    ;14.289
    ;        de    0x6B, 0xE8, 0x83, 0x00    ;18.104
    ;        de    0x7F, 0x07, 0x88, 0x00    ;21.312
    ;        de    0x94, 0x70, 0x7D, 0x00    ;24.904
    ;        de    0xAC, 0x86, 0x90, 0xA0    ;28.945
    ;        de    0x00, 0x01, 0x86, 0xA0    ;1000Hz
    ;        de    0x00, 0x02, 0x49, 0xF0    ;1500Hz
    ;        de    0x00, 0x00, 0x9C, 0x40    ;400Hz
    ;        de    0x00, 0x00, 0x00, 0x64    ;1Hz

        org     0  
        nop
        clrw
        movwf   INTCON      ;disable interrupts
        goto    StartUp     ;jump to main 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
    ;................
    OtherInt
    CarryOnInt

        swapf   StsReg , W      ;Restore STATUS
        movwf   STATUS
        swapf   Wreg            ;Restore W
        swapf   Wreg , W        ; nb.  movf affects Z bit
        retfie

    ;=============================================================
    StartUp
        clrf    PORTA           ;Special setup to disable comparator on 'F628
        movlw   7
        movwf   CMCON


        bsf     STATUS,RP0  ;ram page 1
        movlw   b'00000000' ;
        movwf   PORTA       ;
        movlw   b'00001111' ;B0/1/2/3  - I/Q/Buttons
        movwf   PORTB       ;

        movlw   b'01000010'     ;Internal input, Prescalar /4,  pull-ups
        movwf   OPTION_REG

        bcf     STATUS,RP0  ;ram page 0

            ;

        clrf    PORTA
        bsf    DDSreset
        clrf    D4
        movlw    PLL
        addwf    D4

        call    SetUpLCD
        bcf    DDSreset

        call    IntroMsg
        call    ShowConst
        movlw    d'40'
        call    LongerDel    ;2s
    ShowInitLoop
        call    Delay50  
        btfss    Button        ;If button held down at start, freezes intro window
        goto    ShowInitLoop

        call    ClrDisp
        clrf    Flags
        movlw    2
        movwf   ButtonPress
        clrf    CurrentMem

        movlw    LINE2 + d'10
        call    LCDCmd
        movlw    CHARMARK  
        call    LCDChar

        call    DispMem
        call    LoadFreq
        call    DispFreq
        call    SendSynth
          call    Delay50
            call    SendSynth         ;Send twice just in case

        bsf    INTCON, INTF
        bsf     INTCON, GIE

        goto    JumpIn        ;Enter main loop so display is set correctly
    ;.......................
    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

    JumpIn      
        movlw    LINE2 + 2    ;Show the digit being changed
        call    LCDCmd
        movlw    " "        ;Clear existing marker
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar

        movf    ButtonPress, W        ;0-6 depending on digit being changed. 0 = LSD
        sublw    d'
    10'            ;move Back from position of LS digit  
        movwf    Temp

        movlw    5            ;Need to bypass the decimal point for ButtonPress = 5/ 6
        subwf    ButtonPress, W        ;W = BP - 5, if +ve/0, C=1, move back one
        btfsc    STATUS, C  
        decf    Temp

        movf    Temp, W
        addlw    LINE2
        call    LCDCmd            ;Position under the digit to be changed
        movlw    CHARMARK
        call    LCDChar  
                   
        movlw   0      
        subwf    ButtonPress, W
        btfss    STATUS, Z
        goto    NotButt0

        movlw    LOW(STEP1)
        movwf    StepLo
        movlw    HIGH(STEP1)
        movwf    StepMe
        clrf    StepHi
        goto    DoneButt
    ;...........
    NotButt0
        movlw   1      
        subwf    ButtonPress, W
        btfss    STATUS, Z
        goto    NotButt1

        movlw    LOW(STEP2)
        movwf    StepLo
        movlw    HIGH(STEP2)
        movwf    StepMe
        clrf    StepHi
        goto    DoneButt
    ;...........
    NotButt1
        movlw   2
        subwf    ButtonPress, W
        btfss    STATUS, Z
        goto    NotButt2

        movlw    LOW(STEP3)
        movwf    StepLo
        movlw    HIGH(STEP3)
        movwf    StepMe
        clrf    StepHi
        goto    DoneButt
    ;...........
    NotButt2
        movlw   3
        subwf    ButtonPress, W
        btfss    STATUS, Z
        goto    NotButt3

        movlw    LOW(STEP4)
        movwf    StepLo
        movlw    HIGH(STEP4)
        movwf    StepMe
        clrf    StepHi
        goto    DoneButt
    ;...........
    NotButt3
        movlw   4
        subwf    ButtonPress, W
        btfss    STATUS, Z
        goto    NotButt4

        movlw    LOW(STEP5)
        movwf    StepLo
        movlw    HIGH(STEP5)
        movwf    StepMe
        clrf    StepHi
        goto    DoneButt
    ;...........
    NotButt4
        movlw   5
        subwf    ButtonPress, W
        btfss    STATUS, Z
        goto    NotButt5

        movlw    LOW(STEP6)
        movwf    StepLo
        movlw    (STEP6 >> d'
    8') & 0xFF
        movwf    StepMe
        movlw    (STEP6 >> d'
    16') & 0xFF
        movwf    StepHi
        goto    DoneButt
    ;.......
    NotButt5
        movlw   6
        subwf    ButtonPress, W
        btfss    STATUS, Z
        goto    NotButt6

        movlw    LOW(STEP7)
        movwf    StepLo
        movlw    (STEP7 >> d'
    8') & 0xFF
        movwf    StepMe
        movlw    (STEP7 >> d'
    16') & 0xFF
        movwf    StepHi
        goto    DoneButt
    ;........
    NotButt6
        movlw    LOW(STEP8)
        movwf    StepLo
        movlw    (STEP8 >> d'
    8') & 0xFF
        movwf    StepMe
        movlw    (STEP8 >> d'
    16') & 0xFF
        movwf    StepHi

    DoneButt
            call    DispFreq
    NoButton
            btfsc   INTCON, T0IF    ;Look for 4ms timeout, ie. no rotary
            goto    DoUpdate        ; encoder  activity for this period

            call    Delay50

            goto    MainLoop
    ;...............
    DoUpdate
            btfss   Updated         ;See if it has already been done
            goto    DoOne
            goto    MainLoop
    ;...............
    DoOne
            bcf     INTCON, INTE    ;Inhibit interrupt while doing update
            bsf     Updated         ;To prevent repeatedly sending the same data

        call    CalcDDS        ;generate D0..3 from Frequency register
        call    DispFreq
        call    DispCode
        call    SendSynth

        bsf     INTCON, INTE
        goto    MainLoop
    ;..........
    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
    ;-----------------------------
    DoMemory
        call    Delay50
        btfsc    MemButton
        goto    NoButton
    MbuttUp
        call    Delay50
        btfss    MemButton
        goto    MbuttUp

        movlw    4        ;Count in multiples of 4,  00 - 0x2C
        addwf    CurrentMem, W
        andlw    b'
    00111100'
        movwf    CurrentMem
       
        call    DispMem
        call    LoadFreq
        call    CalcDDS
        call    DispFreq
        call    DispCode  
        call    SendSynth

        goto    NoButton
    ;==========================   SUBROUTINES   ==============================
    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

        return
    ;-------------------------------
    FreqDn
        movf    StepLo, W
        subwf   F0
        btfsc   STATUS, C       ;If borrowed, C=0
        goto    FrqDwn1Done

        decf    F1           ;decf doesn'
    t set carry flag, so we need to test
        comf    F1, W        ; for FreqHi going from 0 > 0xFF by complementing
        btfss   STATUS, Z       ; then test for zero
        goto    FrqDwn1Done

        decf    F2
        comf    F2, W  
        btfsc   STATUS, Z  
        decf    F3

        comf    F3, W  
        btfsc   STATUS, Z
        goto    GoneNeg

    FrqDwn1Done
        movf    StepMe, W
        subwf   F1
        btfsc   STATUS, C      
        goto    FrqDwn2Done

        decf    F2        
        comf    F2, W
        btfsc   STATUS, Z    
        decf    F3

        comf    F3, W  
        btfsc   STATUS, Z
        goto    GoneNeg

    FrqDwn2Done
        movf    StepHi, W
        subwf   F2
        btfss   STATUS, C      
        decf    F3        

        comf    F3, W  
        btfsc   STATUS, Z
        goto    GoneNeg

        return
    ;...............
    GoneNeg
        clrf    F0
        clrf    F1
        clrf    F2
        clrf    F3
        return

    ;-------------------------------
    CalcDDS                ;Calculates D0..3 for DDS,  = FREQCONST * F0..3 / 2^32
        movf    F0, W
        movwf   A0
        movf    F1, W
        movwf   A1
        movf    F2, W
        movwf   A2
        movf    F3, W
        movwf   A3

        movlw   LOW(FREQCONST + 5)
        call    GetEE
        movwf   B0
        movlw   LOW(FREQCONST + 4)
        call    GetEE
        movwf   B1
        movlw   LOW(FREQCONST + 3)
        call    GetEE
        movwf   B2
        movlw   LOW(FREQCONST + 2)
        call    GetEE
        movwf   B3
        movlw   LOW(FREQCONST + 1)
        call    GetEE
        movwf   B4
        movlw   LOW(FREQCONST)
        call    GetEE
        movwf   B5

        call    Multiply48x32        ;A * B / 2^16  ....  Truncated to 64 bit result
                   
        movf    Acc5, W     ;Divide by another 2^16 to compensate for DDS constant
        movwf   D3          ;  by offsetting accumulator by 16 bits to give the
        movf    Acc4, W    ;  32 bit word for the DDS
        movwf   D2
        movf    Acc3, W
        movwf   D1
        movf    Acc2, W
        movwf   D0


        return
    ;----------------------------------
    DispMem
        movlw    LINE2 + d'12'
        call    LCDCmd
        movlw    "M"
        call    LCDChar
        movlw    "e"
        call    LCDChar
        movlw    "m"
        call    LCDChar
        rrf    CurrentMem, W
        movwf    Temp
        rrf    Temp, W
        andlw    0x0F
       
        addlw    "A"
        call    LCDChar
        return
    ;-------------------------
    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

    NoMSDs
        movlw    LINE1 + 2
        call    LCDCmd          
        swapf    BCDVi, W
        andlw    0x0F
        addlw    0x30
        call    LCDChar

        movf    BCDVi, W
        andlw    0x0F
        addlw    0x30
        call    LCDChar

        swapf    BCDHi, W
        andlw    0x0F
        addlw    0x30
        call    LCDChar

        movlw    "."
        call    LCDChar

        movf    BCDHi, W
        andlw    0x0F
        addlw    0x30
        call    LCDChar

        swapf    BCDMe, W
        andlw    0x0F
        addlw    0x30
        call    LCDChar

        movf    BCDMe, W
        andlw    0x0F
        addlw    0x30
        call    LCDChar

        swapf    BCDLo, W
        andlw    0x0F
        addlw    0x30
        call    LCDChar

        movf    BCDLo, W
        andlw    0x0F
        addlw    0x30
        call    LCDChar

        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    " "
        call    LCDChar
        movlw    LINE1 + d'12'
        call    LCDCmd
        movlw    "k"
        call    LCDChar
        movlw    "H"
        call    LCDChar
        movlw    "z"
        call    LCDChar
        return
    ;-------------------------------
    DispCode
        movlw    LINE4 + d'1'
        call    LCDCmd
        movlw    "0"
        call    LCDChar
        movlw    "x"
        call    LCDChar

        movf    D4, W
        call    ShowHex
        movlw    "."
        call    LCDChar
        movf    D3, W
        call    ShowHex
        movf    D2, W
        call    ShowHex
        movf    D1, W
        call    ShowHex
        movf    D0, W
        call    ShowHex

        movlw    " "
        call    LCDChar
        return
    ;-------------------------------
    BinToBCD            ;Takes in A3/A2/A1/A0, calculates packed BCD equivalent
        clrf    BCDUi    ;Result in BCDUi/3/2/1/0
        clrf    BCDVi    ;Also uses BCDCounter, BCDTemp  Destroys A
        clrf    BCDHi    ;  may be able to reuse Acc registers in some cases
        clrf    BCDMe
        clrf    BCDLo
        movlw   d'32'
        movwf   BCDCounter
    BCDloop
        rlf     A0
        rlf     A1
        rlf     A2
        rlf     A3
        rlf     BCDLo
        rlf     BCDMe
        rlf     BCDHi
        rlf     BCDVi
        rlf     BCDUi
        decfsz  BCDCounter      ;Need a final shift only, so loop count here
        goto    BCDgo
        goto    BCDone
        ;..........
    BCDgo
        movf    BCDUi , W
        addlw   3
        movwf   BCDTemp
        btfsc   BCDTemp , 3
        movwf   BCDUi            ;If BCDUi >= 5, add 3 and store back

        movf    BCDUi , W
        addlw   0x30
        movwf   BCDTemp
        btfsc   BCDTemp , 7
        movwf   BCDUi            ;Adjust BCDUi if > 80

        movf    BCDVi  , W
        addlw   3
        movwf   BCDTemp
        btfsc   BCDTemp , 3
        movwf   BCDVi      

        movf    BCDVi  , W
        addlw   0x30
        movwf   BCDTemp
        btfsc   BCDTemp , 7
        movwf   BCDVi      

        movf    BCDHi  , W   ;Repeating for middle then low digits
        addlw   3
        movwf   BCDTemp
        btfsc   BCDTemp , 3
        movwf   BCDHi      

        movf    BCDHi  , W
        addlw   0x30
        movwf   BCDTemp
        btfsc   BCDTemp , 7
        movwf   BCDHi    

        movf    BCDMe  , W   ;
        addlw   3
        movwf   BCDTemp
        btfsc   BCDTemp , 3
        movwf   BCDMe    

        movf    BCDMe  , W
        addlw   0x30
        movwf   BCDTemp
        btfsc   BCDTemp , 7
        movwf   BCDMe  

        movf    BCDLo  , W   ;
        addlw   3
        movwf   BCDTemp
        btfsc   BCDTemp , 3
        movwf   BCDLo    

        movf    BCDLo  , W
        addlw   0x30
        movwf   BCDTemp
        btfsc   BCDTemp , 7
        movwf   BCDLo  

        goto    BCDloop
        ;...........
    BCDone
        return

    ;---------------------------------------------------

    ShowHex       ;Convert byte to ASCII / Hex and print to LCD
        movwf   Temp2           ;Uses Temp2 , Temp
        swapf   Temp2 , W  
        andlw   0x0F            ;High nibble
        addlw   0x30            ;Convert to ASCII
        movwf   Temp            ;Temp contains correct ASCII for "0" to "9"
        sublw   0x39            ;W = "9" - W,  if > "9" answer -ve so C=0
        movlw   7               ;(Does not affect status bits)
        btfss   STATUS , C
        addwf   Temp            ;Add 7 for "A" - "F"
        movf    Temp , W
        call    LCDChar        ;Make sure Temp2 is preserved

        movf    Temp2 , W       ;Recover original data
        andlw   0x0F            ;Low nibble
        addlw   0x30          
        movwf   Temp
        sublw   0x39          
        movlw   7            
        btfss   STATUS , C
        addwf   Temp          
        movf    Temp , W
        call    LCDChar
       
        movf    Temp2 , W       ;Restore original data to W
                                ; as this is a test mode only
        return
    ;------------------------------
    LCDChar
            bsf     LCDRS
            goto    LcdNibble
    LCDCmd                          ;Command byte to LCD module RS = 0
            bcf     LCDRS
    LcdNibble
            movwf   Temp            ;LCD is on high order nibble of LCDPORT
            movf    Temp, W
            andlw   0xF0            ;mask to low order bits
            movwf   LCDPORT         ;MS Nibble to PORT 4/7
            nop
            bsf     LCDE
            nop
            bcf     LCDE            ;Strobe in high order nibble
            nop
            swapf   Temp , W        ;load low order nibble
            andlw   0xF0            ;mask to low order bits
            movwf   LCDPORT
            nop
            bsf     LCDE
            nop
            bcf     LCDE            ;Strobe in low order nibble
            call    Delay100us

            return
    ;-------------------------------
    SetUpLCD
        call    Delay50
            bcf     LCDE            ;LCDPORT - B0-B3 to be used for nibble data
            bcf     LCDRS

            movlw   0x30        ;LCDPORT is on Hig Nibble
            movwf   LCDPORT         ;R/W - Write  RS = 0  E = Low
            nop
            bsf     LCDE
            nop
            bcf     LCDE            ;strobe in first $30
            call    Delay5
           
            bsf     LCDE
            nop
            bcf     LCDE            ;second $30
            call    Delay5
           
            bsf     LCDE
            nop
            bcf     LCDE            ;third $30
            call    Delay5

            movlw   0x20            ;set nibble node $20
            movwf   LCDPORT
            nop
            bsf     LCDE
            nop
            bcf     LCDE
            nop                     ;LCD Module now working in nibble mode
                                    ;  so we can now use the routines
            movlw   0x28            ;Sets 4bit, 2 lines 5x10 dots
            call    LCDCmd        
            movlw   0x1C            ;Cursor move, shift right
            call    LCDCmd
            movlw   0x0C            ;Display on, Cursor on, Blink
            call    LCDCmd
            movlw   0x04            ;Increment cursor
            call    LCDCmd
            movlw   0x01            ;Clear and Home
            call    LCDCmd
            call    Delay5          ;could eventually use RS232 delay
                             
        call    ClrDisp
        return
    ;-------------------------------
    ClrDisp
        movlw   1
        call    LCDCmd
        call    Delay50
        return
    ;-------------------------------
    Delay100us    
        movlw   d'19'
        movwf   DelCount
    ShortDelLoop
        nop
        nop
        decfsz  DelCount
        goto    ShortDelLoop
        return
    ;-------------------------------
    Delay50            ;General purpose 50ms delay
        movlw   d'250'
        movwf   DelCount2
    Del50Loop
        call    Delay100us
        call    Delay100us
        decfsz  DelCount2
        goto    Del50Loop
        return
    ;----------------------------
    Delay5              ;5ms delay for LCD setup
        movlw   d'50'
        movwf   DelCount2
    Del5Loop
        call    Delay100us
        decfsz  DelCount2
        goto    Del5Loop
        return
    ;-------------------------------
    LongerDel                       ;Delays by W * 50ms
        movwf   Counter
    LongDelLoop
        call    Delay50
        decfsz  Counter
        goto    LongDelLoop
        return
    ;------------------------------
    LoadFreq
        movlw    LOW(StFreq)
        addwf    CurrentMem, W
        call    GetEE
        movwf    F3

        movlw    LOW(StFreq + 1)
        addwf    CurrentMem, W
        call    GetEE
        movwf    F2

        movlw    LOW(StFreq + 2)
        addwf    CurrentMem, W
        call    GetEE
        movwf    F1

        movlw    LOW(StFreq + 3)
        addwf    CurrentMem, W
        call    GetEE
        movwf    F0
        return
    ;-----------------------------=
    GetEE         ;different from ;F84   EE registers all in bank 1 now
        bsf     STATUS,RP0      ;ram page 1
        movwf   EEADR
        bsf     EECON1 , RD
        movf    EEDATA , W
        bcf     STATUS , RP0    ;ram page 0
        return
    ;-------------------------
    StoreEE           ;Enter with W = EE data,  Whi = EE address
        bsf     STATUS, RP0
        movwf   EEDATA
        bcf     STATUS, RP0
        movf    Whi, W
        bsf     STATUS, RP0
        movwf   EEADR  

        bsf     STATUS , RP0    ;All EE registers in Bank 1

        bsf     EECON1 , WREN   ;Enable EEprom writing
        movlw   0x55
        movwf   EECON2
        movlw   0xAA
        movwf   EECON2
        bsf     EECON1 , WR

        bcf     STATUS, RP0     ;PIR1 register is in bank 0
    EEwaitW
       
        btfss   PIR1 , EEIF
        goto    EEwaitW
        bcf     PIR1 , EEIF       ;has to be cleared manually

        bsf     STATUS, RP0
        bcf     EECON1 , WR
        bcf     STATUS , RP0
        return
    ;-------------------------
    ConstructR0
        return
    ;-----------------------------


    ;--------------------
    Multiply48x32       ;32x 48 bit multiplication, followed by /2^16
        clrf    Acc0   ;Input A0/1/2/3 and B0/1/2/3/4/5, output Acc0---7
        clrf    Acc1        ;A destroyed,  B kept
        clrf    Acc2        ;64 bit answer, LSBs thrown away
        clrf    Acc3      
        clrf    Acc4
        clrf    Acc5
        clrf    Acc6
        clrf    Acc7        ;Extend A range by changing counter and adding
                            ;  extra RRF Ax terms
        movlw   d'32'      
        movwf   Counter
    MultLoop          
        bcf     STATUS, C
        rrf     A3
        rrf     A2
        rrf     A1
        rrf     A0          ;Effectivley adds shifted version of B
        btfss   STATUS, C   ; into Acc depending on working bit of A
        goto    NoMult      ; by shifting the accumulator instead of B itself

        movf    B0, W       ;Get B0 value and add
        addwf   Acc2        ; into shifted accumulator if 1 in
        btfss   STATUS, C   ; appropriate bit in Avalue
        goto    MulAdd1
        incf    Acc3
        btfss   STATUS, Z
        goto    MulAdd1    
        incf    Acc4
        btfss   STATUS, Z
        goto    MulAdd1    
        incf    Acc5
        btfss   STATUS, Z
        goto    MulAdd1    
        incf    Acc6
        btfss   STATUS, Z
        goto    MulAdd1
        movlw   1           ;Need more complex addition routine for last Acc as
        addwf   Acc7        ; final Carry has to be preserved for the shift
    MulAdd1
        movf    B1, W
        addwf   Acc3
        btfss   STATUS, C
        goto    MulAdd2
        incf    Acc4
        btfss   STATUS, Z
        goto    MulAdd2
        incf    Acc5
        btfss   STATUS, Z
        goto    MulAdd2
        incf    Acc6
        btfss   STATUS, Z
        goto    MulAdd2
        movlw   1
        addwf   Acc7
    MulAdd2
        movf    B2, W
        addwf   Acc4
        btfss   STATUS, C
        goto    MulAdd3
        incf    Acc5
        btfss   STATUS, Z
        goto    MulAdd3
        incf    Acc6
        btfss   STATUS, Z
        goto    MulAdd3
        movlw   1
        addwf   Acc7
    MulAdd3
        movf    B3, W
        addwf   Acc5
        btfss   STATUS, C
        goto    MulAdd4
        incf    Acc6
        btfss   STATUS, Z
        goto    MulAdd4
        movlw   1
        addwf   Acc7
    MulAdd4
        movf    B4, W
        addwf   Acc6
        btfss   STATUS, C
        goto    MulAdd5
        movlw   1
        addwf   Acc7
    MulAdd5
        movf    B5, W
        addwf   Acc7

    NoMult                  ;Need to rotate in carry from final addition.  C is
        rrf     Acc7        ; already zero if we've jumped in here.
        rrf     Acc6
        rrf     Acc5
        rrf     Acc4
        rrf     Acc3      
        rrf     Acc2
        rrf     Acc1
        rrf     Acc0
        decfsz  Counter
        goto    MultLoop

        return              ;Acc7/6/5/4/3/2/1/0 = A * B    
    ;------------------------------------------------------------------
    Div2N                           ;Divides Acc by 2^N.  N in W
        movwf   Counter         ;Does not work if entered with 0
        movf    Counter
        btfsc   STATUS , Z      ;So trap it out
        return
    DivLoop
        bcf     STATUS , C
        rrf     Acc3
        rrf     Acc2
        rrf     Acc1
        rrf     Acc0
        decfsz  Counter
        goto    DivLoop
        return
    ;------------------------------
    ShowConst
        movlw    LINE3 + 2
        call    LCDCmd

            movlw   "F"
            call    LCDChar
            movlw   "r"
            call    LCDChar
            movlw   "e"
            call    LCDChar
            movlw   "q"
            call    LCDChar
            movlw   " "
            call    LCDChar
            movlw   "C"
            call    LCDChar
            movlw   "o"
            call    LCDChar
            movlw   "n"
            call    LCDChar
            movlw   "s"
            call    LCDChar
            movlw   "t"
            call    LCDChar
        movlw   "."
            call    LCDChar
            movlw   " "
            call    LCDChar
            movlw   "="
            call    LCDChar


        movlw    LINE4 + 1
        call    LCDCmd

        movlw    "0"
        call    LCDChar
        movlw    "x"
        call    LCDChar
            movlw   LOW(FREQCONST + 0)
            call    GetEE
            call    ShowHex
            movlw   LOW(FREQCONST + 1)
            call    GetEE
          call    ShowHex
            movlw   LOW(FREQCONST + 2)
            call    GetEE
          call    ShowHex
            movlw   LOW(FREQCONST + 3)
            call    GetEE
            call    ShowHex
            movlw   LOW(FREQCONST + 4)
            call    GetEE
            call    ShowHex
            movlw   LOW(FREQCONST + 5)
            call    GetEE
        call    ShowHex
       
        return
    ;-------------------------------------
    IntroMsg
        movlw   LINE1 + 5
        call    LCDCmd

        movlw   "G"
        call    LCDChar
        movlw   "4"
        call    LCDChar
        movlw   "J"
        call    LCDChar
        movlw   "N"
        call    LCDChar
        movlw   "T"
        call    LCDChar
        movlw   " "
        call    LCDChar

        movlw   LINE2 + 1
        call    LCDCmd

        movlw   "A"
        call    LCDChar
        movlw   "D"
        call    LCDChar
        movlw   "9"
        call    LCDChar
        movlw   "8"
        call    LCDChar
        movlw   "5"
        call    LCDChar
        movlw   "0"
        call    LCDChar
        movlw   " "
        call    LCDChar
        movlw   "C"
        call    LCDChar
        movlw   "o"
        call    LCDChar
        movlw   "n"
        call    LCDChar
        movlw   "t"
        call    LCDChar
        movlw   "r"
        call    LCDChar
        movlw   "o"
        call    LCDChar
        movlw   "l"
        call    LCDChar

        return
    ;--------------------------------------
    SendSynth               ;Send Tx registers as a serial data to DDS
            movf    D0 , W
            call    Write9850
            movf    D1 , W
            call    Write9850
            movf    D2 , W
            call    Write9850
            movf    D3 , W
            call    Write9850
            movf    D4 , W          ;Phase word
            call    Write9850
            bcf     WClk

        goto    $+1
            bsf     FQud      ;+ve edge of FQud sets 9850 internal reg
            goto    $+1
            bcf     FQud
            bcf     FData
            nop

            return
    ;--------------------------
    Write9850
        movwf    Temp
            movlw   8
            movwf   BitCount
    Loop9850
            bcf     WClk       ;data changes with -ve edge of clock
            rrf     Temp
            btfss   STATUS , C
            bcf     FData
            btfsc   STATUS , C
            bsf     FData
            goto    $+1
            bsf     WClk    
            goto    $+1
            decfsz  BitCount        
            goto    Loop9850

            return
    ;------------------------------
        cblock 0x20  
            Temp, Temp2, BTemp, Whi
            Counter
            DelCount, DelCount2
        BitCount
            ButtCount, ButtonPress
        AutoEEADR
            Flags
            Wreg, StsReg
        CurrentMem
            StepHi, StepMe, StepLo                      ;24 bit Tuning step
            A0, A1, A2, A3,
            B0, B1, B2, B3, B4, B5
        Acc0, Acc1, Acc2, Acc3, Acc4, Acc5, Acc6, Acc7
            SynthReg1, SynthReg2
            F0,F1, F2, F3                              ;Frequency Register
        D0, D1, D2, D3, D4
            BCDLo, BCDMe, BCDHi, BCDVi, BCDUi
            BCDTemp, BCDCounter
        Tx0, Tx1, Tx2, Tx3                    ;Serial shift registers

        endc        
    ;------------------------------------------------
     end

     
     
    Last edited: Jul 2, 2018
  2. DrG

    DrG New Member

    Joined:
    Dec 16, 2017
    Messages:
    13
    Likes:
    3
    There are a couple of issues to consider. I think it is usually (not always) a bad idea to modify code when you don't completely understand how it works. The other thing to consider is that you are not posting the entire program.

    Others here may see this more clearly and I have not spent a lot of time on it, but it looks like the 16 memory locations contain the information for eight frequencies. IF you only wanted to use the first two frequencies, you may be able to modify the code below, replacing '7' with '1', thus allowing only frequencies 0 and 1. But, again, unless you just want to do some playing around, it seems like a much better idea to spend more time learning how the program works.

    Code (ASM):

    decf ButtonPress
    movlw 7
    btfsc ButtonPress, 7 ;Test for underflow
    movwf ButtonPress ;Cycles round 7 - 0
     
     
  3. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,701
    Likes:
    126
    Location:
    Michigan, USA
    Please provide a link to the project?
     
  4. dave miyares

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    2
    Likes:
    -10


     
  5. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    Hi. DrG

    Thank you for the advice, I will try that code mod as soon as I get a chance tomorrow.
     
  6. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    Hi Mike
    I am new to this forum. How do I post a link to the project.
     
  7. DrG

    DrG New Member

    Joined:
    Dec 16, 2017
    Messages:
    13
    Likes:
    3
    You should probably look for a statement that declares the starting/default frequency - maybe it is 7 and not 0, if you know what I mean. I also look forward to seeing the link to the project and complete code and think you may be able to do do what you want to do.
     
  8. dave miyares

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    2
    Likes:
    -10


     
  9. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    I have now edited the first post to include the full code
     
  10. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    I have now edited the first post to include the full code.
    DrG - I have tried your suggestion re: btfsc ButtonPress, 7 ; Result - this affected the ( #define Button PORTB, 2) not the ( #define MemButton PORTB, 3).
    The (Button PORTB, 2) is used to move the curser under one of the 8 digits to select the digit to modify it up or down with the Rotary Encoder
    #define RotI PORTB, 0 ;Drives interrupt
    #define RotQ PORTB, 1
    #define Button PORTB, 2
    #define MemButton PORTB, 3 - This membutton has 16 eeprom locations, "A" to "P" on the LCD display , I need to change it to 2 location "A" & "B"

    I hope the above has made it a little clearer.

    Also I would like to set a maximum frequency.
     
  11. DrG

    DrG New Member

    Joined:
    Dec 16, 2017
    Messages:
    13
    Likes:
    3
    OK, you were going to post a link to the project. This is important to help you and also to credit the author.

    One way to do that is to click the link icon (7th from the left on the options bar) and enter the link in the pop-up. I have done one below as an example (and I am sure there are directions somewhere to do links and lots of other things).


    https://www.electro-tech-online.com...emory-locations-only-need-2-locations.154293/
     
  12. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
  13. DrG

    DrG New Member

    Joined:
    Dec 16, 2017
    Messages:
    13
    Likes:
    3
  14. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    Hi DrG
    Yes I have the AD9850 and the circuit is working good on a breadboard at present.

    Also I would like to set a maximum frequency, and just realised I would then need to remove the leading zeros on the display if possible.
     
  15. DrG

    DrG New Member

    Joined:
    Dec 16, 2017
    Messages:
    13
    Likes:
    3
    Try this.
    Find this section of code:
    Code (ASM):

       movlw   4       ;Count in multiples of 4,  00 - 0x2C
       addwf   CurrentMem, W
       andlw   b'00111100'
       movwf   CurrentMem
     
    change
    andlw b'00111100'
    to
    andlw b'00000100'

    I am flying blind here, not having the device. It seems like a pretty cool project and a nice job of coding as far as I can tell.

    IF I am reading correctly (and I very possibly am not), this should only allow the first two defined memory locations corresponding to the frequencies. The value of W will be either 0 or 4 and so the other 14 frequencies will not be seen. That is, when you turn the rotary encoder, you are adding steps of four, corresponding to the 16 frequency locations (the de table).

    I would not comment out the other 14 values as you have shown, just leave everything as is and see if the change works.

    As far as setting a maximum frequency, I am not sure what you mean, but start small - see if you can modify the code to only use the first two frequencies first.

    Also, why do you want to do this? :)

    Hope this helps.
     
  16. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    Hi DrG.

    Fantastic, changing andlw b'00111100' to andlw b'00000100' work perfect, I now have just the first 2 memory locations.
    I see that now, changing from binary 60 to binary 4:)
    Thank You very much for your help DrG.

    Next step would to hide the leading zeros on the LCD display. so that if it was set to 99Hz the leading zeros would not show, i.e. 99.00 not 000.09900

    I am looking to control a small AC motor
     
  17. DrG

    DrG New Member

    Joined:
    Dec 16, 2017
    Messages:
    13
    Likes:
    3
    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 (ASM):

       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 )
     
  18. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,701
    Likes:
    126
    Location:
    Michigan, USA
    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 (asm):
    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ;   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         ;                                 |
     
    Last edited: Jul 5, 2018
  19. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,701
    Likes:
    126
    Location:
    Michigan, USA
    Anyone know what the "synth module" is in the original author's schematic and code? Is that a part of this AD9850 DDS project?
     
  20. DrG

    DrG New Member

    Joined:
    Dec 16, 2017
    Messages:
    13
    Likes:
    3
    I think it refers to a LMX2541 or LMX2470 Synthesizer Module. Not used in the present project (see note - " This module is also used for control of Fractional-N synthesizers with appropriate PIC firmware. Ignore the part on the diagram referring to LMX2xxx connections. - http://www.g4jnt.com/AD9850-Controller.pdf"), but a different one see: http://www.g4jnt.com/fractn_rot_controller.pdf
     
  21. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    Hi Mike- K8LH
    Thank You for your reply.

    DrG is correct the syth module is not used in this setup, it is part of another project
     
  22. Cyber

    Cyber New Member

    Joined:
    Jul 1, 2018
    Messages:
    16
    Likes:
    0
    Hi. Drg and Mike - K8LH

    Thank you both for your suggestions, I will have to wait until the weekend to try them out , but can't wait.
    I will let you know how I get on.

    Thanks again, with your help and explanation of the code I seem to be able to understand it better than I ever would do reading lots of books and datasheets.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice