C Programming for 8051: SFR directions as arguments

8051c

I'm currently making a very simple Tic-Tac-Toe game with an AT89C51RC2 and I am having issues getting the button input right.

Basically, the input is a 3×3 Button Matrix which I want to utilize by scanning through the rows with a pulse while checking the columns for a connection; pretty basic. However, the way I wanted to do this was by making a unique scroll method that received the row parameter and set it to HIGH accordingly.

I already have

sbit R1 = P1^0; 

all through the needed inputs, but I'm not sure if this is correct.

Then, on my main method, I run something like

while(TRUE)
{
    scroll(R1);
}

which is named scroll, I have this

void scroll (bit P)
{
   P = HIGH; //Sets the row being checked to HIGH (HIGH is already defined as a 1). Same goes with the aformentioned TRUE
   ...
}

So, this is not working. I know I'm not doing this right, but I had to start somewhere. Is what I am attempting to do possible? Sending a single Pin adress as an overload for a method? If so, what datatype should it be? I was juggling between char and bit but I can't settle.

I hope my question is understandable! If not, I will gladly elaborate and maybe post all the code (although it is quite messy). Thanks, everyone, in advance!

Best Answer

Edit: I changed code example to answer your question much better

I never used that chip, but it looks like a 8 bit variant of the 8051, so I would make the following guess: your port are defined as "sfr". Usually your MCU header file contains definitions such as :

sfr P1=0x90;

As per your chip's datasheet on page 5, P1 is at address 0x90. So that means that you could write something like that:

unsigned char scroll(sbit pin);

int main(int argc,char** argv)
{
 sbit pinMap[3]={P0^6,P0^7,P1^0}; // P0.6, P0.7 and P1.0.
 char keyboardRows[3]; // Keyboard layout is: one row per byte.  Column are mapped on 0 to 2.
 int i;

 while(1)
 {
  for(i=0;i<3;++i)
  {
   scroll(pinMap[i]);
  }
 }

 return 0;
}

unsigned char scroll(sbit pin)
{
 unsigned char rowState;
 pin=1; // or HIGH.

 // Save your column state in rowState here.

 pin=0; // or LOW?

 return rowState;
}

Now, an you didn't say what kind of problem you were having. We need more information to help you out.

  1. Is it software or could it be hardware? software

  2. What kind of error are you getting? I'm still not sure other than it doesn't work

  3. It doesn't compile? It is fine.

  4. It doesn't do what you expect? I still don't know what you get vs. what you expect.

  5. Is it a custom matrix? Yes and it works.

  6. Is so, have you used pull up resistors to set a definite state when the buttons are not pressed? It's ok.

  7. Have to put diode to prevent ghost keys to appear (when pressing many keys at once)? It's ok.

Edit: Ok, your compiler don't like sbit as parameter, so one may try this:

unsigned char scroll(unsigned char* port,unsigned char pin);

int main(int argc,char** argv)
{
 unsigned char* portAddr={&P0,&P1,&P2}; // Put whatever here.
 unsigned char pin[3]={0x40,0x80,0x01}; // P0.6, P0.7 and P1.0.
 char keyboardRows[3]; // Keyboard layout is: one row per byte.  Column are mapped on 0 to 2.
 int i;

 while(1)
 {
  for(i=0;i<3;++i)
  {
   scroll(portAddr[i],pinMap[i]);
  }
 }

 return 0;
}

unsigned char scroll(unsigned char* port,unsigned char pin)
{
 unsigned char rowState;
 *port|=pin; // Let the bus weak pull-up pull the bus up.

 // Save your column state in rowState here.

 *port&=~pin; // Drive low the output.

 return rowState;
}

If you really insist on using sbit and such things, you could make the declaration global such as this:

sbit RowPins[3]={P0^6,P0^7,P1^0};

unsigned char scroll(int rowIndex);

int main(int argc,char** argv)
{
 char keyboardRows[3]; // Keyboard layout is: one row per byte.  Column are mapped on 0 to 2.
 int i;

 while(1)
 {
  for(i=0;i<3;++i)
  {
   scroll(i);
  }
 }

 return 0;
}

unsigned char scroll(int rowIndex)
{
 RowPins[i]=HIGH;

 // Read stuff here and put in "column".

 RowPins[i]=LOW;

 return column;
}