Problems whilst using MPLAB's MCC to configure and use I2C and ADC

Thread Starter

aamir_sheikh

Joined Nov 19, 2013
15
I am trying to communicate to BQ24259 through I2C using PIC16LF1554. The 7th register of the device has a bit which can be used to turn off the battery. I used Mplab's MCC to configure the I2C settings. Using the example code in header files i wrote a similar function.

here is the relevant snippet of the code

Code:
#define RETRY_MAX       100
    #define ON              0x4B   //register 7 toggle 5th bit to turn ON/OFF
    #define OFF             0x6B
    I2C_MESSAGE_STATUS status;

    uint16_t        timeOut;
    uint8_t         writeBuffer[1];                // writeBuffer[0] = 07, writeBuffer[1] = data 01001011b(on) 01101011b(off)
    uint8_t         stat;
    uint16_t        address = (0x6B/2) ;           //Bit shifting to the write, and having '0' for write opertaoin, at MSB

uint8_t bat_fet(uint8_t val){
    writeBuffer[0] = 7;                      //slave's seventh register
    writeBuffer[1] = val;
    timeOut=0;
    while(status != I2C_MESSAGE_FAIL){
        I2C_MasterWrite( writeBuffer,        // address of data to be sent
                         2,                  // number of data bytes
                         address,            // address of the peripheral
                         &status);           // address of status register

        while(status == I2C_MESSAGE_PENDING);

        if(status == I2C_MESSAGE_COMPLETE){
            return 1;
            break;
        }
        if(timeOut == RETRY_MAX){
            return 0;

            break;
        }
        else
            timeOut++;
    }
    if(status == I2C_MESSAGE_FAIL)
        return 0;

}
but its not working, nothing happens, sometimes the controller just freezes, mostly it continues to work. I have connected an LED to an unused IO pin, and programmed it to turn on whenever the function returns 1, and it turns on. But the battery remains on too.

Similarly, i am trying to use ADC 1 of the pic to check the battery voltage,

here is the code,

Code:
uint16_t check_bat_voltage(){

    uint16_t bat_v;

    ADC1_StartConversion(01011); //i am using Channel AN11, but no matter what variation of channel and AN11 i passed, it just wouldn't recognize. so i just pass the 5 bit values of the ADCON1 register.

    while(ADC1_IsConversionDone());

    bat_v = ADC1_GetConversionResult(); 

//digital value = [analog voltage / (vref+ - vref-)] * 1024
//analog value minimum = 2.5/2, voltage divider network
//vref+ 5
//vref- 0
// 1.25/5 * 1024 = 256
    return bat_v;
}
but again nothing happens. Can anyone please review it? I am just stuck. Thanks.

I can attach screen shots of MCC too, maybe i didnot configure the peripherals right.

P.S. i do initialize both modules in main().
 

spinnaker

Joined Oct 29, 2009
7,830
People might not have access to MCC for you chip or might not want to set it up.

I think you should tackle one issue at a time. The ADC issue probably the easiest.

What does ADC1_StartConversion(01011); do?

What does the code look like for ADC1_GetConversionResult?

Share your code where you initialize the ports. Again just stick with ADC for now.


And post your schematic.
 

Thread Starter

aamir_sheikh

Joined Nov 19, 2013
15
People might not have access to MCC for you chip or might not want to set it up.

I think you should tackle one issue at a time. The ADC issue probably the easiest.

What does ADC1_StartConversion(01011); do?

What does the code look like for ADC1_GetConversionResult?

Share your code where you initialize the ports. Again just stick with ADC for now.


And post your schematic.
don't have schematic's Softcopy. but its not the issue, trust me. there is 1.35 volts appearing on the pin, through the voltage divider, and i have used a 100nf cap in parallel with the pin to the ground.

in ADC1_StartConversion() a five bit value is passed, i think a new data type was defined. i tried passing the channel name, but the compiler gave an error.

initialization is done by mcc, i can add adc.c, and adc.h files, which are auto generated. in which functions are defined, and registers are updated.

Last time i checked, i was trying to use this code to check if ADC results are correct

Code:
 bat_vol= check_bat_voltage();
             if (bat_vol > 400){
                 dled_Toggle();
                 __delay_ms(600);
                 dled_Toggle();
                 __delay_ms(600);
                 dled_Toggle();
                 __delay_ms(600);
                 dled_Toggle();
according to my calculations it shouldnt have blinked, but it did (there was 1.35 volts on the pin, 1.35/5 - 1024 = 276), so so i dont know whats going on now.

I'm new at this, please be patient with me.
 

Attachments

Last edited:

spinnaker

Joined Oct 29, 2009
7,830
You need a schematic. That is a requirement around here and a small price for all of the wonderful help that you get.


One thing I saw. Do you want to pass a decimal value to ADC1_StartConversion? That is what you are doing here: ADC1_StartConversion(01011); The number looks like you might want it to be binary. If you want to represent a binary number preceed it with 0b DC1_StartConversion(0b01011);
 

Thread Starter

aamir_sheikh

Joined Nov 19, 2013
15
Where is your code that sets up the ADC pin as an analog input?
i attached screenshot to my previous post, also here is pin manager. c, auto generated by mcc


C:
#include <xc.h>
#include "pin_manager.h"
#include "stdbool.h"



void PIN_MANAGER_Initialize(void)
{
    /**
    LATx registers
    */ 
    LATA = 0x00;  
    LATC = 0x00;  

    /**
    TRISx registers
    */  
    TRISA = 0x1F;
    TRISC = 0x33;

    /**
    ANSELx registers
    */ 
    ANSELC = 0x14;
    ANSELA = 0x13;

    /**
    WPUx registers
    */
    WPUA = 0x1F;
    OPTION_REGbits.nWPUEN = 0;

  
    /**
    APFCONx registers
    */
    APFCON = 0x00;


 
  
}     

void PIN_MANAGER_IOC(void)
{ 

}

/**
End of File
*/
 

spinnaker

Joined Oct 29, 2009
7,830
That is a good start. Now please post you schematic. I like Diptrace. Very easy to use with a short learning curve.


Did you check the possible binary notation issue I mentioned?
 

Nakkiran

Joined Mar 15, 2017
1
I am trying to communicate to BQ24259 through I2C using PIC16LF1554. The 7th register of the device has a bit which can be used to turn off the battery. I used Mplab's MCC to configure the I2C settings. Using the example code in header files i wrote a similar function.

here is the relevant snippet of the code

Code:
#define RETRY_MAX       100
    #define ON              0x4B   //register 7 toggle 5th bit to turn ON/OFF
    #define OFF             0x6B
    I2C_MESSAGE_STATUS status;

    uint16_t        timeOut;
    uint8_t         writeBuffer[1];                // writeBuffer[0] = 07, writeBuffer[1] = data 01001011b(on) 01101011b(off)
    uint8_t         stat;
    uint16_t        address = (0x6B/2) ;           //Bit shifting to the write, and having '0' for write opertaoin, at MSB

uint8_t bat_fet(uint8_t val){
    writeBuffer[0] = 7;                      //slave's seventh register
    writeBuffer[1] = val;
    timeOut=0;
    while(status != I2C_MESSAGE_FAIL){
        I2C_MasterWrite( writeBuffer,        // address of data to be sent
                         2,                  // number of data bytes
                         address,            // address of the peripheral
                         &status);           // address of status register

        while(status == I2C_MESSAGE_PENDING);

        if(status == I2C_MESSAGE_COMPLETE){
            return 1;
            break;
        }
        if(timeOut == RETRY_MAX){
            return 0;

            break;
        }
        else
            timeOut++;
    }
    if(status == I2C_MESSAGE_FAIL)
        return 0;

}
but its not working, nothing happens, sometimes the controller just freezes, mostly it continues to work. I have connected an LED to an unused IO pin, and programmed it to turn on whenever the function returns 1, and it turns on. But the battery remains on too.

Similarly, i am trying to use ADC 1 of the pic to check the battery voltage,

here is the code,

Code:
uint16_t check_bat_voltage(){

    uint16_t bat_v;

    ADC1_StartConversion(01011); //i am using Channel AN11, but no matter what variation of channel and AN11 i passed, it just wouldn't recognize. so i just pass the 5 bit values of the ADCON1 register.

    while(ADC1_IsConversionDone());

    bat_v = ADC1_GetConversionResult();

//digital value = [analog voltage / (vref+ - vref-)] * 1024
//analog value minimum = 2.5/2, voltage divider network
//vref+ 5
//vref- 0
// 1.25/5 * 1024 = 256
    return bat_v;
}
but again nothing happens. Can anyone please review it? I am just stuck. Thanks.

I can attach screen shots of MCC too, maybe i didnot configure the peripherals right.

P.S. i do initialize both modules in main().
here
make writeBuffer initlize like this writeBuffer[] or writeBuffer[2]
and the share your code..
what this function call does ? I2C_MasterWrite()
and also need your I2C connection diagram..
 

be80be

Joined Jul 5, 2008
2,394
Your using MMC you have to initialize In main the i2c and the adc.
When you set it up you picked a pin you use the adc like this.

bat_v = ADC_GetConversion(AN3); // ANX would be what pin used I used AN3

You would then test it the i2c is a little harder.
Have a look at the mmc genrated files.
You really would have to post a zip of your whole project.
 
Top