Keil Logo

C51: External SFR Access for 8051 Programs


Information in this article applies to:

  • C51 All Versions

QUESTION

I need to write some routines to perform generic operations using the 8051's I/O pins on port 1 and port 3. The routines will be used in a number of different applications but the I/O pins used will be different for each hardware configuration.

How can I write generic routines that use SFRs so that I can change the SFRs used without re-compiling the software?

ANSWER

As you probably know, C pointers cannot be used to access the 8051's SFRs (special function registers). The reason is because the 8051's SFRs are mapped into the upper 128 bytes of the Directly Addressable On-chip Memory. This area cannot be accessed indirectly, so you cannot use pointers to indirectly access the SFRs.

There are several ways you can write generic software to use ANY SFR.


The best way is to create a header file, define the SFRs for your signals, and include the header file in your C files. The header file would appear as follows:

sfr CLK = 0x91;       /* P1.1 is the CLK signal */
sfr DATA_OUT = 0x93;  /* P1.3 is the DATA_OUT signal */

And the program would appear as follows:

#include "header.h"

void main (void)
{
while (1)
  {
  DATA_OUT = 0;
  CLK = 1;
  CLK = 0;        /* clock out a 0 */

  DATA_OUT = 1;
  CLK = 1;
  CLK = 0;        /* clock out a 1 */
  }
}

The above illustration shows how the CLK and DATA_OUT signals may be used in your program. If you want to locate the signals on other port pins, simply change the address specified in the header file.

This method requires that you re-compile your source files whenever you change the port pin for one of the signals, but that usually isn't a problem.


Another way to access SFRs is to use external variables and let the linker fill in the addresses at link time. This method is a little more complex, however, you do not need to re-compile the source files. You do, however, need to re-link the program.

The main program is similar to the above example except for the external bit declarations. These will be declared in an assembly file that is included at link-time.

extern bit CLK;
extern bit DATA_OUT;

void main (void)
{
while (1)
  {
  DATA_OUT = 0;
  CLK = 1;
  CLK = 0;        /* clock out a 0 */

  DATA_OUT = 1;
  CLK = 1;
  CLK = 0;        /* clock out a 1 */
  }
}

This file can be compiled and the object file subsequently with a number of different applications. The CLK and DATA_OUT variables must be defined somewhere, but their physical location is not resolved until link-time.

The easiest way to declare the variables for these signals is to use the following short assembly file.

PUBLIC  CLK
PUBLIC  DATA_OUT

CLK       BIT 91h    ; Port 1.1
DATA_OUT  BIT 93h    ; Port 1.3

         END

As you can see, this file simply declares the variables to be public (using exactly the same names used in the C file) and then declares the variables at bit variables at specific addresses.

Both of the above methods will help you to define SFR addresses outside your source file(s).

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.