Keil Logo

SFR access without keyword "sfr"

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Arnaud DELEULE
Posted
5-Dec-2000 13:45 GMT
Toolset
C51
New! 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
Read-Only
Author
James Wilkinson
Posted
5-Dec-2000 15:31 GMT
Toolset
C51
New! RE: SFR access without keyword
you can use the sfr keyword in "C" and it seems the easiest method to use?
There is the _at_ keyword for absolute memory locations which should do the same (p71 C51 manual). if its only a bit, then sbit can be pointed to a sfr location. ( sbit VAR = 0xA8 )
Read-Only
Author
Mark Odell
Posted
5-Dec-2000 22:16 GMT
Toolset
C51
New! RE: SFR access without keyword
*((unsigned char data *) 0xA8) = 0x1;

Unfortunately the generated code is :

MOV  	R0,#0A8H
MOV  	@R0,#01H

Which is exactly what should happen. The SFR's are not memory, the are registers. You cannot take the address of a register, thus you cannot point to it. You must use sbit, sfr, or sfr16 to access the 8051 registers. I.e.

sfr someBit = 0xA8;
someBit = 0x12;

This is a major pain when you have two UART's and would like to pass in a UART context to multiply instantiated UART driver code.

- Mark
Read-Only
Author
Arnaud DELEULE
Posted
6-Dec-2000 08:25 GMT
Toolset
C51
New! RE: SFR access without keyword

*((unsigned char data *) 0xA8) = 0x1;
Unfortunately the generated code is :
MOV     R0,#0A8H
MOV     @R0,#01H

Which is exactly what should happen. The SFR's are not memory, the are registers.


??????
Cf Keil C51 Compiler book p68 : "The 8051 family of microprocessors provides you with a distinct memory area for accessing SFRs.
[...] SFRs reside from address 0x80 to 0xFF and can be accessed as bits, bytes and words.

Moreover in Keil A51/A251 Assembler book p10, SFR Space Data appears as an area within DATA space.

This is logic since SFR is only direct addressable as DATA area is.


You cannot take the address of a register, thus you cannot point to it. You must use sbit, sfr,
or sfr16 to access the 8051 registers.


So if I want to init a SFR register (which is unknown at compile time),
how can I do ?

In fact, my application can use up to 14 interrupts.
So it must initialize IE (or IE1) depending of the interrupt to enable.
The best solution (from my point of view ! ;-) ) is :
a funtion which receive the address of the SFR and the bit to "enable".
That's why I tried to cast the SFR address into a pointer in order to address directly the byte.

I also tried to use a local variable of type "sfr" but this can't be done.
It seems that "sfr" type variables can only be global ones .... ?

Have you a better solution ?

Arnaud DELEULE
Read-Only
Author
Andrew Neil
Posted
6-Dec-2000 10:36 GMT
Toolset
C51
New! RE: SFR access without keyword
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

Read-Only
Author
Arnaud DELEULE
Posted
6-Dec-2000 12:44 GMT
Toolset
C51
New! RE: SFR access without keyword
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
Read-Only
Author
Mark Odell
Posted
6-Dec-2000 13:57 GMT
Toolset
C51
New! RE: SFR access without keyword
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
Read-Only
Author
Mark Odell
Posted
6-Dec-2000 13:53 GMT
Toolset
C51
New! RE: SFR access without keyword
Cf Keil C51 Compiler book p68 : "The 8051 family of microprocessors provides you with a distinct memory area for accessing SFRs.
[...] SFRs reside from address 0x80 to 0xFF and can be accessed as bits, bytes and words.


Yes, and you use sbit, sfr, sfr16 to access them. Assembler allows you to do anything so I'll ignore that here.

So if I want to init a SFR register (which is unknown at compile time),
how can I do ?


You mean on a new 8051 that Keil doesn't explicitly support? Look in the databook for the part, find the DATA address of the sfr, and sfr the thing.

sfr myNewSfr = 0xE8;
if (myNewSfr & SOME_BIT) ...

In fact, my application can use up to 14 interrupts.
So it must initialize IE (or IE1) depending of the interrupt to enable.
The best solution (from my point of view ! ;-) ) is :
a funtion which receive the address of the SFR and the bit to "enable".
That's why I tried to cast the SFR address into a pointer in order to address directly the byte.


Write two functions, maskInterrupt() and allowInterrupt() that take an enum of all 14 possible interrupts. Have these functions set/clear the appropriate bits in IE0 and IE1. Also, write enableInterrupts() and disableInterrupts() which set/clear the .EA flag. SFR's are registers, registers are hardware, hardware is global, you can not make an SFR local. C scoping rules don't apply to them.

- Mark
Read-Only
Author
Andrew Neil
Posted
6-Dec-2000 16:55 GMT
Toolset
C51
New! RE: SFR access without keyword
Yes, and you use sbit, sfr, sfr16 to access them. Assembler allows you to do anything so I'll ignore that here.

When you do it in Assembler, you choose the appropriate Addressing Mode and/or mnemonic yourself; it's the sbit, sfr, sfr16 which tell the compiler that you're accessing an SFR and therefore what Addressing Mode and/or mnemonic to use.
Read-Only
Author
Mark Odell
Posted
6-Dec-2000 19:54 GMT
Toolset
C51
New! RE: SFR access without keyword
How did what I said contradict what you said? I said, "Assembler allows you to do anything so I'll ignore that here." The OP is asking about how to do this in C but quoted irrelvant text about assembler.

- Mark
Read-Only
Author
Andrew Neil
Posted
7-Dec-2000 10:57 GMT
Toolset
C51
New! RE: SFR access without keyword
How did what I said contradict what you said?

No contradiction!
Just adding some detail (which, as you say, was not essential to main 'C' discussion).

"Reply" doesn't necessarily imply "Disagree" - sorry if it sounded that way.
Read-Only
Author
Mark Odell
Posted
7-Dec-2000 13:48 GMT
Toolset
C51
New! RE: SFR access without keyword
"Reply" doesn't necessarily imply "Disagree" - sorry if it sounded that way.

My fault. I was being overly sensitive. Please ignore me.

Regards.

- Mark

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.