hi,
i have a question regarding passing a port/pin to a function.
i have written a piece of code as below
#define LED_PIN P1_0 // bit LED_PIN = P1_0 also does not work
void blink(bit pin, int delayTime, int blinkCount) { while( --blinkCount ) { pin = !pin ; delay(delayTime) ; // function to generate delay...this works fine } }
void main() { blink( LED_PIN, 1000, 10 ) ; }
this also does not work if i code the blink function as a macro.
is there any way i can pass the address/pin name to the function? i am using keil compiler for 89C51 MCU.
But let's say you extend your code into:
void set(bit Pin) { Pin = 1; } void main() { set(P1_0); set(P1_7); set(P3_4); }
What code would the compiler then have generated inside te set() function?
Note that set() is a function - but it isn't an inline function. So the compiler will call a same single function implementation to perform the task. So the compiler would then have to speculatively generate code where you don't send a bit but the integer representing the address of a bit. And it would then have to use conditional code that translate this address into fixed byte-sized operations on all bit-addressable bytes to fake an indirect access. This would require large and slow code. But that would then still have required that set() had taken a pointer to a bit as parameter - because call-by-value doesn't allow you to modify the original parameter. Without call-by-value, set(P1_1) does not mean "set the pin P1:1" but only means "send the current value of P1:1 into the function set()". Only the caller would known that the address of a specific port bit was actually involved.
If you had instead created a #define macro, then the compiler would have been able to directly expand that macro on every use and so directly insert the address of the individual bits.
Note another thing - since the processor can't do indexed accesses to bit variables, the compiler can't implement stack-relative bit parameters or auto bit variables. So the compiler will have to fake things with global bit variables - this would work as long as you don't try recursion. And "passing a bit" means copying the source bit value into the hard-coded global bit "parameter" that the function then knows how to address.
So while the native atomic bit operations are magnificent, they do come with the limitation that the developer must understand the processor limitations and develop the software around these limitations. The alternative would have to be to strictly follow the C language standard - and totally miss out on the best feature of the 8051 chips. Keil is "an ARM company", but it took ARM half a lifetime to give us ARM chips with a decent alternative to the single-bit functionality the 8051 chips have had since day one.
very true...i didnt give it much thought earlier...i understand it perfectly now.
thanks for your detailed explanation.
But i had coded the function as a macro and in that case it did not work either...that had me wondering for a while...i will try again later ofcourse and let you know if it works as a macro.
Refer some good book on embedded C and/or C coding for 8051