CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

MPL3115A2 not working with PIC16F877A

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kufre



Joined: 19 Oct 2013
Posts: 7
Location: Nigeria

View user's profile Send private message

MPL3115A2 not working with PIC16F877A
PostPosted: Thu Dec 12, 2013 7:37 pm     Reply with quote

Hi Guys!

I have a new MPL3115A2 Temperature/Pressure/Altitude breakout board from Sparkfun as part of my school project. The sensor is a two wire serial (I2C) device. Am interested in reading only the Pressure.
I've connected the SDA and SCL on the breakout board to the SDA and SCL pins of the PIC16F877A respectively. The sensor is powered with +3.3vcc and the PIC is +5vcc both of them has common Gnd.

I have run the diagnostic test @ http://www.ccsinfo.com/forum/viewtopic.php?t=49713 and receive 0xC0 as the slave address.

The issue is when all of them are powered on, I'll get MSB:FF CSB: FF LSB: FF which shouldn't be so. The combination of the MSB, CSB, LSB should give me the pressure reading.

Also, from the datasheet, when reading the "WHO_AM_I" register (0x0C), the device should response with 0xC4, but what am getting is still 0xFF.

Here is the code, am using CCS C v4.068



Code:


#include <16F877A.h>
#FUSES NOWDT                     
#FUSES HS 
#FUSES BROWNOUT               
#FUSES NOLVP, PUT


#use delay(clock=20000000)
// i2c preprocessor directives
#use i2c(Master, sda=PIN_C4,scl=PIN_C3, FORCE_HW, SMBUS)
#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=UART, ERRORS,BRGH1OK)


#define OUT_P_MSB 0x01
#define WHO_AM_I 0x0C
#define PT_DATA_CFG 0x13
#define CTRL_REG1 0x26
#define F_SETUP    0x0F
#define MPL3115A2_ADDRESS 0xC0 //0x60  7-bit I2C address  0xC0  8-bit I2C address

BYTE IIC_Read(BYTE regAddr);
void IIC_Write(byte regAddr, byte value);
void MPL3115A2_request(void);
void toggleOneShot(void);
void readPressure(void);
void setModeBarometer(void);
void enableEventFlags(void);


BYTE IIC_Read(BYTE regAddr)
{
   BYTE re;
   // This function reads one byte over IIC
   i2c_start();
   i2c_write(MPL3115A2_ADDRESS); 
   i2c_write(regAddr);  // Address of CTRL_REG1     
   re=i2c_read(0);
   i2c_stop(); 
   return  re;
}

void IIC_Write(BYTE regAddr, BYTE value)
{
// This function writes one byto over IIC
   i2c_start();
   i2c_write(MPL3115A2_ADDRESS);
   i2c_write(regAddr);   
   i2c_write(value);
   i2c_stop();
}

/* send a measurement request. in ~40ms issue a data request */
void MPL3115A2_request(void)
{
   BYTE re;
   fprintf(UART, "Request..\r\n");     
   re = IIC_Read(WHO_AM_I); 
    fprintf(UART, "WHO_AM_I: %X\r\n",re);
}

   //Clears then sets the OST bit which causes the sensor to immediately take another reading
   //Needed to sample faster than 1Hz
 void toggleOneShot(void)
{
   BYTE tempSetting;
   tempSetting = IIC_Read(CTRL_REG1);   //Read current settings
   tempSetting &= ~(1<<1); //Clear OST bit
   IIC_Write(CTRL_REG1, tempSetting);
   tempSetting = IIC_Read(CTRL_REG1); //Read current settings to be safe
   tempSetting |= (1<<1); //Set OST bit
   IIC_Write(CTRL_REG1, tempSetting);
}

   //Reads the current pressure in Pa
   //Unit must be set in barometric pressure mode
void readPressure(void)
{
   BYTE msb, csb, lsb;
   toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
   delay_ms(10);
   // start i2c communication
   i2c_start();
   // Read pressure registers
   i2c_write(MPL3115A2_ADDRESS);
   i2c_write(OUT_P_MSB); // Address of data to get   
   msb = i2c_read(1);
   csb = i2c_read(1);
   lsb = i2c_read(0);
   fprintf(UART, "msb :%X csb: %X lsb: %X\r\n", msb, csb, lsb);
}

   //Sets the mode to Barometer
   //CTRL_REG1, ALT bit
void setModeBarometer(void)
{
   BYTE tempSetting;
   tempSetting = IIC_Read(CTRL_REG1); //Read current settings
   tempSetting &= ~(1<<7); //Clear ALT bit
   IIC_Write(CTRL_REG1, tempSetting);
}

   //Call with a rate from 0 to 7.
   //Sets the over sample rate. Datasheet calls for 128 but you can set it
   //from 1 to 128 samples. The higher the oversample rate the greater
   //the time between data samples.
void setOversampleRate(BYTE sampleRate)
{
   BYTE tempSetting;
   if(sampleRate > 7) sampleRate = 7; //OS cannot be larger than 0b.0111
   sampleRate <<= 3; //Align it for the CTRL_REG1 register
   tempSetting = IIC_Read(CTRL_REG1); //Read current settings
   tempSetting &= 0b11000111; //Clear out old OS bits
   tempSetting |= sampleRate; //Mask in new OS bits
   IIC_Write(CTRL_REG1, tempSetting);
}

   //Enables the pressure and temp measurement event flags so that we can
   //test against them. This is recommended in datasheet during setup.
void enableEventFlags(void)
{
   IIC_Write(PT_DATA_CFG, 0x07); // Enable all three pressure and temp event flags

}


void main(void)
{   
   delay_ms(1000);     
   fprintf(UART, "Reading Start....\r\n");
    MPL3115A2_request();
    // Configure the sensor
      setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa     
      setOversampleRate(7); // Set Oversample to the recommended 128     
      enableEventFlags(); // Enable all three pressure and temp event flags 
      delay_ms(20);       
   while(1) {                         
      readPressure();         
      delay_ms(3000);
   }
}




Result:

Quote:

Reading Start....
Request..
WHO_AM_I: FF
msb :FF csb: FF lsb: FF
msb :FF csb: FF lsb: FF
msb :FF csb: FF lsb: FF
msb :FF csb: FF lsb: FF
msb :FF csb: FF lsb: FF
msb :FF csb: FF lsb: FF
msb :FF csb: FF lsb: FF
msb :FF csb: FF lsb: FF
msb :FF csb: FF lsb: FF


Is anything wrong with the code or is there anything am missing out? Pls I need your help.
Thanks
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Dec 12, 2013 8:18 pm     Reply with quote

comment: you need correct hardware before debugging software..

comment: It is never a good idea to mix 5V PICs with 3V peripherals. Best solution is to use 3V PICS with 3V peripherals. Next is to use a 5V to 3V logic level translation chips in between. Next would be to use I/O pins that WILL allow the PIC to see proper logic levels.Check the datasheet to see which pins would see a '1' when input is 3.3volts( homework for you).

comment: the 16F877 is 'obsolete' or at least 'at end of production life',if possible, choose a current PIC of the LF series( good for 3V) that is pin compatible.Newer PICs will have more features at a lower price.

comment: check the comments at the sparkfun website about the device,seems there's a lot of talk about it...maybe Google for PIC related info.

comment:in the I2C setup options you have SMBUS enabled, is this correct? what speed is the I2C bus(device max is 400KHz)?

hth
jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 12, 2013 10:04 pm     Reply with quote

He's using the SMBUS option for #use i2c. With that parameter, a 5v
PIC will work with a 3.3v i2c slave (with 3.3v pull-ups).

One of the problems is in the IIC_Read() function. It should be replaced by this:
Code:

BYTE IIC_Read(BYTE regAddr)
{
BYTE re;

i2c_start();
i2c_write(MPL3115A2_ADDRESS); 
i2c_write(regAddr);       
i2c_start();
i2c_write(MPL3115A2_ADDRESS +1); 
re=i2c_read(0);
i2c_stop(); 
return  re;
}
kufre



Joined: 19 Oct 2013
Posts: 7
Location: Nigeria

View user's profile Send private message

MPL3115A2 not working with PIC16F877A
PostPosted: Sat Dec 14, 2013 6:47 am     Reply with quote

Thanks PCM Programmer for your help!

I did exactly as your code and its working now.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group