Microchip XC8 Port Pin Pointer?

Thread Starter

AlbertHall

Joined Jun 4, 2014
12,625
I found this code which makes accessing port pins simple and clear.

Code:
// n = name to be used, x = Port name, y = Pin number
#define PIN(n,x,y)    static volatile bit n @ (unsigned)&x*8+y

PIN(LED1,   PORTC, 6);
LED1 = 1;
I have read many times that you cannot use bit pointers in XC8, but this code seems to do just that. How does this code work?
 

dannyf

Joined Sep 13, 2015
2,197
It is a risky (and poorly written) macro.

An easier approach, you want to go down this path, is to user a point to a strict with bit elements to map that pin.

A better approach, in my view, is to use masks - it is 100 percent supported by any compliant compiler.
 

NorthGuy

Joined Jun 28, 2014
611
I found this code which makes accessing port pins simple and clear.
I didn't try if it works, but it is very simple indeed.

But then you'd want to access TRIS, or read PORT and write to LAT, or enable/disable pull-ups, control IOC etc, or perhaps you want to output MSSP clock through the pin. So, it quickly goes back to complicated :)
 

Thread Starter

AlbertHall

Joined Jun 4, 2014
12,625
It does work and it works for TRIS and LAT too.
I don't understand what it is actually doing and I would like to - can anyone explain what this C code is doing?
 

NorthGuy

Joined Jun 28, 2014
611
It does work and it works for TRIS and LAT too.
Yes, but you need to re-define LED1 as LED1TRIS, LED1LAT or whatever, and you need to keep track of all the definitions so that they point to the same bit. It's not that far from the usual:

C:
#define LED1 LATCbits.LATC6
LED1 = 1;
I don't understand what it is actually doing and I would like to - can anyone explain what this C code is doing?
The standard C doesn't allow absolute addressing, so this is a compiler extension. C doesn't forbid bit addressing, and doesn't require it to work neither. Apparently, XC8 has a compiler-specific mechanism for placing a bit variable at an absolute bit-addressed place in the memory (in this case in the middle of the PORTC register). Once the variable is placed you can use it. I didn't know XC8 had such mechanism.
 

Thread Starter

AlbertHall

Joined Jun 4, 2014
12,625
The XC8 user guide says:
It is not possible to declare a pointer to bit types or assign the address of a bit object
to any pointer. Nor is it possible to statically initialize bit variables so they must be
assigned any non-zero starting value (i.e., 1) in the code itself. Bit objects will be
cleared on startup, unless the bit is qualified persistent.

But it's not a pointer, it is telling the compiler that there is a bit variable there. Is that right?
 

NorthGuy

Joined Jun 28, 2014
611
But it's not a pointer, it is telling the compiler that there is a bit variable there. Is that right?
It certainly is not a pointer. It's just a variable placed at absolute address. According to what they say, it would be impossible to assign its address to any pointer. So, I guess this should fail:

C:
void *pointer;
pointer = &LED1; // this should fail
Another thing to try is:

C:
unsigned int variable;
variable = (unsigned int)&LED1; // Retrieve the bit address
Thechnically, it is not assigning the address to any pointer. I have no idea if this can be done or not.

At any rate, this is all compiler-specific.
 

dannyf

Joined Sep 13, 2015
2,197
It is fairly simple, as it is laid out in the manual.

The compiler supports absolute addressing of bit types, from the lowest bit to the highest bit. So bit 4 of a variable at address 50 can be defined as a bit at 50 x 8 + 4.

The macro does that calculation for you.
 

Picbuster

Joined Dec 2, 2013
1,058
Here is a part of my code
put this in your .h file
// make code readable make use On and Off instead 1 and 0
#define On 1
#define Off 0

// -- give pin a name ----------------------
// syntax #define [name] [Bit in port]
#define Alive_led PORTDbits.RD0 // keep alive led
#define Lcd_Pwr PORTDbits.RD2 //
#define Batt_Pwr PORTDbits.RD3 //
#define Aux42V PORTJbits.RJ7 // in combination with GSM_PWR
// -------------- GSM -----------------------------------------
#define GSM_Pwr PORTJbits.RJ1 //
in main;
make sure that the tris bits are set for output ( zero)

want to blink led ?
put in a timer;
Alive_led =!Alive_led;
and led will blink.

switch power on do
Lcd_Pwr = On; // effect set pin rd2 high
switch off
Lcd_Pwr =Off; // set rd2 low
Picbuster
 
Top