ARM Technical Support Knowledge Articles

GENERAL PURPOSE SFR INTERFACE

Applies to: C51 C Compiler

Answer


Information in this article applies to:


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 ("
");
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. My experience using dScope shows 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

SEE ALSO

Article last edited on: 2006-11-19 18:15:39

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential