This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Write R7 register directly from C

I use KeilC uVision4 for 89C51 MCU.
By "Inline ASM", i can easily direct write value to R7 register, like this :

    #pragma ASM
        MOV R7, #10
    #pragma ENDASM


But now, there are some reason that i have to write to R7 register direct from C (not from inline ASM), eg:

    R7 = 10;


Of course, the C compiler does not understand R7 as MCU Register (not Inline ASM).

-> Is there anyway to solve this problem. Please help me if anyone know, thanks a lot !

Parents
  • Well, I intend to write an Accurate "ASM Delay Routine" by "Inline ASM".

    Let take the simplest delay code:

        #pragma ASM
        MOV R1, #vR1
        // Calculate Time spent From Here
        DJNZ R1, $ //2 Machine cycle (MCs)
        #pragma ENDASM
    


    With 8051MCU, it spent : t1 = vR1 x 2 machine cycles (MCs)

    Now, with 2 registers used:

        #pragma ASM
        MOV R1, #vR1
        MOV R2, #vR2
        // Calculate Time spent From Here
        DJNZ R1, $
        DJNZ R2, $-2
        #pragma ENDASM
    


    time spent : t2 = (t1 + 257vR2 - 256) x 2 MCs

    Finally, with 3 registers used:

        #pragma ASM
        MOV R1, #vR1
        MOV R2, #vR2
        MOV R3, #vR3
        DJNZ R1, $
        DJNZ R2, $-2
        DJNZ R3, $-4
        #pragma ENDASM
    


    time spent : t3 = (t2 + 65793vR3 - 65792) x 2 MCs

    Generraly, with n Register used, we can delay :

    tn = (tn-1 + (Cn-1 + 1)vRn - Cn-1) x 2 MCs
    where :

    Cn = 256^n + 256^(n-1) + ... + 256 + 0

    Now i write a delay 3000MCs routine :

    //8051 MCU
    #define Interval 3000 // Change here to change delay in MCs)
    
    #define C0 0                 // Constant in formula above
    #define C1 256               // Constant
    #define C2 65792             // Constant
    
    #define t3 Interval/2        // DJNZ take 2 MCs, so divide by 2 for easier calculation
    #define vR3 ((t3+C2-2)/(C2+1))   // Calculate R3 value
    
    #define t2  (t3+C2-(C2+1)*vR3)
    #define vR2 ((t2+C1-1)/(C1+1))   // Calculate R2 value
    
    #define t1  (t2+C1-(C2+1)*vR2)
    #define vR1 ((t1+C0-0)/(C0+1))   // Calculate R1 value
    
    void Delay() {
        #pragma ASM
        MOV R1, #vR1
        MOV R2, #vR2
        MOV R3, #vR3
        DJNZ R1, $
        DJNZ R2, $-2
        DJNZ R3, $-4
        #pragma ENDASM
    }
    


    Use in main routine :

    void main() {
        Delay(); // Delay 3000 Machine Cycles
    }
    

    => For easier use, i should write a DelayMCs() Macro, eg :

        #define DelayMCs(Interval) //Code Here???
    


    Then, use this Macro like this :

    void main() {
        DelayMCs(7000);
    }
    


    => That's my idea. But i don't know how to write this Macro. Can anyone help me build "Code Here" above. Thanks !

Reply
  • Well, I intend to write an Accurate "ASM Delay Routine" by "Inline ASM".

    Let take the simplest delay code:

        #pragma ASM
        MOV R1, #vR1
        // Calculate Time spent From Here
        DJNZ R1, $ //2 Machine cycle (MCs)
        #pragma ENDASM
    


    With 8051MCU, it spent : t1 = vR1 x 2 machine cycles (MCs)

    Now, with 2 registers used:

        #pragma ASM
        MOV R1, #vR1
        MOV R2, #vR2
        // Calculate Time spent From Here
        DJNZ R1, $
        DJNZ R2, $-2
        #pragma ENDASM
    


    time spent : t2 = (t1 + 257vR2 - 256) x 2 MCs

    Finally, with 3 registers used:

        #pragma ASM
        MOV R1, #vR1
        MOV R2, #vR2
        MOV R3, #vR3
        DJNZ R1, $
        DJNZ R2, $-2
        DJNZ R3, $-4
        #pragma ENDASM
    


    time spent : t3 = (t2 + 65793vR3 - 65792) x 2 MCs

    Generraly, with n Register used, we can delay :

    tn = (tn-1 + (Cn-1 + 1)vRn - Cn-1) x 2 MCs
    where :

    Cn = 256^n + 256^(n-1) + ... + 256 + 0

    Now i write a delay 3000MCs routine :

    //8051 MCU
    #define Interval 3000 // Change here to change delay in MCs)
    
    #define C0 0                 // Constant in formula above
    #define C1 256               // Constant
    #define C2 65792             // Constant
    
    #define t3 Interval/2        // DJNZ take 2 MCs, so divide by 2 for easier calculation
    #define vR3 ((t3+C2-2)/(C2+1))   // Calculate R3 value
    
    #define t2  (t3+C2-(C2+1)*vR3)
    #define vR2 ((t2+C1-1)/(C1+1))   // Calculate R2 value
    
    #define t1  (t2+C1-(C2+1)*vR2)
    #define vR1 ((t1+C0-0)/(C0+1))   // Calculate R1 value
    
    void Delay() {
        #pragma ASM
        MOV R1, #vR1
        MOV R2, #vR2
        MOV R3, #vR3
        DJNZ R1, $
        DJNZ R2, $-2
        DJNZ R3, $-4
        #pragma ENDASM
    }
    


    Use in main routine :

    void main() {
        Delay(); // Delay 3000 Machine Cycles
    }
    

    => For easier use, i should write a DelayMCs() Macro, eg :

        #define DelayMCs(Interval) //Code Here???
    


    Then, use this Macro like this :

    void main() {
        DelayMCs(7000);
    }
    


    => That's my idea. But i don't know how to write this Macro. Can anyone help me build "Code Here" above. Thanks !

Children