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

SFR access without keyword "sfr"

Hi,

I'm trying to access SFR memory using the hexa address of the SFR
and using only "C" instructions.
Since SFR memory is accessed by direct addressing mode, like the first
128 bytes of internal RAM, I tried to use the following instruction :

* ((unsigned char data *) 0xA8) = 0x1;
Unfortunately the generated code is :
MOV  	R0,#0A8H
MOV  	@R0,#01H
which is indirect addressing and points to the upper 128 bytes of
internal memory (in a 8052) or nowhere (with 8051).

If I try to address specificly the upper 128 bytes of internal RAM using
* ((unsigned char idata *) 0xA8) = 0x1;
then the generated code is :
MOV  	R0,#0A8H
MOV  	@R0,#01H
which seems to be correct.

I think I miss something but I don't see what.
Anybody can help ?

Thanks in advance.

Arnaud

Parents
  • It seems that "sfr" type variables can only be global ones .... ?

    The processor has only 1 set of registers; you can't just create a whole new set of "local" registers within a function!

    The Keil C51 manual is a bit misleading in its example:

    SFRs are declared in the same fashion as other C variables. The only difference
    is that the data type specified is sfr rather than char or int. For example:

    sfr P0 = 0x80; /* Port-0, address 80h */

    If that were
    int P0 = 0x80; 
    it would define a 16-bit variable at an unknown address with an initial value of 0x80; however
    sfr P0 = 0x80; /* Port-0, address 80h */

    defines a variable which can be used to access the processor register at address 0x80

Reply
  • It seems that "sfr" type variables can only be global ones .... ?

    The processor has only 1 set of registers; you can't just create a whole new set of "local" registers within a function!

    The Keil C51 manual is a bit misleading in its example:

    SFRs are declared in the same fashion as other C variables. The only difference
    is that the data type specified is sfr rather than char or int. For example:

    sfr P0 = 0x80; /* Port-0, address 80h */

    If that were
    int P0 = 0x80; 
    it would define a 16-bit variable at an unknown address with an initial value of 0x80; however
    sfr P0 = 0x80; /* Port-0, address 80h */

    defines a variable which can be used to access the processor register at address 0x80

Children
  • The processor has only 1 set of registers; you can't just create a whole new set of "local" registers within a function!

    Sure but I want to name an SFR with a specific name within the local scope of a function. As you do with other parameters.
    And it appears that sfr can't be a parameter of a function.

    As I mentionned before, the SFR register to modify is unknown at compile time.
    I receive the address of the SFR in an unsigned char variable and don't know how to modify the corresponding SFR register value !!!
    So how can I do ?

    It seems that I have to modify the architecture of my software ....

    Arnaud

  • Sure but I want to name an SFR with a specific name within the local scope of a function. As you do with other parameters.
    And it appears that sfr can't be a parameter of a function.


    No! SFR's cannot be parameters. Parameters are pushed onto the stack or placed in fixed locations in regular memory - you cannot do this with registers. Please stop attempting to do this - these are not memory mapped registers like external device registers.

    As I mentionned before, the SFR register to modify is unknown at compile time.

    C51 doesn't know about any SFR's at compile time. By including reg51.h you define them. Give me the address and description of you mystery SFR and I'll show you how to access it. For that matter, what chip are you using?

    - Mark