pic18f14k50.h:

// Register: PORTC #define PORTC PORTC extern volatile unsigned char PORTC __at(0xF82); #ifndef _LIB_BUILD asm("PORTC equ 0F82h"); #endif // bitfield definitions typedef union { struct { unsigned RC0 :1; unsigned RC1 :1; unsigned RC2 :1; unsigned RC3 :1; unsigned RC4 :1; unsigned RC5 :1; unsigned RC6 :1; unsigned RC7 :1; }; struct { unsigned AN4 :1; unsigned AN5 :1; unsigned AN6 :1; unsigned AN7 :1; unsigned :2; unsigned AN8 :1; unsigned AN9 :1; }; struct { unsigned :6; unsigned NOT_SS :1; }; struct { unsigned C12INP :1; unsigned C12IN1M :1; unsigned C12IN2M :1; unsigned C12IN3M :1; unsigned C12OUT :1; unsigned CCP1 :1; unsigned nSS :1; }; struct { unsigned INT0 :1; unsigned INT1 :1; unsigned INT2 :1; unsigned PGM :1; unsigned SRQ :1; unsigned T0CKI :1; unsigned T13CKI :1; unsigned T1OSCO :1; }; struct { unsigned VREFP :1; unsigned VREFM :1; unsigned CVREF :1; unsigned :3; unsigned T1OSCI :1; }; struct { unsigned :2; unsigned P1D :1; unsigned P1C :1; unsigned P1B :1; unsigned P1A :1; unsigned SS :1; unsigned SDO :1; }; struct { unsigned :1; unsigned CCP2 :1; unsigned PA1 :1; }; struct { unsigned :1; unsigned PA2 :1; }; } PORTCbits_t; extern volatile PORTCbits_t PORTCbits __at(0xF82); // bitfield macros // Lots of macros...

main.c:

if (PORTCbits.RC0 == 1) { LATCbits.LATC1 = 0; }

iom328p.h:

#define PINC _SFR_IO8(0x06) #define PINC0 0 #define PINC1 1 #define PINC2 2 #define PINC3 3 #define PINC4 4 #define PINC5 5 #define PINC6 6

main.c:

if (PINC & (1 << PINC0)) { PORTC |= (1 << PORTC1); }

I personally prefer the way PIC implemented ports. It is more human-readable and easier to use.

Why AVR didn't implement registers this way?