PIC32 Digital Ports Project

Working with the Digital Ports

The most basic requirement of any system is getting data in and out or reacting to events. A large percentage of the work a microcontroller does is manipulating the ports in some way.

In common with other microcontrollers the ports used in PIC on the BV513 are multi purpose, most have at least 3 functions so it is a question of not only choosing whether the port is input or output but making sure that the port will act as a digital port. This is carried out automatically by the portset and portb(w) words.

This section deals with the digital functions, how to set the direction, get date from them and put data to them. The ports are designated b,c,d,e,f and g. There is no ‘a’ port on this processor. All ports work in the same way so for the purposes of this text we will use port b. This is chosen because at reset this is not a digital port but and analogue port and we must change it first before we can use it.

Input

Although the PIC runs on 3.3 Volts most of the ports will accept up to 5V with the exception of port b. The user must take care not to subject those port to voltages higher then 3,3V

Because of their high input resistance digital input ports may take on any random value when not connected to anything. Touching the pin with a finger normally produces a high output but not always. To have any meaningful signals the pins need to be tied to the +ve rail with a resistor, 10k to 100k will suffice for most applications.
The PIC32 however already has internal pull-up resistors but only on some ports.

Change
Notice
Weak
Pull Up
Port Pin
CN0 CNPUE0 RC14
CN1 CNPUE1 RC13
CN2 CNPUE2 RB0
CN3 CNPUE3 RB1
CN4 CNPUE4 RB2
CN5 CNPUE5 RB3
CN6 CNPUE6 RB4
CN7 CNPUE7 RB5
CN8 CNPUE8 RG6
CN9 CNPUE9 RG7
CN10 CNPUE10 RG8
CN11 CNPUE11 RG9
CN12 CNPUE12 RB15
CN13 CNPUE13 RD4
CN14 CNPUE14 RD5
CN15 CNPUE15 RD6
CN16 CNPUE16 RD7
CN17 CNPUE17 RF4
CN18 CNPUE18 RF5
CN19 CNPUE19 RD13
CN20 CNPUE20 RD14
CN21 CNPUE21 RD15

This table shows which pins have a pull up resistor already available on all ports, port b has this facility available on ports 0 to 5. The middle column refers to a register CNPUE, which by default (reset) is set to 0, disabling the weak pull up resistors.

Setting a Port for Input / Output

The easiest way to configure a port is by using 'setport'. This allows a port to be set as an input or as an output and at the same time set the weak pull up facility if available on that port.

setport "c15" as output // sets port C15 as an output, on the BV513 this is connected to an LED

The word 'output' can be abbreviated to 'out' if required. To use this port the 'port' statement is used:

port "c15" 1    // turns the LED off and
port "c15" 0    // will turn it on
port "c15" t  // toggles port

The action of toggle is to reveres the condition of the port, so if it were 0 before the toggle it would be 1 after and vice versa. Of course it is probably better to use a constant in place of "c15", that way if the port needs to be changed the whole program does not need editing, the technique would be:

constant LED$ "c15"   // sets LED$ as "c15"
setport LED$ as out   // sets the port to output

The constant does not have to be in upper case but that tends to be a convention.

Setting a port for input uses the same technique so:

setport "e1" as input  // sets port e1 as input
print port("e1") // prints either 1 or 0 depending on if e1 was high or low.

Weak pull ups can also be set at this stage but if an attempt to use 'wpu' on a port that does not support it will produce an error.

setport "b0" as in wpu        // sets b0 as an input and enables the weak pull up

setport "b0" as in        // sets b0 as an input and disables the weak pull up

The setport and port statements are highly convenient and reasonably easy to remember. As an alternative the registers that enable the port functions can be directly accessed with the pokei() statement.

constant CPNUSET 0xbf8861e8
function p_init
        pokei(CPNUE%+8)=0x2
endf

The above will enable the pull up resistor for port B0. To fully understand how this works the datasheet for the PIC will need to be consulted. There is a kind of 'half way' solution provided in PIC32-Basic and that is to set the port functions using the 'portb' and 'portw' statements. These statements are much more flexible than the above but in turn they are more complex to use. A short explanation of the statements is given below, for a more detailed explanation see the ports chapter in the PIC32-Basic section

Set Clear & Invert

Any register value that allows write access can be changed using the pokei() statement. In keeping with other RISC 32bit processors there are four register addresses for each single register. First consider this: if you want to set say bit 0, and only bit 0 to 1 of port b, you would need to read the port first, do some AND OR logic and then write it back. If you just said port b=1 then this will set all of the other bits to 0 and they may be in use for something else.

To make it more convenient to set individual bits, there are three additional register addresses for each 'normal' register. The CLEAR, SET and INVERT registers.

This is an extract from the datasheet for port a (the 100 pin devices have a port a) To set a bit 3 to 1, and only bit 3, then PORTASET=0x80 would do the trick (in basic portb "aos" 3 or portw "aos" 0x80)*. All port bits are numbered form 0 and so bit 3 is 0000 0000 0000 1000 which is 0x80. Similarly to clear (make 0) bit 3: PORTACLR=0x80.

* Note the BV513 uses a 64 pin device that does not have a port a, but all ports work the same way.