I am trying to setup a PIC24FJ64GB002 for UART communication in MBLAB using XC16. I am using the USB CDC demo to communicate with a device, and I am trying to relay that information to an arduino using the PIC. I am confused as to what frequency the cpu is running at. I am using an external 8 MHZ crystal, with several bits set in the demo. Bits relating to the oscillator are set here.
#include <p24FJ64GB002.h>
#include "system.h"
#include "usb.h"
/** CONFIGURATION Bits **********************************************/
_CONFIG1(
WDTPS_PS1 &
FWPSA_PR32 &
WINDIS_OFF &
FWDTEN_OFF &
ICS_PGx1 &
GWRP_OFF &
GCP_OFF &
JTAGEN_OFF
)
_CONFIG2(
POSCMOD_HS &
I2C1SEL_PRI &
IOL1WAY_OFF &
OSCIOFNC_ON &
FCKSM_CSDCMD &
FNOSC_PRIPLL &
PLL96MHZ_ON &
PLLDIV_DIV2 &
IESO_OFF
)
_CONFIG3(
WPFP_WPFP0 &
SOSCSEL_SOSC &
WUTSEL_LEG &
WPDIS_WPDIS &
WPCFG_WPCFGDIS &
WPEND_WPENDMEM
)
_CONFIG4(
DSWDTPS_DSWDTPS3 &
DSWDTOSC_LPRC &
RTCOSC_SOSC &
DSBOREN_OFF &
DSWDTEN_OFF
)
/*********************************************************************
* Function: void SYSTEM_Initialize( SYSTEM_STATE state )
*
* Overview: Initializes the system.
*
* PreCondition: None
*
* Input: SYSTEM_STATE - the state to initialize the system into
*
* Output: None
*
********************************************************************/
void SYSTEM_Initialize( SYSTEM_STATE state )
{
//On the PIC24FJ64GB004 Family of USB microcontrollers, the PLL will not power up and be enabled
//by default, even if a PLL enabled oscillator configuration is selected (such as HS+PLL).
//This allows the device to power up at a lower initial operating frequency, which can be
//advantageous when powered from a source which is not gauranteed to be adequate for 32MHz
//operation. On these devices, user firmware needs to manually set the CLKDIV<PLLEN> bit to
//power up the PLL.
{
unsigned int pll_startup_counter = 600;
CLKDIVbits.PLLEN = 1;
while(pll_startup_counter--);
}
switch(state)
{
case SYSTEM_STATE_USB_HOST:
PRINT_SetConfiguration(PRINT_CONFIGURATION_LCD);
break;
case SYSTEM_STATE_USB_HOST_CDC_BASIC:
BUTTON_Enable(BUTTON_USB_HOST_CDC_BASIC);
PRINT_SetConfiguration(PRINT_CONFIGURATION_LCD);
break;
}
}
I then use this function to initialize the UART
void UART_INIT()
{
AD1PCFGL = 0xFFFF;
__builtin_write_OSCCONL(OSCCON & 0xbf);
TRISBbits.TRISB15 = 0;
__builtin_write_OSCCONL(OSCCON | 0x40);
RPOR7bits.RP15R = 3;
U1BRG = 103; //set baud speed
U1MODE = 0x8000; //turn on module
U1STA = 0x8400; //set interrupts
IEC0bits.U1TXIE = 0;
IFS0bits.U1RXIF = 0;
IFS0bits.U1TXIF = 0;
}
And this function to transmit a byte
void send(char c)
{
while(U1STAbits.UTXBF == 1);
U1TXREG = c;
}
I am trying to figure out what value FCY should be defined to be. I assumed that it would be 16 MHZ, (96MHz / 3) / 2 but the code did not work at that setting. Could there be another problem in the code?
I am making all pins digital and setting the UART pin as an input with this code
__builtin_write_OSCCONL(OSCCON & 0xbf);
AD1PCFGL = 0xFFFF;
TRISBbits.TRISB15 = 0;
UART_INIT(9600);
__builtin_write_OSCCONL(OSCCON | 0x40);
Finally, I use the functions like this
UART_INIT(9600);
while(1)
{
send('H');
send('e');
send('l');
send('l');
send('o');
send(' ');
send('W');
send('o');
send('r');
send('l');
send('d');
send('\n');
}
Best Answer
A diagram would help convey what you're doing. I think this is what you have implemented:
"a device" (USB device) <-> USB <-> PIC24FJ64BG002 (USB host) <-> UART <-> Arduino
Let's take a look at the clock options for this part:
Let's also look more closely at the USB-specific clock stuff:
CONFIG2 contains your oscillator-related stuff:
Recapping what we know:
Also, from the datasheet:
So, what's our conclusion? I would say that unless there's other code messing with the bits somewhere, the situation is as is shown in figure 8.2 - HSPLL is running at 32 MHz (96 MHz USB PLL output, divided by three, then divided by one).
And, because we know that
\$ F_{CY} = \dfrac {F_{OSC}}{2} \$
the answer should be 16 MHz.
Now, to your baud rate formula:
(It's bad practice to have the same variable name on both sides of the equation: the left side should be renamed to BRG or something more like what it is - it's the baud rate generator value, not the baud rate itself.)
If you look up the PIC24 Family Reference Manual for UART, you'll find the values pre-computed for you:
By default, BRGH is zero so unless code is messing with it, your baud rate generator should be set to 103 decimal. (Your formula is for BRGH - 0 and with a 16 MHz clock rate agrees with this table.)
I would dare a guess and say that your UART issues, if they persist, aren't clock related...