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 Registers

I'm using an TI 8051 device with Keil and had a piece of code that is not behaving as I had originally expected. I created a simple piece of testcode to demonstrate this:

char passtest = 0;
char tempvar = 0;

P0 = 0xAA;
tempvar = P0;
if(tempvar = 0xAA)
{
     passtest = 1;
}
else
{
     passtest = 0;
}

I would expect that this testcode would end with a passtest value of 1 but this is not the case as, although P0 is set to 0xAA as expected, tempvar has a value of 0xFF. I assume this is because P0 is not a standard variable but is an sfr. I started reading through the 8051 bible and when reading the hardware section, found this:

Special Function Registers
...Read accesses to these addresses will in general return random data, and write accesses will have no effect...
(pg 55 www.lpcware.com/.../80C51 Family Hardware Description.pdf)

I searched my code and found the following line in TPIC8300.H file:

sfr P0   = 0x80;

The above statement is providing an address for the P0 register (far as I know) so I assumed the sfr keyword is what makes it either read only or provide unreliable data upon reading (as described in the hardware bible). To test this, I changed the above line to:

char P0   = 0x80;

I found that it is still providing write only access and can't be read back.

My question for this is why? Is P0 a protected variable name used in Keil (in that it can't be configured to be anything but an SFR) or am I trying to change it in the wrong area?

NOTE: I have no intentions of actually changing this in the code, I just want to understand the compiler better (specifically in terms of how Keil handles SFRs and why it would behave differently than I would expect).

  • Sorry, correction to the code (typed it in wrong), it should be a '==' in the if statement:

    char passtest = 0;
    char tempvar = 0;
    
    P0 = 0xAA;
    tempvar = P0;
    if(tempvar == 0xAA)
    {
         passtest = 1;
    }
    else
    {
         passtest = 0;
    }
    

    On a sidenote, I'm aware that, in this circumstance, I can eliminate the tempvar variable altogether (since it's still reading the value of P0 in the if statement so it still fails, even when the code is changed to:

    char passtest = 0;
    
    P0 = 0xAA;
    if(P0 == 0xAA)
    {
         passtest = 1;
    }
    else
    {
         passtest = 0;
    }
    

  • Time for someone to read up on the functionality of port pins.