Reputation: 1089
I'm using some macros that initializes & writes & reads port or port pin: (And it works fine)
/* GPIO port operations */
#define GPIO_InitPort(CONTROL, DIRECTION) ((CONTROL) = ((DIRECTION)? (~GPIO_OUT):(GPIO_OUT)))
#define GPIO_WritePort(PORT, DATA) ((PORT) = (DATA))
#define GPIO_ReadPort(PORT) (PORT)
/* GPIO port pin operations */
#define GPIO_InitPortPin(CONTROL, PIN, DIRECTION) ((CONTROL) = (CONTROL & (~(1 << PIN)))|(DIRECTION << PIN))
#define GPIO_WritePortPin(PORT, PIN, DATA) ((PORT) = (PORT & (~(1 << PIN)))|(DATA << PIN))
#define GPIO_ReadPortPin(PORT, PIN) (((PORT) & (1 << PIN)) >> (PIN))
And, i was thinking to make a GPIO module, its functions implemented as follows:
void GPIO_InitPort(uint8 PortControl, uint8 PortDir){
PortControl = ((PortDir) ? (~GPIO_OUT) : (GPIO_OUT));
}
void GPIO_WritePort(uint8 PortData, uint8 PortLevel){
PortData = PortLevel;
}
uint8 GPIO_ReadPort(uint8 PortData){
return PortData;
}
void GPIO_InitPortPin(uint8 PortControl, uint8 Pin, uint8 PinDir){
PortControl &= ( ~(1<<Pin) | (PinDir<<Pin) );
}
uint8 GPIO_ReadPortPin(uint8 PortData, uint8 PinLevel){
return (( PortData & (1<<PinLevel) ) >> PinLevel);
}
void GPIO_WritePortPin(uint8 PortData, uint8 Pin, uint8 PinLevel){
PortData &= ( ~(1<<Pin) | (PinLevel<<Pin) );
}
Unfortunately, that doesn't work, although same logic used.
Upvotes: 0
Views: 101
Reputation: 123448
Remember that macros are just text substitutions - macro arguments are not evaluated, they are simply expanded in place. If you write something like
GPIO_InitPort( foo, bar );
the preprocessor expands that to
((foo) = ((bar) ? (~GPIO_OUT) : (GPIO_OUT)));
Function arguments, OTOH, are evaluated, and the result of that evaluation is passed to the function. Remember that C uses pass-by-value semantics - the formal argument is a different object in memory than the actual argument, so updating one has no effect on the other. If you call the function
GPIO_InitPort( foo, bar );
the formal argument PortControl
is a different object in memory from the actual argument foo
, and similarly PortDir
is a separate object from bar
. Writing to PortControl
has absolutely no effect on foo
.
If you want a function to write to the actual parameter in the caller, then you must pass a pointer to that parameter. So GPIO_InitPort
would need to be written as
void GPIO_InitPort( uint8 *PortControl, uint8 PortDir )
{
*PortControl = PortDir ? ~GPIO_OUT : GPIO_OUT;
}
and called as
GPIO_InitPort( &foo, bar );
Upvotes: 4
Reputation: 70
You need to learn about pointers.
Example:
void changeVar(int *var, int source)
{
*var = source;
}
int main()
{
int foobar;
changeVar(&foobar, 5);
return 0;
}
Upvotes: 0