Passing port/pin to a user defined function in 89c52 code
The 8051 processor has a peculiar memory layout, which can be very handy for manipulating bits. In addition to "normal" bit addressing, supported by many processors (location address + bit number), the 8051 has a "bit mode" addressing: a single byte (0-255) can address 256 different bits (in two different areas) with a single instruction. Many internal peripherals are mapped in that bit addressable area.

The C language, instead, is (were) not very versed in bit manipulation. At the time of the 80C51, processors were also slow and equipped with little code memory.

To take advantage of the bit addressing mode of the 8051, some C compiler (for example Keil, but probably many others) invented a new data type "sbit", which is tied to a specific bit address, and that can be manipulated with single, short address instruction (like SETB and CLRB, if I well remember).

The name "sbit" says it all: a Special Bit - with a fixed address. So, you can not use the type sbit inside a function formal parameter, it makes no sense because a variable of type sbit has a fixed address, and hence can not be "parametric". This is the explanation of the compiler error.

A subroutine, or even a macro like suggested by Swanand, using "normal" syntax and normal "C" concepts, will work - but will be far less efficient than using the native 8051 instruction.

Many years have been passed since I used the 8051, so I may be wrong; but I think that a good compiler can do what you want: a general routine able to manipulate a sbit, passing it the address of the (special) bit. Such routine, able to modify the passed argument, needs a pointer (pass by reference): this is normal in C. So your routine f() was wrong by concept. You can try to write

void f(sbit* recievedBit){
  *recievedBit = !*recievedBit;
}


...if your compiler is smart enough, it will understand correctly the above function and use the intrinsic capabilities of the 8051, because the function is correct for both the C semantics and the 8051 architecture. Note also that such routine, by definition, can only manage variables of type sbit - NOT bits residing is some location different from the two special areas reserved for sbits. Of course, such routine would be invoked with "f(&amp;P1^5)" (again normal C syntax regarding the "&amp;"). Read carefully the C compiler manual, especially the C extensions for 8051, and the section about pointers (even for normal/byte access, the 8051 can use 3 different modes, so 3 different kinds of pointers!).

The 8051 (and its derivatives like your AT89C52) are really funny MCUs...