Search code examples
picpic32

programming PIC32MX250F128B with Pickit3


I am successfully programming PIC32MX250F128B using Pickit3. I have written a code where, when I press a I am getting 100 data from vibration sensor. Now if I want to get another 100 data, either I have to disconnect and then reconnect the 10k ohm pull up resistor connected to MCLR pin or have to run the program again.

Is there any other way I can reset the pickit?

Here is the code I am using:

#include <p32xxxx.h>                // include chip specific header file
#include <plib.h>                   // include peripheral library functions

// Configuration Bits
#pragma config FNOSC = FRCPLL       // Internal Fast RC oscillator (8 MHz) w/ PLL
#pragma config FPLLIDIV = DIV_2     // Divide FRC before PLL (now 4 MHz)
#pragma config FPLLMUL = MUL_20     // PLL Multiply (now 80 MHz)
#pragma config FPLLODIV = DIV_2     // Divide After PLL (now 40 MHz)
                                    // see figure 8.1 in datasheet for more info
#pragma config FWDTEN = OFF         // Watchdog Timer Disabled
#pragma config ICESEL = ICS_PGx2    // ICE/ICD Comm Channel Select
#pragma config JTAGEN = OFF         // Disable JTAG
#pragma config FSOSCEN = OFF        // Disable Secondary Oscillator
#pragma config FPBDIV = DIV_1       // PBCLK = SYCLK

// Defines
#define SYSCLK 40000000L

// Macros
// Equation to set baud rate from UART reference manual equation 21-1
#define Baud2BRG(desired_baud)      ( (SYSCLK / (16*desired_baud))-1)

// Function Prototypes
int SerialTransmit(const char *buffer);
unsigned int SerialReceive(char *buffer); //, unsigned int max_size);
int UART2Configure( int baud);

short a2dvals[11000];
int adcptr,num_channels,k,i;
char sampling;
int ADC_RSLT0,totaldata,totaldata1,chunks_sent,data_count,l;
short temp;
BOOL a2don;
volatile unsigned int channel4;
void __ISR(_ADC_VECTOR, IPL2) TIMER3Handler(void) // Fonction d'interruption Timer 3
    {


        temp = ReadADC10(0);

        a2dvals[k] = (temp);
        k++;
        if (k>totaldata1)// && sampling == 's')
        {
            T3CONCLR = 0x8000;
            a2don=FALSE;
            chunks_sent = 0;
            totaldata = k/2;
            k = 1;

        }
     mAD1ClearIntFlag();
}

int main(void)
{
    char   buf[1024];       // declare receive buffer with max size 1024


    // Peripheral Pin Select
    U2RXRbits.U2RXR = 4;    //SET RX to RB8
    RPB9Rbits.RPB9R = 2;    //SET RB9 to TX

   SYSTEMConfigPerformance(SYSCLK);

    UART2Configure(9600);  // Configure UART2 for a baud rate of 9600
    U2MODESET = 0x8000;     // enable UART2

    ANSELBbits.ANSB2 = 1;   // set RB2 (AN4) to analog
    TRISBbits.TRISB2 = 1;   // set RB2 as an input

    //adcConfigureManual();   // Configure ADC
    //AD1CON1SET = 0x8000;    // Enable ADC


    SerialTransmit("Hello! Enter 'a' to do ADC conversion \r\n");

    unsigned int rx_size;

    while( 1){
        rx_size = SerialReceive(buf); //, 1024);     // wait here until data is received
        SerialTransmit(buf);                   // Send out data exactly as received


         SerialTransmit("\r\n");

    }



   return 1;
} // END main()

/* UART2Configure() sets up the UART2 for the most standard and minimal operation
 *  Enable TX and RX lines, 8 data bits, no parity, 1 stop bit, idle when HIGH
 * Input: Desired Baud Rate
 * Output: Actual Baud Rate from baud control register U2BRG after assignment*/
int UART2Configure( int desired_baud){

    U2MODE = 0;         // disable autobaud, TX and RX enabled only, 8N1, idle=HIGH
    U2STA = 0x1400;     // enable TX and RX
    U2BRG = Baud2BRG(desired_baud); // U2BRG = (FPb / (16*baud)) - 1

    // Calculate actual assigned baud rate
    int actual_baud = SYSCLK / (16 * (U2BRG+1));

    return actual_baud;
} // END UART2Configure()


/* SerialTransmit() transmits a string to the UART2 TX pin MSB first
 *
 * Inputs: *buffer = string to transmit */
int SerialTransmit(const char *buffer)
{
    unsigned int size = strlen(buffer);
    while( size)
    {
        while( U2STAbits.UTXBF);    // wait while TX buffer full
        U2TXREG = *buffer; // send single character to transmit buffer



        buffer++;                   // transmit next character on following loop
        size--;                     // loop until all characters sent (when size = 0)

    }

    while( !U2STAbits.TRMT);        // wait for last transmission to finish

    return 0;
}

/* SerialReceive() is a blocking function that waits for data on
 *  the UART2 RX buffer and then stores all incoming data into *buffer
 *
 * Note that when a carriage return '\r' is received, a nul character
 *  is appended signifying the strings end
 *
 * Inputs:  *buffer = Character array/pointer to store received data into
 *          max_size = number of bytes allocated to this pointer
 * Outputs: Number of characters received */
unsigned int SerialReceive(char *buffer) //, unsigned int max_size)
{
    //unsigned int num_char = 0;


    /* Wait for and store incoming data until either a carriage return is received
     *   or the number of received characters (num_chars) exceeds max_size */
    while(1)
    {
        while( !U2STAbits.URXDA);   // wait until data available in RX buffer
        *buffer = U2RXREG;  // empty contents of RX buffer into *buffer pointer



        if (*buffer == 'a')
        {

            int dummy,dummy1;
            unsigned char tempstr[5];


    SYSTEMConfig(SYSCLK, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

        // the ADC ///////////////////////////////////////
        // configure and enable the ADC
    CloseADC10();   // ensure the ADC is off before setting the configuration

    // define setup parameters for OpenADC10
    // Turn module on | ouput in integer | trigger mode auto | enable autosample
        // ADC_CLK_AUTO -- Internal counter ends sampling and starts conversion (Auto convert)
        // ADC_AUTO_SAMPLING_ON -- Sampling begins immediately after last conversion completes; SAMP bit is automatically set
        // ADC_AUTO_SAMPLING_OFF -- Sampling begins with AcquireADC10();
        #define PARAM1  ADC_MODULE_ON|ADC_FORMAT_INTG32 | ADC_CLK_TMR | ADC_AUTO_SAMPLING_ON //

    // define setup parameters for OpenADC10
    // ADC ref external  | disable offset test | disable scan mode | do 1 sample | use single buf | alternate mode off
    #define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF
        //
    // Define setup parameters for OpenADC10
        // use peripherial bus clock | set sample time | set ADC clock divider
        // ADC_CONV_CLK_Tcy2 means divide CLK_PB by 2 (max speed)
        // ADC_SAMPLE_TIME_5 seems to work with a source resistance < 1kohm
        #define PARAM3 ADC_CONV_CLK_SYSTEM | ADC_SAMPLE_TIME_5 | ADC_CONV_CLK_Tcy2 //ADC_SAMPLE_TIME_15| ADC_CONV_CLK_Tcy2

    // define setup parameters for OpenADC10
    // set AN4 and  as analog inputs
    #define PARAM4  ENABLE_AN4_ANA 

    // define setup parameters for OpenADC10
    // do not assign channels to scan
    #define PARAM5  SKIP_SCAN_ALL

    // use ground as neg ref for A | use AN4 for input A     
    // configure to sample AN4 
    SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN4 ); // configure to sample AN4 
    OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using the parameters defined above

    ConfigIntADC10(ADC_INT_PRI_2 | ADC_INT_ON);


    EnableADC10(); // Enable the ADC

       INTEnableSystemMultiVectoredInt();

    OpenTimer3(T3_OFF | T3_SOURCE_INT | T3_PS_1_1 ,0x3e8);

    num_channels = 1;
    totaldata1 = 10500;
    a2don=TRUE;
    T3CONSET = 0x8000;
    k=0;
    while(1)
    {       
        while(a2don);

        for(i=0;i<100;i++)
        {
            dummy = a2dvals[i]/1000 ;
            tempstr[0] = dummy + 0x30;
            dummy1 = a2dvals[i]- dummy*1000;
            dummy = dummy1/100;
            tempstr[1] = dummy + 0x30;
            dummy1 = dummy1 - dummy*100;
            dummy = dummy1/10;
            tempstr[2] = dummy + 0x30;
            dummy1 = dummy1 - dummy*10;
            tempstr[3] = dummy1 + 0x30;
            //tempstr[4] = "\0";

            printf("%c%c%c%c \n", tempstr[0],tempstr[1],tempstr[2],tempstr[3]);
        }
        a2don=TRUE;   
    }

        }

    }

    return 1;
}// END SerialReceive()

enter image description here

Thanks for your advices.


Solution

  • You use while(1) loops everywhere, and if you don't use a break; or return command you stay in that loop forever. I think you don't need while(1) loops in the functions except in main(). Remove these and it should work.

    Try drawing out your program flow in a flow chart, it should clear things up. Also consider using a state machine using switch/case. It makes it a lot clearer where you are in the code and it's easier to debug. Also, it's probably even better to use interrupts for adc and the serial port. You free up the pic to do other stuff while peripherals are doing stuff that takes time.