Chapter 8


C bit fields

Here is a section of /opt/microchip/xc32/v1.33/pic32mx/include/proc/p32mx250f128b.h to access PORTB.

extern volatile unsigned int        PORTB __attribute__((section("sfrs")));
typedef union {
  struct {
    unsigned RB0:1;
    unsigned RB1:1;
    unsigned RB2:1;
    unsigned RB3:1;
    unsigned RB4:1;
    unsigned RB5:1;
    unsigned :1;
    unsigned RB7:1;
    unsigned RB8:1;
    unsigned RB9:1;
    unsigned RB10:1;
    unsigned RB11:1;
    unsigned :1;
    unsigned RB13:1;
    unsigned RB14:1;
    unsigned RB15:1;
  struct {
    unsigned w:32;
} __PORTBbits_t;
extern volatile __PORTBbits_t PORTBbits __asm__ ("PORTB") __attribute__((section("sfrs")));
extern volatile unsigned int        PORTBCLR __attribute__((section("sfrs")));
extern volatile unsigned int        PORTBSET __attribute__((section("sfrs")));
extern volatile unsigned int        PORTBINV __attribute__((section("sfrs")));

And here are some from /opt/microchip/xc32/v1.33/pic32mx/include/proc/ppic32mx.h .

/* PORTB */
#define _RB0 PORTBbits.RB0
#define _RB1 PORTBbits.RB1
#define _RB2 PORTBbits.RB2
#define _RB3 PORTBbits.RB3
#define _RB4 PORTBbits.RB4
#define _RB5 PORTBbits.RB5
#define _RB6 PORTBbits.RB6
#define _RB7 PORTBbits.RB7
#define _RB8 PORTBbits.RB8
#define _RB9 PORTBbits.RB9
#define _RB10 PORTBbits.RB10
#define _RB11 PORTBbits.RB11
#define _RB12 PORTBbits.RB12
#define _RB13 PORTBbits.RB13
#define _RB14 PORTBbits.RB14
#define _RB15 PORTBbits.RB15

There are also macros that are similar to functions. Here are a few from /opt/microchip/xc32/v1.33/pic32mx/include/peripheral/ports.h .

#define mPORTBRead()                        (PORTB)
#define mPORTBReadBits(_bits)               (PORTB & (unsigned int)(_bits))
#define mPORTBReadLatch()                   (LATB)
#define mPORTBReadLatchBits(_bits)          (LATB & (unsigned int)(_bits))

#define mPORTBWrite(_lat)                   (LATB = (unsigned int)(_lat))
#define mPORTBSetBits(_bits)                (LATBSET = (unsigned int)(_bits))
#define mPORTBClearBits(_bits)              (LATBCLR = (unsigned int)(_bits))
#define mPORTBToggleBits(_bits)             (LATBINV = (unsigned int)(_bits))

Here are ways to test if RB5 is high. Some of these will return values that are neither 0 nor 1.

Connecting the chip

pins of the microchip wiring the microchip programming the microchip pins of the microchip pins of the microchip

Addressing inside the chip

memory of the microchip bus of the microchip

Configuration bits

Configuration bits are set with pragmas, an extension of C and C++, that allows including extra information. They are similar to Java annotations. Here are some examples of using pragma to set configuration bits.

#pragma JTAGEN=OFF
#pragma FWDTEN=OFF
#pragma FSOCEN=OFF

Determining which configurations to use can be difficult. There are several files which are installing with the compiler that can help out, such as the configuration setting pages for the PIC32 MX250F128B that we are using in class.

MPLAB X also provides a useful tool for configuring the bits. You can access it through menu with the selections WindowPic Memory ViewsConfiguration Bits. Below you see the start, end, and code windows generated during the bit configuration process. You can then cut-and-paste the generated C code into your project.

Starting to configure the bits Finished configuring the bits Source for configured bits

The clock!

clocks of the PIC32 clocks of the PIC12 clocks of the PIC12

It is possible to change the clock rate after the chip is running. This is not easy on the PIC24.

#pragma config FNOSC=FRC       // Fast RC Oscillator
#pragma config FCKSM=CSECMD    // Clock switching enabled, FSCM disabled
inline void setupClock(void) {
    PLLFBD = 41 ;             // PLL Feedback Divisor
    _PLLPOST = 0 ;            // PLL postscaler
    _PLLPRE = 0 ;             // PLL prescaler
    // Multiplying by (41+2)/((0+2)*2+(0+2)*2) or 10.75
    // 10.75 * 7370000 = 79227500

    // Writes 0x78 then 0x9A to unlock and then updates _NOSC
    __builtin_write_OSCCONH(0b001) ;
    // Writes 0x46 then 0x57 to unlock and then updates _OSWEN
    __builtin_write_OSCCONL(0x1) ;

    while(_COSC != 0b001) ;   // waiting for clock switch

    while(_LOCK != 0b1) ;     // waiting for PLL to lock

It is much easier on the PIC12.


Reset and the watch dawg

reset circuit of the PIC32 watch dog timer of the PIC32 watch dog timer of the PIC12 WDTCON of the PIC12

Here’s some code to sleep for eight seconds on the PIC12.

    WDTCON |= _WDTCON_SWDTEN_MASK ;               // Enable the dawg
    WDTCON = (WDTCON & ~_WDTCON_WDTPS_MASK) | (0XD << 1) ;    // 8 secs
    asm("  SLEEP") ;                              //  ZZZZZ

GPIO — General Purpose Input/Output

ports of the PIC32 remappable ports of the PIC32 ports of the PIC12

Here is the usual sequence for doing digital I/O.