PIC32MX Quickstart - A Tutorial for Hobbyists - Page 1
Forum section: electronics / general

author: caroper
author_rank: Regular Contributor
timestamp: May 18, 2012, 12:19:59 am
content: PIC32MX QuickstartThe MotivationI recently acquired a sample quantity of PIC32MX150F128B Chips and am very pleased with them. They contain an impressive set of peripherals, several of which are not available in the 8 bit chips, they have the same MIPS M4K Core as the larger members of the PIC32MX family, so code is portable between them all, and whilst cheaper than several of the 8 and 16 bit chips they provide full 32bit arithmetic, have a staggering amount of Flash and RAM compared to the 8 Bit chips and they can run at 40Mhz.The real clincher for me is that they also come in a 28 Pin DIP package (Skinny DIP, The long slimthroughhole ICPackaging, notswimmingnaked) which is perfect for hobbyists because they can be used on a standard breadboard. That makes them accessible without having to buy a full development kit. (You will have to buy a programmer if you don’t already have a suitable one, but that may well be a better long term investment than the Development Kit.)In short they are a perfect introduction to the world of 32 Bit Microcontrollers, C Programming, MIPS Processors and technologies like capacitive touch sensing, Digital Signal Processing and low power architectures and techniques.BUT they are still usable andaffordablein most applications that a hobbyist would use an older 8 Bit PIC.The Reason for this TutorialWhilst fairly easy to setup they are new enough that very little practical information is available on the internet to help Hobbyists get started and they are different enough from the PIC16’s and ATMega’s that there are many “Traps for Young Players” as a famous Video Blogger would say.Having previously worked with the larger PIC32 chips I thought I would help fill that gap, and contribute something back to the community, with a simple Breadboard Circuit, some Sample Source Code and somenarrativeto help navigate the initial mine field. It is intended to provide you with a Quickstart that you can then modify, expand or even replace once you gain confidence with the chip.Both the Code and the Circuit should work with any PIC32MX1 or 2 series Chip in a SPDIP 28 Package, but I have only tested it with the MX150.At a later stage I hope to develop a Bootloader for them as well, but for now you will need at least a PICKit3 to program them and a TTL Level FTDI cable or adapter to use the Serial Communications.The accompanying Source Code addresses the basics of:Setting the Configuration Fuses and Clock Source.Optimizing performanceCreating a 1mS interrupt from the MIPS Core Timer.Mapping a Peripheral (UART2) to I/O Pins using Peripheral Pin Select (PPS).Configuring the UARTIt also provides a simple set of Utilities for Serial Communications and a Simple “Hello World!” test application to show that it all works as expected.I will post this project as a series of parts so this is Part 1 of Several.The next post will be the hardware sectionCheersChris

author: BloodyCactus
author_rank: Frequent Contributor
timestamp: May 18, 2012, 01:03:04 am
content: sounds good. can you use the bootloader from ubw32? I know the chipkit stuff has alternate usb bootloader and an arduino style bootloader... maybe one of those would work?

author: caroper
author_rank: Regular Contributor
timestamp: May 18, 2012, 01:27:59 am
content: The two you suggest are both good examples of working Bootloaders, however, the only one I have any experience with is the the ChipKit bootloader and that is based on the AVRDude format. To work with MPLAB you need a bootloader that can handle Intel Hex16 format.I recently created one for a client, so that is the one I will port over for this project, but I agree that a Chipkit Bootloader would be awesome. It would also need a lot of other support work in order to work with MPIDE though, so I think that is more a ChipKit community project than a Hobbyist intro to PIC32MX.CheersChris

author: T4P
author_rank: Super Contributor
timestamp: May 18, 2012, 07:00:35 am
content: But ... there are teething problems on the PIC32 i read up on microchip's forums before. TEETHING.

author: caroper
author_rank: Regular Contributor
timestamp: May 18, 2012, 08:27:27 am
content: PIC32MX QuickstartPart One - Hardware:Introduction:The Hardware could not be any simpler. In fact you can plug the chip into a breadboard, connect it to a PICKit3 (with no external components) and have a working system. There are, however, certain recommendations that the manufacturer (Microchip) give for reliability and stability of the circuit.The Datasheet for the chips is available herePIC32MX1XX/2XX Family Data SheetI suggest you grab a copy to read along and help you expand on this basic introduction and to get a better overview of the chips capabilities.Section 2.0 of that document recommends (in fact insist on) Decoupling Capacitors on ALL supply pins (Analogue and Digital) and a Capacitor on the Internal Voltage regulator, even if the regulator is not being used. It also shows how to protect the Reset (MCLR) pin to prevent accidental resets.Here is the schematic for my breadboard circuit.Notes on the Schematic:The 3x 0.1uF capacitors are CeramicsThe 10uF capacitor is a Tantalum 6V rating but I used a 10V 6.8uF from the parts box.There is NO Oscillator Circuit. The Clock is generated onboard.There is NO Voltage regulator, I power the circuit from the PICKit3 or the FTDI Board.CAUTION:These Chips are 3V3 parts,DO NOTPower them from a 5V FTDI Cable (Use a Bench Supplyor a3v3 low dropout regulatorif a 5V FTDI cable is all you have). I use the Adafruit FTDI Friend:https://www.adafruit.com/products/284It has jumpers that allow you to change Vcc and the Signal Levels from 5V (default) to 3V3.DO NOT Connect Vcc to Vddunless you have modified the FTDI Friend or have a 3V3 FTDI.Do Nothave both the PICKit3 and the FTDI powering the circuit at the same time.The PICKit3 Power is off by default. If you wish it to Power the Circuit, you have to turn the option on in the IDE. It is intelligent enougth to detect that the Circuit it already powered but for the sake of an expensive piece of kit I still suggest you be selective.If you have a 3v3 FTDI or an external 3V3 supply then use that and leave it connected.The Pins that have been chosen to act as Rx and Tx on the Chip were selected specifically because they are are 5V tolerant, so any TTL level FTDI cable should work (excluding Vcc). I have tested it with the FTDI Friend in 5V mode and all was well.I have Labeled the Pins for what they are being used for, you will not find pins marked as Rx and Tx in the Datasheet, they are assigned using Peripheral Pin Select (PPS).The Breadboard Layout:Notes on the Layout:Notice that all of the Capacitors are as close as possible to the pins they are Decoupling and that the wires are as short as possible. This chip is running at 40MHz which is really pushing the limits for a breadboard circuit. Fortunately because we are using an internal Clock the maximum frequency we see externally will be 8MHz (Explained later).I have tried to keep the layout compact so that it can be built on a Mini Breadboard too.It also leaves 2/3 of a standard breadboard free for application circuits that way.You will notice one extra component that I didn’t show on the Schematic, it is a 22uF 50V electrolytic, across the supply rails. I added it as a tank circuit to relieve the load on the PICKit3 whilst Flashing LED’s. It is not strictly needed but probably helps.On my breadboard I removed the upper power strip. I makes it easier to use right angle connectors for the PICKit3 and the FTDI Friend, but you can leave it intact and use vertical connectors and a ribbon cable to connect if you prefer.That is it for now, I have begun to build it on a small piece of strip board along with a regulator and some common support circuits, such as those found on development boards. I will post that as a separate hardware section though.The Above is all you need to get started and you have the rest of your breadboard available for building support circuits.Next Up - Software - Framework.CheersChris

author: caroper
author_rank: Regular Contributor
timestamp: May 18, 2012, 10:10:07 am
content: PIC32MX QuickstartPart Two - Software:Preamble:You will need MPLab to experiment with the Chip.I have developed the code with MPLAB 8.x and C32 V2.2 under Windows XP. There is no reason, however, for it not to work with MPLabX on any other Platform (WIN7, MacOS and Linux included).The reason I am still using MPLAB 8.x, (apart from not having the time or inclination to learn yet another IDE) is that I am working on a large project that started in MPLAB 8.x and all the other team members are using MPLAB 8.x.So for the sake of sanity and to ensure we don't inadvertently change anything at this late stage of a year long project, we chose to remain on MPLAB 8.x until the Project is signed off.Both are available FREE from Microchip, MPLAB 8.x ishereand MPLABX ishereDownload and install the one you prefer or that supports your computer, but remember I can only advise on MPLAB 8.x at this stage if you get stuck and any posted screen shots will be from MPLAB 8.x.Testing the circuit - Our First Code:One of the things I really like about this family of chips is the flexibility they provide in terms of Oscillator selection.However, along with choices comes complexity and the first hurdle to overcome with any Microcontroller is to get it to clock.This can be even more difficult to achieve on a breadboard due to all the parasitic capacitance and inductance floating around.Fortunately Microchip took that into account when designing this chip so the default Oscillator is an internal High Speed RC clock running at 8MHz.You can plug in the chip, apply 3V3 and it runs.Here is the absolute minimum code needed to flash the LED.Code:// Example 1.0#include <plib.h>main(){mPORTAClearBits(BIT_0); //Clear bits to ensure the LED is off.mPORTASetPinsDigitalOut(BIT_0); //Set port as outputint j;while(1){j = 100000;mPORTAToggleBits(BIT_0); //Toggle light status.while(j--) {} //Kill time.}}That is all you need to prove that you have correctly wired the Board, programmed the chip and everything is running.The next section will start to go into more detail, take a look at the Configuration and Fuse settings and show how to setup the Clock Frequency to get the maximum number of MIPS (Pun Intended) from our MIPS M4K Core.CheersChrisEdited to implement advice frombaljemmett

author: nctnico
author_rank: Super Contributor
timestamp: May 18, 2012, 12:15:48 pm
content: Quote from: Dave.S on May 18, 2012, 07:00:35 amCan you elaborate on that?

author: baljemmett
author_rank: Unknown
timestamp: May 18, 2012, 12:39:45 pm
content: Quote from: caroper on May 18, 2012, 10:10:07 amThe forum will co-operate a bit more if you put your code inside code tags -- [ code ] ... [ /code ], without the spaces -- that gives you a properly formatted box with scrollbars and an easy way to copy the text, as follows:Code:// Example 1.0#include <plib.h>main(){mPORTAClearBits(BIT_0); //Clear bits to ensure the LED is off.mPORTASetPinsDigitalOut(BIT_0); //Set port as outputint j;while(1){j = 100000;mPORTAToggleBits(BIT_0); //Toggle light status.while(j--) {} //Kill time.}}... and now I'm wondering whether I should upgrade my ancient PICkit so I can try one of these new-fangled devices out

author: caroper
author_rank: Regular Contributor
timestamp: May 18, 2012, 12:56:38 pm
content: Thanks for that, it will be a great helpUnfortunately, whilst the PICKit2 version V2.61 supports a few of the PIC32 Chips, it does not support the PIC32MX1xx range.The chips were only announced in January and have only started shipping in production quantities fairly recently.So before you replace the trusty old PICKit2 it may be worth asking Microchip if they have an update in the pipeline to support the MX1xx series.Even if you do replace the PICKit2 with the PICKit3 hang on to it.I have found the Serial Communications and the Simple Logic Analyzer functions invaluable in the past.In fact this Project may be a perfect use for those featuresCheersChris

author: T4P
author_rank: Super Contributor
timestamp: May 18, 2012, 02:37:02 pm
content: http://www.microchip.com/forums/m586823.aspx

author: caroper
author_rank: Regular Contributor
timestamp: May 18, 2012, 03:23:05 pm
content: Quote from: Dave.S on May 18, 2012, 02:37:02 pmI am not sure of the relevance of the link Dave?It is talking about the dsPIC33E (PIC24H) architecture.This thread is about the MIPS Based PIC 32 Architecture. They are totally different families of chips.

author: caroper
author_rank: Regular Contributor
timestamp: May 18, 2012, 06:56:12 pm
content: PIC32MX QuickstartPart Three - Configuration:Clock Management:As mentioned earlier The PIC32MX has a very flexible Oscillator section including four external and internal oscillator options as clock sources, combined with an On-Chip PLL with user-selectable input divider, multiplier and output divider to boost operating frequency of the selected sources.Our initial test code is using the internal RC oscillator at its default frequency.Whilst sufficient to get the chip up and running or even to run non time critical applications, an RC clock is not stable or accurate enough for any kind of communications, or so I thought.Let’s take a look at FIGURE 8-1: of thePIC32MX1XX/2XX Family Data Sheet(I linked to it before so you may not need to download it again). The first thing that I noticed is that the Chip actually has two PLL systems. one for the system Clock and another one for the USB clock. But what I found really surprising is that the RC Oscillator (FRC) is connected to the input of the PLL.Experiment 1.Seeing that the FRC is connected to the PLL and the chip is capable of running at 40Mhz, lets have a look at what is required to set up the PLL.Referring again to the Datasheet FIGURE 8-1 we can see that the PLL input can be selected as either Posc or FRC and that the input needs to be between 4 and 5 Mhz. We also know that our FRC Oscillator is running at 8MHz so the first thing we need to do is divide the Clock by 2. There is no Multiply by 10 function but there is a Multiply by 20 so in order to get a 40MHz output all we need to do now is Divide that by 2 again.All of those steps are set by the Configuration Bits or Fuses.For a full list of configuration bits, in MPLab, select Help --> Topics...From the list select Language Tools --> PIC32MX Config Settings.Finally from the list of devices select PIC32MX150F128B (Or the Chip that you are using)I will not go into detail here, I just wanted to show you where to find them, as that is one of the most frequently asked questions.The Fuses, or Configuration Bits are set in C32 by using the #pragma config derivative.Lets have a look at what we need to select our FRC as input to the PLL, from the list we find Oscillator Selection Bits and within that FNOSC = FRCPLLNow we need the PLL Input Divider: FPLLIDIV = DIV_2Our Multiplier: FPLLMUL = MUL_20and finally the System PLL Output Clock Divider FPLLODIV = DIV_2Putting it all together we get:#pragma config FNOSC = FRCPLL#pragma config FPLLIDIV = DIV_2#pragma config FPLLMUL = MUL_20#pragma config FPLLODIV = DIV_2Those could be combined into one line as :#pragma config FNOSC = FRCPLL, FPLLIDIV = DIV_2, FPLLMUL = MUL_20, FPLLODIV = DIV_2They can also be in any order, However, I don’t recommend doing that as it is easy to end up spending hours trying to find a non existent bug in your code when in reality you have just overlooked a fuse setting. You will be thankful one day if you have them one per line and in a logical order.Modifying our example code we get:Code:// Example 2.0#pragma config FNOSC = FRCPLL#pragma config FPLLIDIV = DIV_2#pragma config FPLLMUL = MUL_20#pragma config FPLLODIV = DIV_2#include <plib.h>main(){mPORTAClearBits(BIT_0); //Clear bits to ensure the LED is off.mPORTASetPinsDigitalOut(BIT_0); //Set port as outputint j;while(1){j = 100000;mPORTAToggleBits(BIT_0); //Toggle light status.while(j--) {} //Kill time.}}Upload it to the chip and you will see the LED Flash rate increase dramatically.If you have a frequency counter you could measure the rate before and after by measuring the output of RA0.Using the EXETECH I measured 1.542Hz initially and 15.42Hz after the Oscillator modifications for an exact 10 fold increase in performance.Experiment 2.We still have not quite finished with our Oscillator set up. You will also notice from Datasheet FIGURE 8-1 That the Peripheral Bus has a separate Clock (PBCLK) that is derived from the system clock. As we are trying to get the maximum we can out of the Chip, let's set the PBCLK to 40Mhz too: #pragma config FPBDIV = DIV_1The chip has a lot of registers that can be used to optimize the internal pipe lining of the chip. Without going into too much detail suffice it to say we have DMA controllers that are running independently from the Peripheral Bus and the CPU, we also have various wait states on certain memory locations such as the Flash, the Ram and the Internal Registers, we also have several other factors such as instruction and data pipe lining that can impact on performance.The topic of optimization is sufficient to fry your brain, well mine at least, and it could certainly put the hobbyist off using such a powerful chip. Fortunately we don't have to worry about it. You will have noticed that in our code we have the statement:#include <plib.h>Plib is a Library of macros and functions specifically designed to make it easier to use the PIC32 Chips.One of the most useful Functions in it is the System Configuration utility so lets put it to use.SystemOptimizationIn order to use it we need to pass it our clock frequency, but as several functions in Plib also require that information it is useful to define it in one place and use it wherever we need it. That way if we change our Clock Frequency to reduce power consumption for instance, we only ever change it in one place.#define GetSystemClock()(40000000ul)notice that although 40000000 is a constant we need to type it as an unsigned long hence the ul postfix.we are running ourPeripheral Bus at the same speed so we also define:#define GetPeripheralClock() (GetSystemClock())Then in the initialization part of our code we can say:SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);Putting it all together we now get:Code:// Example 2.1#pragma config FNOSC = FRCPLL#pragma config FPLLIDIV = DIV_2#pragma config FPLLMUL = MUL_20#pragma config FPLLODIV = DIV_2#pragma config FPBDIV = DIV_1#define GetSystemClock() (40000000ul)#define GetPeripheralClock() (GetSystemClock())#include <plib.h>main(){SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);mPORTAClearBits(BIT_0); //Clear bits to ensure the LED is off.mPORTASetPinsDigitalOut(BIT_0); //Set port as outputint j;while(1){j = 100000;mPORTAToggleBits(BIT_0); //Toggle light status.while(j--) {} //Kill time.}}Compile, and upload it and you will notice another change in the flash rate.If you still have the Frequency Counter attached it will be reading somewhere around 20Hz, 20.05 in my case.So that one line of code has given us another 25% increase in performance.Certainly a function worth having.That is it for today, but I will continue tomorrow with a look at Peripheral Pin Select (PPS) and Setting up a UART for serial communications.Till then,Cheers,Chris

author: BloodyCactus
author_rank: Frequent Contributor
timestamp: May 19, 2012, 01:55:00 am
content: this is awesome! thanks mate.

author: T4P
author_rank: Super Contributor
timestamp: May 19, 2012, 04:01:49 am
content: Quote from: caroper on May 18, 2012, 03:23:05 pmThey have been talking about the PIC32, scroll down.

author: caroper
author_rank: Regular Contributor
timestamp: May 20, 2012, 12:26:17 am
content: PIC32MX QuickstartPart 4 - Peripheral Pin Select (PPS)Anyone starting out with the MX150, that is used to working with other chips, are likely to look at the pin out diagram and think it has hardly any peripherals. They couldn't be more wrong.One of the biggest problems with microcontrollers is how to bring all of the peripherals out to pins without making them mutually exclusive, for instance if the SPI module and the Timer/Counter module share a common pin, you can use one or the other but not both.Things get even worse the less pins you have to work with and the MX150 only has 28 PINS.To compound the issue further this chip packs a lot of Peripherals but only 21 of the 28 Pins are usable for actual I/O.This sounds like a recipe for disaster, but it is not thanks to PPS.Lets have a look at it, you will need thePIC32MX1XX/2XX Family Data Sheetagain. Download it if you haven't already.TABLE 11-1: of the Datasheet shows the possible INPUT PIN SELECTION and TABLE 11-2: the OUTPUT PIN SELECTION.At first glance these look pretty daunting. You can either select a Peripheral and see which pins it can use or you can select a pin and see which peripherals are available. The tables are also separated into 4 groups of 8 Pins.For Inputs the the Peripheral is listed on the left and the available pins on the right.For outputs it is the other way round.So lets have a look at how these tables are used.Possibly the most used peripheral in any microcontroller is the UART.Even if the target application has no need to talk to a PC, having some kind of console I/O is incredibly useful for debugging. Often when I have the ICD3 and the Logic / Protocol analyzer connected I still have a console session going at the same time. So lets have a look at connecting a UART to the outside world via PPS.The MX150 has two UART’s so lets have a look and see where we can connect them.First we will consider UART1 so we look at TABLE 11-1 Left hand column and look for U1RX.We find that RPA2, RPB6, RPA4, RPB13, RPB2, RPC6, RPC1 and RPC3 can all be used.Next we locate them physically on the package, to do this you need to cross reference the pinout diagram on page 4. (I always print out the diagram for the package I am working with).At this point we can see a problem with using UART1 in this application.The dark shaded PINS on the diagram are 5V tolerant, but none of the available pins for U1RX fall in this category. This interface is likely to be used with a 5V FTDI cable so a 5V tolerant input is essential.Lets have a look for U2RX instead. We find it can be used on RPA1, RPB5, RPB1, RPB11, RPB8, RPA8, RPC8, and RPA9.BINGO: RPB5, RPB11 and RPB8 are all 5V tolerant so UART2 will be our choice.Now we look at TABLE 11-2 Right hand column and find U2TX.The Pins available are: RPA3, RPB14, RPB0, RPB10, RPB9, RPC9, RPC2 and RPC4.Just in case the cable is connected in reverse we should probably make our TX Pin 5V tolerant too, so we can narrow the selection to: RPB10 and RPB9.Select a pair, any pair.Well not quite.We also have to consider any other Peripherals we may need to use, especially the Analogue ones as Analogue Peripherals can not be remapped by PPS, they have dedicated I/O.Once you have weeded out the pins that are unavailable due to conflicts, the final decision can be determined by PCB routing. If you can simplify the routing or save a layer on the board by choosing a different Pin that is an added bonus.In this case I will just select RPB10 and RPB11 as they are adjacent.The Paperwork is almost done, but remember the 4 groups of pins? they are relevant.We have selected to use U2RX on RPB11 and that was in the 2nd Section of TABLE 11-1 and U2TX on RPB10 in the 4th section of TABLE 11-2.lets get back to creating code, and Plib again comes to the rescue, it avoids us having to directly set bits in registers by providing functions to do it for us.PPSInput() and PPSOutput()The arguments are in the order we read them from the tables so to set U2TX we say:PPSOutput(4, RPB10, U2TX);And to to set U2RX we say:PPSInput (2, U2RX, RPB11);Being able to assign pins like this in Software, whilst powerful, is also potentially dangerous.If your program crashes or you mess up some pointer arithmetic in C you could start writing random data all over the memory map. If that happens there is the possibility of it inadvertently changing a pin allocation and blowing up external hardware or the CPU. In order to prevent that, PPS has a locking mechanism that requires certain values to be written in a certain sequence before the registers can be changed.Fortunately Plib handles that for us too.So we now say:PPSUnLock;PPSOutput(4, RPB10, U2TX); // MAP Tx to PB10PPSInput (2, U2RX, RPB11); // MAP Rx to PB11PPSLock;the indentation is irrelevant, I just use it to show the blocking.There is one more thing to consider.The PPS functions set up the mapping but they do not setup the actual port.That has to be done separately and with the usual consideration for turning off any Analogue functions.mSETPORTBDigitalOut(RPB10);andmSETPORTBDigitalIn(RPB11);takes care of that for us.I need my bed so that is it for today, tomorrow we will look at actually using the UART.Thanks for following along.CheersChris

author: bxs
author_rank: Regular Contributor
timestamp: May 21, 2012, 02:54:41 pm
content: Great work, just keep it coming.I also like this new SDIP PIC32, they are nice to play, I prefer the USB ones, like PIC32MX250F128B, even if the USB is not used it's nice for example for a USB bootloader so no USB-RS232 stuff.As you said it's great for hobbyists, but I think that for simple things they are simple too expensive, better go with PIC 8bit or 16bit.For 32bits final products NXP for example, have really cheap stuff, for quantities is goes a bit less than $1, once again, microchip don't have nothing not even near that, they probably don't want to kill the other PICs, but they end up killing PIC32 for entry level.But for hobbyists, the price don't really matter and this new PIC32 are really nice to play, I love them

author: caroper
author_rank: Regular Contributor
timestamp: May 22, 2012, 10:38:00 am
content: Thanks,Sorry for the delay in posting the UART Code, I got distracted prototyping other parts of the Project and ended up spending more time playing than I expected. Then work got in the way.Customers are a pain but they do put bread on the table and the cash to buy bits to experiment with.Update coming ASAP.CheersChris

author: poorchava
author_rank: Super Contributor
timestamp: May 23, 2012, 09:58:02 pm
content: Heh, the PPS is one of the main reasons for which I love dspic33/pic24h (I've got some samples of 'E' versions of both, but haven't tried those yet). It makes board layout SO much simpler..

author: xquercus
author_rank: Contributor
timestamp: May 24, 2012, 06:57:40 am
content: Nice tutorials. Thanks for bringing my attention to this line. I've really just ignored the 32-bit PICs but will have to get my feet wet at some point.

author: caroper
author_rank: Regular Contributor
timestamp: May 24, 2012, 09:06:54 am
content: PIC32MX QuickstartPart 5 - The UARTWe are moving away from hardware into software for this post so I will begin with the code and then explain it.Attach the board to the PC via an FTDI connector or the PICKit2 UART Tool if you have a PICKit2 (I will talk about using the UART Tool along with an expanded Schematic and Breadboard layout in another Post).Set your terminal emulation to 38400 Baud, 8 Bit, No Parity, 1 Stop Bit.Compile it and program the Chip, You should see 'Hello World!" appear on the Terminal each time you press the reset button.Code:// Example 3.0#pragma config FNOSC = FRCPLL#pragma config FPLLIDIV = DIV_2#pragma config FPLLMUL = MUL_20#pragma config FPLLODIV = DIV_2#pragma config FPBDIV = DIV_1#define GetSystemClock() (40000000ul)#define GetPeripheralClock() (GetSystemClock())#define BaudRate 38400 // Maximim Rate of PICKit2 UART Toolchar Message[] = "Hello World!";#include <plib.h>void Serial_print(char *buffer){while(*buffer != (char)0){while(!UARTTransmitterIsReady(UART2));UARTSendDataByte(UART2, *buffer++);}while(!UARTTransmissionHasCompleted(UART2));UARTSendDataByte(UART2, '\r');UARTSendDataByte(UART2, '\n');}main(){SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);mPORTAClearBits(BIT_0); //Clear bits to ensure the LED is off.mPORTASetBits (BIT_1); //Clear bits to ensure the LED is off.mPORTASetPinsDigitalOut(BIT_0|BIT_1); //Set port as outputmPORTBClearBits(BIT_10);mPORTBSetPinsDigitalOut(BIT_10); // Set PB10(Tx) as outputmPORTBSetPinsDigitalIn (BIT_11); // Set PB11(Rx) as inputPPSUnLock; // Allow PIN MappingPPSOutput(4, RPB10, U2TX); // MAP Tx to PB10PPSInput (2, U2RX, RPB11); // MAP Rx to PB11PPSLock; // Prevent Accidental Mapping// Configure UART2UARTConfigure(UART2, UART_ENABLE_PINS_TX_RX_ONLY);UARTSetLineControl(UART2, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);UARTSetDataRate(UART2, GetPeripheralClock(), BaudRate);UARTEnable(UART2, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));Serial_print(Message);int j;while(1){j = 100000;mPORTAToggleBits(BIT_0|BIT_1); //Toggle light status.while(j--); //Kill time.}}Like most things in the PIC32 the UART has been considerably enhanced over the UART in the 8Bit PIC's. Once again PLib is used to abstract out the complexity of addressing individual registers and bits.Lets have a look at the code additions in order of execution.UART Configuration.UARTConfigure(UART2, UART_ENABLE_PINS_TX_RX_ONLY);The PIC32 can have up to six UART's, however, UART's can now be paired up to automatically handle Hardware Handshaking. Effectively that means you can have 6 simple UART's, 3 UART's with Hardware Handshaking or any combination in between.The Constant'UART_ENABLE_PINS_TX_RX_ONLY'is telling PLib that we only want basic UART functionality, that is No Handshaking.The next line is the same as the parameters that we set in the Terminal emulation.UARTSetLineControl(UART2, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);The PIC32 derives it's UART Timing from the peripheral bus, that is the reason we have:#define GetPeripheralClock() (GetSystemClock()) .PLib uses it in this case to determine the register values for our chosen BaudRate. If we change either the System Clock or the Peripheral Clock we only have to alter the code in one place and it will be able to recalculate everything for us.I place the line:#define BaudRate 38400at the top of the code so that it can be easily changed whilst experimenting and to keep it grouped with the rest of the system timingparameters.Finallywe enable the UART.UARTEnable(UART2, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));Interfacing with the UARTSerial_print(Message) is a function call. Lets break down the Function.Code:void Serial_print(char *buffer){while(*buffer != (char)0){while(!UARTTransmitterIsReady(UART2));UARTSendDataByte(UART2, *buffer++);}while(!UARTTransmissionHasCompleted(UART2));UARTSendDataByte(UART2, '\r');UARTSendDataByte(UART2, '\n');}I am a hardware not a Software guy, and I am also new to C. I started learning C specificaly to use the PIC32, so I will not presume to teach you C Programming. I will, however, point out what PLIb is doing for us again.char *buffer is a pointer to a string, the string in question is the one we defined at the start of the code with the line:char Message[] = "Hello World!";and passed into the Function with the line:Serial_print(Message);Our Function will step through that string sending one character at a time followed by CR-LF.The PIC32 UART's include both a TX and an RX Buffer in hardware, it is not large, only 4 bytes each, but it can be useful and makes using the UART's easier in a lot of cases.The function UARTTransmitterIsReady(UART2) will be TRUE if one or more Bytes of the Tx buffer are empty and ready to receive data. So the line:while(!UARTTransmitterIsReady(UART2));is effectively waiting for buffer space before sending the next Character with the line:UARTSendDataByte(UART2, *buffer++);UARTTransmissionHasCompleted(UART2) returns TRUE is the Tx Buffer is empty.We are using it in the loop:while(!UARTTransmissionHasCompleted(UART2));to wait until our Message has been sent.The CR and LF characters are sent without any poling as we know the 4 Byte Tx Buffer is empty, so in this case we can fire and forget.Well that's it for this post but I should point out where you can got more information on PLib.In MPLab select Help -> Topics...and under Language Tools you should see: C32 Peripheral Lib Guide.And a well hidden PDF document exists (as of this posting) on the Microchip web site:http://ww1.microchip.com/downloads/en/DeviceDoc/32bitPeripheralLibraryGuide.pdfCheersChris

author: LuckyJaker
author_rank: Contributor
timestamp: May 25, 2012, 01:59:55 pm
content: I wish I read your articles before I started programming the PIC32...

author: caroper
author_rank: Regular Contributor
timestamp: May 25, 2012, 08:28:32 pm
content: PIC32MX QuickstartPart 6 - an Extra Timer and InterruptsThe PIC32MX has a nice complement of timers, five by 16 bit which may be paired to form one 16 bit and two 32 bit timers or any combination. These timers are similar to the ones we know from the rest of the PIC line, and I will go into more detail on them in a later post. I mention them here because what is often overlooked, and indeed not even mentioned in the Data Sheets as far as I can tell, is the existence of a yet another 32 Bit Timer.We already know that the PIC32MX family of Microcontrollers are based on the MIPS M4K Core, well it just so happens that the MIPS M4K Core contains a 32 bit Timer.This timer is like gold, just about every program ever written for a Microcontroller needs a timing source, usually of 1mS, and to achieve that one of the valuable Timer/Counter modules is often sacrificed.Lets then have a look at how we can use the Core Timer to provide us with that useful function effectively for free.The MIPS Core TimerThe Core Timer is a 32 Bit Timer that is fed from the System Clock, as opposed to the peripheral clock, via a divide by 2 input. We have no control over the prescaler and it starts Timing as soon as the Oscillator starts running. If we are running our Clock at 40Mhz then the Tick rate of the Core Timer is going to be 50ns and the depth of 32 bits means it will count for 220 Seconds before it rolls over.Whilst we cannot start or stop the timer, we can clear it or reload it. More importantly, it can generate an interrupt.Lets have a look at some code to do just that.First we decide how often we want the interrupt to occur, in this case we want a 1mS Tick, we have already defined GetSystemClock() and we know that it is divided by 2 before being fed to the Core Timer, so if we divide that by 1000 we have the CORE_TICK_RATE, that is required for an interrupt every 1mS.#define CORE_TICK_RATE (GetSystemClock() / 2 / 1000)We now have to pass that value to the Core Timer itself and as usual PLib has a function for that:OpenCoreTimer(CORE_TICK_RATE);That Function is going to Set a Flag bit and optionally fire an interrupt when the Value in CORE_TICK_RATE is reached. Let’s use the latter option:mConfigIntCoreTimer((CT_INT_ON | CT_INT_PRIOR_2 | CT_INT_SUB_PRIOR_0));This macro Enables the Core Timer Interrupt, assigns it a Priority of 2 and a Sub Priority of zero.You will have noticed 2 important things here:1) The PIC32 has interrupt Priority levels.2) Interrupts can be prioritised within an interrupt priority level.This is referred to as MultiVectored interrupts.What is particularly powerful in the PIC32 architecture is that the Interrupt Controller is separated from the CPU. That means that Interrupts are prioritised before being presented to the CPU, it also allows such things as edge polarity control and Software generated Interrupts. In fact the documentation on the Interrupt controller is longer than the Documentation of many of the PIC10F series devices. But we don’t need to concern ourselves with most of it, because PLib is hiding all the complexity anyway.What we do need to know is that each interrupt can have one of seven priority levels, where 1 is the lowest priority and 7 is the highest priority, and within each priority Level there are four sub priority levels where 0 is the lowest priority and 3 is the highest priority. Notice that the main priority level counts from 1, a priority level of zero is equivalent to disabling the interrupt. It is also useful to know that the priority 7 interrupts use a shadow register set to save the time normally required to Push and Pull the working registers in an interrupt service routine.In order to actually use the interrupts we need to turn them on first and Just to prove that Microchip Engineers do have a sense of humour I quote this from some correspondence with them:QuoteWhich pretty much sums up the whole of PLib as I am sure you have noticed by now.Handling InterruptsWhen an interrupt is generated it is prioritised by the Interrupt controller and then passed to the CPU as an interrupt vector. In order to process that interrupt we need to generate code associated with the appropriate Interrupt vector.As there are up to 96 interrupt sources distributed amongst 64 interrupt vectors we are very fortunate that they have been defined for us in advance in the PLib Header files. All we need to know is that we are using:_CORE_TIMER_VECTORNote the proceeding underscore.and to create the interrupt handler we use the special function statement:__ISR()This time notice the two underscores. This syntax is critical to the compiler.An interrupt handler has no return value so it is declared as void and we need to pass it the Vector it is handling, the priority level and a function name (used by the linker and debugger)void __ISR(_CORE_TIMER_VECTOR, ipl2) CoreTimerHandler(void)You should never do much inside an Interrupt handler, keep it as short as possible.In this case we need to increment our milliseconds count and initialise our Core Timer and critically, clear the interrupt flag to prevent it from immediately triggering on exit.Our milliseconds count we will keep in a global variable and as it is going to be changed inside an interrupt service routine, outside of the compilers control, we need to define it as volatile, this warns the compiler not to try and optimize it in any way.volatile unsigned long gmscount;The code looks like this:gmscount++;UpdateCoreTimer(CORE_TICK_RATE);mCTClearIntFlag();Finally we need some code to test that it is working so let’s define a delay function to replace the loop we are currently using to flash the LED.void delay(unsigned long msdelay){unsigned long startTime = gmscount;while(gmscount - startTime < msdelay);}our body code will then change to:PORTToggleBits(IOPORT_A, BIT_0);delay(500);which should flash the LED every second.Lets put it all together and try it out:Code:// Example 4.0#pragma config FNOSC = FRCPLL#pragma config FPLLIDIV = DIV_2#pragma config FPLLMUL = MUL_20#pragma config FPLLODIV = DIV_2#pragma config FPBDIV = DIV_1#define GetSystemClock() (40000000ul)#define GetPeripheralClock() (GetSystemClock())#define CORE_TICK_RATE (GetSystemClock() / 2 / 1000) // 1mS#define BaudRate 38400 // Maximim Rate of PICKit2 UART Tool#include <plib.h>char Message[] = "Hello World!";volatile unsigned long gmscount;;void delay(unsigned long msdelay){unsigned long startTime = gmscount;while(gmscount - startTime < msdelay);}void Serial_print(char *buffer){while(*buffer != (char)0){while(!UARTTransmitterIsReady(UART2));UARTSendDataByte(UART2, *buffer++);}while(!UARTTransmissionHasCompleted(UART2));UARTSendDataByte(UART2, '\r');UARTSendDataByte(UART2, '\n');}main(){SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);OpenCoreTimer(CORE_TICK_RATE);mConfigIntCoreTimer((CT_INT_ON | CT_INT_PRIOR_2 | CT_INT_SUB_PRIOR_0));INTEnableSystemMultiVectoredInt();mPORTAClearBits(BIT_0); //Clear bits to ensure the LED is off.mPORTASetBits (BIT_1); //Clear bits to ensure the LED is off.mPORTASetPinsDigitalOut(BIT_0|BIT_1); //Set port as outputmPORTBClearBits(BIT_10);mPORTBSetPinsDigitalOut(BIT_10); // Set PB10(Tx) as outputmPORTBSetPinsDigitalIn (BIT_11); // Set PB11(Rx) as inputPPSUnLock; // Allow PIN MappingPPSOutput(4, RPB10, U2TX); // MAP Tx to PB10PPSInput (2, U2RX, RPB11); // MAP Rx to PB11PPSLock; // Prevent Accidental Mapping// Configure UART2UARTConfigure(UART2, UART_ENABLE_PINS_TX_RX_ONLY);UARTSetLineControl(UART2, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);UARTSetDataRate(UART2, GetPeripheralClock(), BaudRate);UARTEnable(UART2, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));Serial_print(Message);int j;while(1){PORTToggleBits(IOPORT_A, BIT_0);delay(500);}}// Interupt Handlersvoid __ISR(_CORE_TIMER_VECTOR, ipl2) CoreTimerHandler(void){gmscount++;UpdateCoreTimer(CORE_TICK_RATE);mCTClearIntFlag();}Compile it and program the chip.you should now have an LED that flashes at exactly 1 second and a frequancy of 1Hz if you still have a frequency counter attached. in my case the frequency counter reads 1.002Hz, which when you consider we are using an RC oscillator is pretty remarkable accuracy.There is a register that we can use to calibrate the internal RC oscillator, if we wanted greater accuracy, but it is stable enough for fairly high speed serial communications as it is and if we need more accuracy for time functions we have a Built in RTCC. That will be discussed soon.That’s it for today,Till next time,CheersChris

author: caroper
author_rank: Regular Contributor
timestamp: June 06, 2012, 10:22:02 pm
content: For those of you that are interested in trying the PIC32 but have been put off by only having a PICKit2 programmer here is a great deal.You can get the Microstick II with integrated Programmer/Debugger and an assortment of CPU's for $3.49 if you enter the code"MCHPPIC32".Thanks tomukymukfor the heads up on this one.I have ordered one, they only have 4 left as of my order, but are getting new stock on the 18th, so future installments of this thread will include examples with thePIC32MX250F128.CheersChris

author: baljemmett
author_rank: Unknown
timestamp: June 07, 2012, 01:42:59 pm
content: Quote from: caroper on June 06, 2012, 10:22:02 pmIndeed, and for those of us still using a PICkit 1 (with a flying DIP8-to-ICSP lead, I'm not atotalmasochist) it was a no-brainer. Many thanks to mukymuk for the tip! Chucked in a few jellybean PICs to replenish my depleted stocks, though, just so the shipping wasn't more than twice as much as the goods total

author: BloodyCactus
author_rank: Frequent Contributor
timestamp: June 10, 2012, 04:00:15 am
content: shoot. good a reason as any to grab one and a couple of extra chips for experimenting

author: HopWorks
author_rank: Contributor
timestamp: October 02, 2012, 09:54:07 pm
content: Quote from: caroper on May 20, 2012, 12:26:17 amIf I may ask, what is the first parameter for? I looked at the pps.h header file in C32 and the parameter name is 'grp'. Why is it 4 for PPSOutput and 2 for PPSInput? Are those values static?Also, when I looked at the comments in the pps.h file, they do not even acknowledge the grp parameter. Yet the #define below the comments clearly shows it.Thank you very very much for your posts! Very well written and very helpful!

author: ptricks
author_rank: Frequent Contributor
timestamp: October 11, 2012, 01:03:59 pm
content: Quote from: LuckyJaker on May 25, 2012, 01:59:55 pmThat is so true. These tutorials would have been a big help for those days I was pulling out my hair. Part of the problem is microchip data sheets for the pic32. They write one datasheet to cover 10 chips and then pick and choose what applies to each chip in the data sheet. That makes it much harder to understand than one datasheet for each chip. Some of the include files don't make it easier either, when you open one and it is filled with a bunch of if then branches for different models it really confuses things.

author: Unknown
author_rank: Unknown
timestamp: October 27, 2012, 11:27:42 am
content: Great post Chris!!

author: mrflibble
author_rank: Super Contributor
timestamp: October 28, 2012, 05:30:42 pm
content: Nice post! Italmostmakes me consider retrying Microchip parts.

author: simonvav
author_rank: Newbie
timestamp: August 22, 2013, 03:02:04 am
content: PIC32MX250F128B is one of the best micro controllers for beginners. If you need a tutorial and plenty of samples, just type "PC USB Projects" into Google.

author: caroper
author_rank: Regular Contributor
timestamp: August 22, 2013, 06:38:42 am
content: I moved the Tutorials over tohttp://caroper.blogspot.com/2013/06/this-will-be-home-for-my-pic32mx.htmland developed he hardware in this thread into a USB based ChipKIT compatible system on a bread Board. Very useful for beginners to 32Bit systems as it eliminates the need for MPLab and includes a fully optimised C++ compiler for free.I have not had a chance to update it this month as I was away on business, but have several more experiments ready to be written up, so if you like what you see, subscribe so you get notified.CheersChris

author: M0BSW
author_rank: Frequent Contributor
timestamp: August 25, 2013, 09:08:55 am
content: This is fascinating as I only recently have dipped my toe into pic programing, I think this is out of my league a lot, but still going to follow this thread as it's current with my endeavours at this time.And here's a fair warning , I am more than likely going to ask some stupid questions, if no when I get lost

author: caroper
author_rank: Regular Contributor
timestamp: August 25, 2013, 09:28:05 am
content: Quote from: M0BSW on August 25, 2013, 09:08:55 amOn the contrary the 32Bit PIC's are actually easer for beginners than the smaller ones, as they are optimised to High Level Programming languages and don't have segmented memory. The main reason I created the board design, linked above, is that it allows you to use an Arduino Style language and has predefined Libraries so that you can dive straight in to exploring capability without having to learn the low level hardware first.QuoteWhen you are trying to learn something new, the only stupid question is the one you didn't ask, especially as getting stuck on something simple may well make you give up.CheersChris

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: August 25, 2013, 09:46:07 am
content: I've used this chip a couple of times - quite nice and good value but IMO they've trimmed a little too much from the larger parts :No shadow registers for interrupt context save severely worstens interrupt latency & context save/restore time from what it could be.No pullups in I/Os - WTF?Only limited pin-remapping capabilityIncomplete UART FIFO implementation - no timeout interrupt means you need to waste a timer for an interrupt to catch small leftovers stuck in the FIFO.Although the UART supports high rates, but looks like they just assumed you'd be using DMA to run it, but this is not always practical, and the interrupt latency means rates over about 3mbits/sec are difficult to achieve in practice if you need to do any realtime processing of incoming data (e.g. address matching).It's still pretty nice though, just annoying when little details spoil things.The wide range of packages is great - I've used both QFN28 and SO28, and DIP for prototyping. The QFN28 is about the smallest non-BGA part I could find with 32K RAM, and Microchip's cheap programming service can be enough on its own tojustify choosing it over an ARM.

author: M0BSW
author_rank: Frequent Contributor
timestamp: August 25, 2013, 09:48:51 am
content: Quote from: caroper on August 25, 2013, 09:28:05 amOk I've taken that on board Thank You

author: GertJL
author_rank: Newbie
timestamp: August 17, 2015, 10:57:39 am
content: Hi Chris,(not sure if this blog is still alive, btw I am also from South Africa)Thanks for the interesting and clear explainations on topicsI have a query, I am sure it is straight-fwd....First, I observe , 'Change Notification' refr in the datasheets.What is the purpose thereoff and is it applicable inPart 4 - Peripheral Pin Select (PPS) ?I have ChipKit DP32, populated with 32MX250F128B -I am using PicKit 3 to prgm the unit.Using MLABX 1.85 xc32 compiler. MLA Lib : 2013/06/15I have the basic I/O working etc.I now wish to implement INT2 on PA4 (chip pin12)So with your info -<<PPSUnLock;PPSInput(3,INT2,RPA4);PPSLock;PORTSetPinsDigitalIn(PORTA,BIT_4);>>I believe I now have PORTA.4 (RPA4) Configure for INT2, digital InputPlease advise if this is incorrect?Now, how do I implement prototype config / ISR Handler for INT2?I want it configured for Edge-trig,Not sure how to configure it etc.Lastly, do you have some examples re ADC configs and Applications(Auto Sampling)Can you advise please?Once again, thank you for interesting reading, which allows for meto progress.Regards,Gerhard

author: caroper
author_rank: Regular Contributor
timestamp: August 18, 2015, 01:04:10 pm
content: Hi Gerhard,Or as a fellow South African maybe I should say "Howzit Boet", and dankie for you kind commentsThe Blog is not dead as such, more dormant as I have had not time to work on it in the past year.That said I have just updated it with the introduction to a new series of articles about a flexible development board.I can't really answer your questions off hand, as I don't use MPLabX or XC32 myself, I tend to use the ChipKit as an Arduino Compatible tool for rapid prototyping and my colleague then writes the native PIC32 code, he is the Software Guru. I am more of a hardware guy so if what I need is not in a Library I get him to create a library for me.The Blog tends to document my current experiments, originally for my own records but I decided why not share.My current focus is on the Small pin Count 8 Bit devices as I am busy developing a proof of concept for a client, so any Blog posts in the near future will probably be PIC18 related as I get to grips with that architecture and its peripherals.One day I am sure I will get back to the series on understanding PIC32's and I still want to create a ChipKIT bootloader for the PIC32MX170, but I have no idea when.CheersChris