Keil Logo

C51: General Purpose SFR Interface


Information in this article applies to:

  • C51 All Versions

QUESTION

I would like to create a general purpose interface function that would allow me to access the sfr's. I have created CmdRI() and CmdWI() functions which read and write idata:

01      void CmdRI(uchar addr)
02      {
03          uchar i;
04          uchar *locAddr;
05
06          /* display starting address */
07          Itoh(argstr0_buf, (int)addr, 2);
08          ComPuts ("I:0x");
09          ComPuts (argstr0_buf);
10          ComPuts (" ");
11
12          /* read and display the requested data */
13          locAddr = (uchar data *)addr;
14
15          for (i=0; i<8; i++) {
16              dataBuf = *locAddr++;
17              Itoh(argstr0_buf, (int)dataBuf, 2);
18              ComPuts (argstr0_buf);
19              ComPuts (" ");
20              }
21
22          ComPuts ("\n");
23
24      } /* CmdRI() end brace */

At first I expected that the type cast on line 13 would cause the code to read data from the sfr's if the value of addr was between 0x80 and 0xff. The debugger shows me that the compiler reads the data from idata and not the sfr's.

Can you recommend any way to get to the sfr's in a general fashion? I want to use the same command format as for simple memory read/write commands.

ANSWER

Unfortunately, there's no way to do that. The SFRs in the 8051 are directly addressable only. That means that the address must be a part of the program. There is no way to indirectly address the SFRs. So, pointers won't work. Take a look at the Intel documentation on the internal data memory and it should become clear.

One way to "sort of" do this is to define an SFR for each SFR address and use a big switch statement as follows:

sfr SFR_0x80 = 0x80;
sfr SFR_0x81 = 0x81;
sfr SFR_0x82 = 0x82;
.
.
.
void write_sfr (
  unsigned char sfr_address,
  unsigned char value)
{
switch (sfr_address)
  {
  case 0x80: SFR_0x80 = value; break;
  case 0x81: SFR_0x81 = value; break;
  case 0x82: SFR_0x82 = value; break;
  }

This is not a really elegant solution, but it will work. The READ function should be similar.

MORE INFORMATION

  • Refer to SFR Memory in the Cx51 User's Guide.
  • Refer to sfr in the Cx51 User's Guide.

SEE ALSO


Last Reviewed: Thursday, February 25, 2021


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  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.