====== PIC24F ====== The PIC24F is a versital microprocessor with lots of nice peripherals such as DAC, multiple UARTS and PWM. I used it for the [[ltp_lidar|LTP Lidar]]. ===== Documentation Notes ===== The PIC24 from Microchip has two types of documentation. The first is the device specific datasheet and the second is a general set of documentation for the PIC24 family of chips. Sometimes, especially when looking for a detailed explanation of how a peripheral works, the general family documentation is more helpful. ===== General ===== Every project has ''%%%%'' includes. In it there are a bunch of ''%%ifdefs%%'' that include your device specific header. Search for it and you will find it! There used to be compiler libraries for the peripherals of the PIC24 but they have become depracated (([[http://www.microchip.com/SWLibraryWeb/product.aspx?product=PIC24%20MCU%20dsPIC%20Peripheral%20Lib|Legacy PIC24 MCU & dsPIC DSC Peripheral Library]])). Instead perhiphal functions are generated by MCC (MPLAB Code Configurator). Here is great website with info on I2C and the MCC I2C commands [[http://www.studentcompanion.co.za/interfacing-the-ds1307-real-time-clock-with-pic-microcontroller-xc8/|link]]. ===== Delay ===== You can use the delay functions of the xc16 compiler but you have to define the following before including the right header file. It is this: #define FOSC (32000000ULL) #define FCY (FOSC/2) #include Then you can use: __delay_us() __delay_ms() ===== PWM ===== Getting PWM to work on the PIC24 is tricky. We make use of the ''%%MCCP/SCCP%%'' peripheral that has a tremendous amount of functionality which also makes it tricky to use. ==== Capture/Compare/PWM/Timer Modules (MCCP and SCCP) ==== The PIC24 has a periphal group called the ''%%MCCP%%'' and ''%%SCCP%%''. The data sheet here has specific register information [[http://www.mouser.com/ds/2/268/33030a-254597.pdf|link]]. This document gives a detailed description of this peripheral group [[http://ww1.microchip.com/downloads/en/DeviceDoc/33035a.pdf|link]]. Go to Section 64.7 of the PIC24 Family document. To make a simple PWM signal use the ''%%MCCP%%'' module in output compare with **Dual Edge Mode**. The **Dual Edge Mode** allows us to reset the ''%%OC%%'' (output compare) pin, set the pulse width and along with the 16 bit timer length. We use dual edge buffered ''%%MCCP1%%'' mode to generate our PWM signal. The buffered part is that so that we can update the PWM values while the PWM is running, and the peripheral takes care of loading the next values at the end of a cycle. ===== SPI ===== I learned a lot about SPI in the LTP Lidar project because it didn't work right off the bat. It is not that complicated and the easy setup in MCC (MPLAB Code Configurator) gives you all the stuff you need. You just use the ''%%MSSP1_SPI_Exchange8bit(address)%%'' function to read and write data. Some notes: * Make sure you have the SPI mode selected correctly!! * Always break out the SPI bus SCK, MISO, MOSI and SS pins to probe test points [[https://datasheet.octopart.com/5117-Keystone-datasheet-15716159.pdf|link]] in new designs. ===== UART ===== To use the UART you can set it up on the the MCC (MPLAB Code Configurator). Check the box that diverts ''%%printf%%'' to the UART. This allows us to use ''%%printf%%'' which can print out strings and is easier to use than the one byte function we get from the configurator. To use ''%%printf%%'' we need to ''%%#include %%'' Read about the xc16 ''%%printf%%'' implmementation [[http://microchip.wikidot.com/tls2101:printf|link]]. To use the MCC generated ''%%UARTx_GetStatus()%%'' function you have to ''%%AND%%'' the enum! They are flags and not unique values. So tricky!!! The PIC24F only has a 4 byte serial buffer. Getting the pic to do a serial read requires me to get out of my comfort zone and work with interrupts. I need to set up an interrupt every time there is a byte and add it to my running buffer. This really shouldn't be that hard and should make the code work pretty easily. I need to set the ''%%URXISEL<1:0>%%'' to ''%%00%%'' which will generate an interrupt whenever there is 1 or more characters in the buffer. There is information about the UART in both the PIC24F Family Reference manual and also the PIC24FV16KM204 Family Reference Manual [[https://www.digikey.com/eewiki/display/microcontroller/Microchip+PIC+Family+Reference+Manuals+-+Compiled|link]]. This is all forcing me to learn about interrupt functions. Reading about it in Chapter 7 of the C30 Compiler User's Guide [[http://ww1.microchip.com/downloads/en/devicedoc/c30_users_guide_51284f.pdf|link]]. I think I can use a macro for the UART Rx interrupt. See Section 8.3.4 in the Interrupts manual [[http://ww1.microchip.com/downloads/en/devicedoc/39707a.pdf|link]]. Im trying to find the correct preproccessor macro for the ISR of the UARTRx interrupt. In doing so, I read this in the C Compiler Manual: If an interrupt handler does not require any of the optional parameters of the interrupt attribute, then a simplified syntax may be used. The following macros are defined in the device-specific header files: I found out I can just use the autogenerated UART handler instead of writing my own ISR. Which may be worse than writing my own ISR because there is a lot of bullshit with it.