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.
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.