View previous topic :: View next topic |
Author |
Message |
ROBOTICAR
Joined: 28 Aug 2007 Posts: 45
|
problem with #define !!!!!! |
Posted: Sat Mar 26, 2011 11:52 pm |
|
|
Hi
I read the "Embedded C programming and the microchip PIC" book, - the bits and bitfields part - and I have problem with some part.
It use bitfields for describing I/O port, for example instead of output_high(PIN_D0) it use this code :
Code: |
////////////////////////PIC 18F452/////////////////////////////////
typedef struct P{
unsigned int bit_0 : 1;
unsigned int bit_1 : 1;
unsigned int bit_2 : 1;
unsigned int bit_3 : 1;
unsigned int bit_4 : 1;
unsigned int bit_5 : 1;
unsigned int bit_6 : 1;
unsigned int bit_7 : 1;
}bits;
#define PORTD (*(bits *)0xf83)
void main()
{
set_tris_d(0);
PORTD.bit_0=1;
}
////////////////////////////////////////////////////////////////////
|
This code works very well. But I could not understand what
"#define PORTD (*(bits *)0xf83)" means??? !!!!!! specially *(bits *) !!!
(I know 0xf83 is the address of PORTD register in pic18f452.)
Could someone explain this code for me ? (+please )
THANKS. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 27, 2011 12:40 am |
|
|
It casts a pointer to a structure of type 'bits' for the byte at address
0xF83, and then takes the contents of it. |
|
|
n-squared
Joined: 03 Oct 2006 Posts: 99
|
|
Posted: Sun Mar 27, 2011 1:53 am |
|
|
Hi
I use a different method for addressing bits in SFR's. This method stems from CCS's way of producing register definition files.
You define the register using:
Code: |
#byte PORTD = 0xf83
|
and define the bits as:
Code: |
#bit PORTD0 = PORTD.0
.
.
#bit PORTD7 = PORTD.7
|
You then use the ports bits like this:
Code: |
if (!PORTD3 && PORTD0)
do_something();
|
Please note that in PIC18, PIC24 and PIC3x you have to use LATx registers for output operations, and not PORTx as you did in your example.
See section "9.0 I/O PORTS" in PIC18FXX2 data sheet.
Another safe method is to use the compiler's output_xxx(PIN_Dx); functions.
BR
Noam
_________________ Every solution has a problem. |
|
|
demonspells
Joined: 06 Jan 2011 Posts: 26
|
|
Posted: Sun Mar 27, 2011 10:07 am |
|
|
I think structs are easier to handle
there is an easier way to handle a certain port or register
it goes like this
Code: | struct {
int1 F0;
int1 F1;
int1 F2;
int1 F3;
int1 F4;
int1 F5;
int1 F6;
int1 F7;
} LATB;
#byte LATB = 0xF8A |
then you can set/reset each pin like this
Code: | LATB.F0 = 0; // Reset pin B0
LATB.F6=1; // Set pin B6
|
_________________ Badr Ghatasheh |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sun Mar 27, 2011 10:28 am |
|
|
n-squared wrote: |
Please note that in PIC18, PIC24 and PIC3x you have to use LATx registers for output operations, and not PORTx as you did in your example.
See section "9.0 I/O PORTS" in PIC18FXX2 data sheet.
Another safe method is to use the compiler's output_xxx(PIN_Dx); functions.
|
Well, no -- he CAN use PORTx, but then he can run into read-modify-write issues when reading back the PORT to see what value it is.
LATx is the best way though.
Also, I would avoid stuff like:
Code: |
#define PORTD (*(bits *)0xf83)
|
Instead, use
Code: |
#byte PORTD = getenv("sfr:LATD")
|
Now when you change the device, PORTD follows the address of LATD according to the compiler's database for the device.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|