Hi,
I am trying to read temperature and pressure from Bosch BMP085 device. I have writtern a code ( given below) but the problem is that I can not get right values for both temperature and pressure.
My problems are that when I calibarate data ( using step into fuction) I am not receiving expected values of register. Could anyone look into my code and advice me what is wrong with the code.
It also kept receiving the value and save in the RXbuffer, even though I dont want to.
#include
"msp430x22x4.h"
//#define NUM_BYTES_TX 1 // How many bytes? //#define NUM_BYTES_RX 24 // Set to two to read one byte from the slave volatile
unsigned char NUM_BYTES_TX = 1;
// How many bytes?
volatile
unsigned char NUM_BYTES_RX = 24;
// Set to two to read one byte from the slave
int
RXByteCtr, RPT_Flag = 0;
// enables repeated start when 1
volatile
unsigned char RxBuffer[24];
// Allocate 24 byte of RAM
volatile
unsigned char RxBufferIndex = 0;
// Sets the location where the received data is stored
unsigned
char *PTxData;
// Pointer to TX data
unsigned
char *PRxData;
// Pointer to RX data
unsigned
char TXByteCtr, RX = 0;
unsigned
char MSData = 0xAA;
unsigned
char address = 0;
unsigned
char data = 0;
const
unsigned char oversampling_setting=3;
// oversampling for measurement
const
unsigned char pressure_converstiontime[4]= {0,1,2,3} ;
// delays for oversampling settings 0,1,2 and 3
//unsigned char UTdata = 0x2E;
// sensor registers from BOSCH BMP085
short
ac1=0;
short
ac2=0;
short
ac3=0;
unsigned short
ac4=0;
unsigned short
ac5=0;
unsigned short
ac6=0;
short
b1=0;
short
b2=0;
short
mb=0;
short
mc=0;
short
md=0;
// Variable to keep the values
int
temperature = 0;
long
pressure = 0;
// Prototypes
void
Setup_TX(void
);
void
Setup_RX(void
);
void
Transmit(void
);
void
Receive(void
);
void
calibraitonData(void
);
void
writeRegister(unsigned char address, unsigned char
data);
int
readIntRegister(unsigned char
address);
unsigned
char readRegister(unsigned char
address);
unsigned
int
readUT();
long
readUP();
void
readSensor();
void
main(void
)
{ WDTCTL = WDTPW + WDTHOLD;
// Stop WDT
P3SEL |= 0x06;
// Assign I2C pins to USCI_B0
//while(1)
// {
calibraitonData();
//writeRegister(address, data);
//readIntRegister(address);
// readRegister(address);
// readIntRegister(UT);
readSensor();
//}
}
//-------------------------------------------------------------------------------
// The USCI_B0 data ISR is used to move received data from the I2C slave
// to the MSP430 memory. It is structured such that it can be used to receive
// any 2+ number of bytes by pre-loading RXByteCtr with the byte count.
//-------------------------------------------------------------------------------
#pragma
vector = USCIAB0TX_VECTOR
__interrupt
void USCIAB0TX_ISR(void
)
{
if(RX == 1){
// Master Recieve?
RXByteCtr--;
// Decrement RX byte counter
if
(RXByteCtr)
{ *PRxData++ = UCB0RXBUF;
// Move RX data to address PRxData
}
else
{
if
(RPT_Flag == 0)
UCB0CTL1 |= UCTXSTP;
// No Repeated Start: stop condition
if(RPT_Flag == 1){
// if Repeated Start: do nothing
RPT_Flag = 0;
}
*PRxData = UCB0RXBUF;
// Move final RX data to PRxData
__bic_SR_register_on_exit(CPUOFF);
// Exit LPM0
}}
else{
// Master Transmit
if (TXByteCtr)
// Check TX byte counter
{
UCB0TXBUF = MSData++;
// Load TX buffer
TXByteCtr--;
// Decrement TX byte counter
}
else
{
if
(RPT_Flag == 1){
RPT_Flag = 0; PTxData = &MSData;
// TX array start address
TXByteCtr = NUM_BYTES_TX;
// Load TX byte counter
__bic_SR_register_on_exit(CPUOFF);
}
else
{
UCB0CTL1 |= UCTXSTP;
// I2C stop condition
IFG2 &= ~UCB0TXIFG;
// Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF);
// Exit LPM0
}
}
}
}
void
Setup_TX(void
){
_DINT(); RX = 0; IE2 &= ~UCB0RXIE;
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent// Disable RX interrupt
UCB0CTL1 |= UCSWRST;
// Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;
// I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST;
// Use SMCLK, keep SW reset
UCB0BR0 = 12;
// fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x77;
// Slave Address is 048h
UCB0CTL1 &= ~UCSWRST;
// Clear SW reset, resume operation
IE2 |= UCB0TXIE;
// Enable TX interrupt
}
void
Setup_RX(void
){
_DINT(); RX = 1; IE2 &= ~UCB0TXIE; UCB0CTL1 |= UCSWRST;
// Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;
// I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST;
// Use SMCLK, keep SW reset
UCB0BR0 = 12;
// fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x77;
// Slave Address is 048h
UCB0CTL1 &= ~UCSWRST;
// Clear SW reset, resume operation
IE2 |= UCB0RXIE;
// Enable RX interrupt
}
void
Transmit(void
){
PTxData = &MSData;
// TX array start address
TXByteCtr = NUM_BYTES_TX;
// Load TX byte counter
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent
UCB0CTL1 |= UCTR + UCTXSTT;
// I2C TX, start condition
__bis_SR_register(CPUOFF + GIE);
// Enter LPM0 w/ interrupts
}
void
Receive(void
){
PRxData = (
unsigned char *)RxBuffer;
// Start of RX buffer
RXByteCtr = NUM_BYTES_RX-1;
// Load RX byte counter
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT;
// I2C start condition
__bis_SR_register(CPUOFF + GIE);
// Enter LPM0 w/ interrupts
}
// get calibration data.....
void
calibraitonData(void
)
{
//Transmit process
Setup_TX();
RPT_Flag = 0;
Transmit();
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent
//Receive process
Setup_RX();
Receive();
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent
ac1 = (
short
) RxBuffer[0]<<8 | RxBuffer[1];
ac2 = (
short
) RxBuffer[2]<<8 | RxBuffer[3];
ac3 = (
short
) RxBuffer[4]<<8 | RxBuffer[5];
ac4 = (
unsigned short
) RxBuffer[6]<<8 | RxBuffer[7];
ac5 = (
unsigned short
) RxBuffer[8]<<8 | RxBuffer[9];
ac6 = (
unsigned short
) RxBuffer[10]<<8 | RxBuffer[11];
b1 = (
short
) RxBuffer[12]<<8 | RxBuffer[13];
b2 = (
short
) RxBuffer[14]<<8 | RxBuffer[15];
mb = (
short
) RxBuffer[16]<<8 | RxBuffer[17];
mc = (
short
) RxBuffer[18]<<8 | RxBuffer[19];
md = (
short
) RxBuffer[20]<<8 | RxBuffer[21];
}
// write 0x2E into reg 0xF4, wait 4.5ms
void
writeRegister(unsigned char address, unsigned char
data)
{ NUM_BYTES_TX = 1; MSData = address; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
MSData = data; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
}
// read register 0xF6 (MSB) , 0xF7 (LSB) ---> 16 bit
int
readIntRegister(unsigned char
address)
{ NUM_BYTES_RX = 5; MSData = address; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
Setup_RX(); Receive();
while
(UCB0CTL1 & UCTXSTP);
return (RxBuffer[0]) <<8 | (int
)(RxBuffer[1]);
}
//
// read an 8 bit register
unsigned
char readRegister(unsigned char
address)
{ NUM_BYTES_RX= 5; MSData = address; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
Setup_RX(); Receive();
while
(UCB0CTL1 & UCTXSTP);
return
RxBuffer[0];
}
// read uncompensated temperature value
unsigned
int
readUT()
{ writeRegister(0xF4,0x2E); __delay_cycles(54022);
// wait of 4.5ms
return
readIntRegister(0xF6);
}
// read uncompensated pressure value
long
readUP()
{ writeRegister(0xF4,0x34+(oversampling_setting<<6));
//_delay_cycles(pressure_converstiontime[oversampling_setting]);
NUM_BYTES_RX = 5;
MSData = address;
Setup_TX();
RPT_Flag = 0;
Transmit();
while
(UCB0CTL1 & UCTXSTP);
Setup_RX(); Receive();
while
(UCB0CTL1 & UCTXSTP);
//return (RxBuffer[0]) <<8 | (int)(RxBuffer[1]);
return (((long)RxBuffer[0] <<16) | ((long)RxBuffer[1]<<8) | ((long
)RxBuffer[2])) >> (8-oversampling_setting);
// unsigned char *msb,*lsb,*xlsb;
// Setup_TX();
// unsigned char address = 0xF6;
// Transmit();
//
// Setup_RX();
// msb = PRxData;
// Receive();
// lsb = PRxData;
// Receive();
// xlsb = PRxData;
// Receive();
//
// return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >> (8-oversampling_setting);
}
// utility functions to get data from the sensor
// read temperature and pressure from sensor
void
readSensor()
{
long
ut=readUT();
long
up = readUP();
long
x1,x2,x3,b3,b5,b6,p;
unsigned long
b4,b7;
//calculate true temperature
x1 = ((
long
)ut - ac6) * ac5 >> 15;
x2 = ((
long
) mc << 11) / (x1 + md);
b5 = x1 + x2; temperature = (b5 + 8) >> 4;
//calculate true pressure
b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;
b3 = ((ac1 * 4 + x3)<<oversampling_setting + 2) >> 2;
x1 = ac3 * b6 >> 13;
x2 = (b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (
unsigned long
) (x3 + 32768)) >> 15;
b7 = ((
unsigned long
) up - b3) * (50000 >> oversampling_setting);
#include
"msp430x22x4.h"
//#define NUM_BYTES_TX 1 // How many bytes? //#define NUM_BYTES_RX 24 // Set to two to read one byte from the slave
volatile
unsigned char NUM_BYTES_TX = 1;
// How many bytes?
volatile
unsigned char NUM_BYTES_RX = 24;
// Set to two to read one byte from the slave
int
RXByteCtr, RPT_Flag = 0;
// enables repeated start when 1
volatile
unsigned char RxBuffer[24];
// Allocate 24 byte of RAM
volatile
unsigned char RxBufferIndex = 0;
// Sets the location where the received data is stored
unsigned
char *PTxData;
// Pointer to TX data
unsigned
char *PRxData;
// Pointer to RX data
unsigned
char
TXByteCtr, RX = 0;
unsigned
char
MSData = 0xAA;
unsigned
char
address = 0;
unsigned
char
data = 0;
const
unsigned char oversampling_setting=3;
// oversampling for measurement
const
unsigned char pressure_converstiontime[4]= {0,1,2,3} ;
// delays for oversampling settings 0,1,2 and 3
//unsigned char UTdata = 0x2E;
// sensor registers from BOSCH BMP085
short
ac1=0;
short
ac2=0;
short
ac3=0;
unsigned short
ac4=0;
unsigned short
ac5=0;
unsigned short
ac6=0;
short
b1=0;
short
b2=0;
short
mb=0;
short
mc=0;
short
md=0;
// Variable to keep the values
int
temperature = 0;
long
pressure = 0;
// Prototypes void
Setup_TX(void
);
void
Setup_RX(void
);
void
Transmit(void
);
void
Receive(void
);
void
calibraitonData(void
);
void
writeRegister(unsigned char address, unsigned char
data);
int
readIntRegister(unsigned char
address);
unsigned
char readRegister(unsigned char
address);
unsigned
int
readUT();
long
readUP();
void
readSensor();
void
main(void
)
{ WDTCTL = WDTPW + WDTHOLD;
// Stop WDT
P3SEL |= 0x06;
// Assign I2C pins to USCI_B0
//while(1)
// {
calibraitonData();
//writeRegister(address, data);
//readIntRegister(address);
// readRegister(address);
// readIntRegister(UT);
readSensor();
//}
} //------------------------------------------------------------------------------- // The USCI_B0 data ISR is used to move received data from the I2C slave // to the MSP430 memory. It is structured such that it can be used to receive // any 2+ number of bytes by pre-loading RXByteCtr with the byte count. //------------------------------------------------------------------------------- #pragma
vector = USCIAB0TX_VECTOR
__interrupt
void USCIAB0TX_ISR(void
)
{
if(RX == 1){
// Master Recieve?
RXByteCtr--;
// Decrement RX byte counter
if
(RXByteCtr)
{ *PRxData++ = UCB0RXBUF;
// Move RX data to address PRxData
}
else
{
if
(RPT_Flag == 0)
UCB0CTL1 |= UCTXSTP;
// No Repeated Start: stop condition
if(RPT_Flag == 1){
// if Repeated Start: do nothing
RPT_Flag = 0; } *PRxData = UCB0RXBUF;
// Move final RX data to PRxData
__bic_SR_register_on_exit(CPUOFF);
// Exit LPM0
}}
else{
// Master Transmit
if (TXByteCtr)
// Check TX byte counter
{ UCB0TXBUF = MSData++;
// Load TX buffer
TXByteCtr--;
// Decrement TX byte counter
}
else
{
if
(RPT_Flag == 1){
RPT_Flag = 0; PTxData = &MSData;
// TX array start address
TXByteCtr = NUM_BYTES_TX;
// Load TX byte counter
__bic_SR_register_on_exit(CPUOFF); }
else
{
UCB0CTL1 |= UCTXSTP;
// I2C stop condition
IFG2 &= ~UCB0TXIFG;
// Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF);
// Exit LPM0
} } } } void
Setup_TX(void
){
_DINT(); RX = 0; IE2 &= ~UCB0RXIE;
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent// Disable RX interrupt
UCB0CTL1 |= UCSWRST;
// Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;
// I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST;
// Use SMCLK, keep SW reset
UCB0BR0 = 12;
// fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0; UCB0I2CSA = 0x77;
// Slave Address is 048h
UCB0CTL1 &= ~UCSWRST;
// Clear SW reset, resume operation
IE2 |= UCB0TXIE;
// Enable TX interrupt
} void
Setup_RX(void
){
_DINT(); RX = 1; IE2 &= ~UCB0TXIE; UCB0CTL1 |= UCSWRST;
// Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;
// I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST;
// Use SMCLK, keep SW reset
UCB0BR0 = 12;
// fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0; UCB0I2CSA = 0x77;
// Slave Address is 048h
UCB0CTL1 &= ~UCSWRST;
// Clear SW reset, resume operation
IE2 |= UCB0RXIE;
// Enable RX interrupt
} void
Transmit(void
){
PTxData = &MSData;
// TX array start address
TXByteCtr = NUM_BYTES_TX;
// Load TX byte counter
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent
UCB0CTL1 |= UCTR + UCTXSTT;
// I2C TX, start condition
__bis_SR_register(CPUOFF + GIE);
// Enter LPM0 w/ interrupts
} void
Receive(void
){
PRxData = (
unsigned char *)RxBuffer;
// Start of RX buffer
RXByteCtr = NUM_BYTES_RX-1;
// Load RX byte counter
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT;
// I2C start condition
__bis_SR_register(CPUOFF + GIE);
// Enter LPM0 w/ interrupts
} // get calibration data..... void
calibraitonData(void
)
{
//Transmit process
Setup_TX(); RPT_Flag = 0; Transmit();
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent
//Receive process
Setup_RX(); Receive();
while (UCB0CTL1 & UCTXSTP);
// Ensure stop condition got sent
ac1 = (
short
) RxBuffer[0]<<8 | RxBuffer[1];
ac2 = (
short
) RxBuffer[2]<<8 | RxBuffer[3];
ac3 = (
short
) RxBuffer[4]<<8 | RxBuffer[5];
ac4 = (
unsigned short
) RxBuffer[6]<<8 | RxBuffer[7];
ac5 = (
unsigned short
) RxBuffer[8]<<8 | RxBuffer[9];
ac6 = (
unsigned short
) RxBuffer[10]<<8 | RxBuffer[11];
b1 = (
short
) RxBuffer[12]<<8 | RxBuffer[13];
b2 = (
short
) RxBuffer[14]<<8 | RxBuffer[15];
mb = (
short
) RxBuffer[16]<<8 | RxBuffer[17];
mc = (
short
) RxBuffer[18]<<8 | RxBuffer[19];
md = (
short
) RxBuffer[20]<<8 | RxBuffer[21];
}
// write 0x2E into reg 0xF4, wait 4.5ms void
writeRegister(unsigned char address, unsigned char
data)
{ NUM_BYTES_TX = 1; MSData = address; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
MSData = data; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
}
// read register 0xF6 (MSB) , 0xF7 (LSB) ---> 16 bit int
readIntRegister(unsigned char
address)
{ NUM_BYTES_RX = 5; MSData = address; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
Setup_RX(); Receive();
while
(UCB0CTL1 & UCTXSTP);
return (RxBuffer[0]) <<8 | (int
)(RxBuffer[1]);
}
// // read an 8 bit register unsigned
char readRegister(unsigned char
address)
{ NUM_BYTES_RX= 5; MSData = address; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
Setup_RX(); Receive();
while
(UCB0CTL1 & UCTXSTP);
return
RxBuffer[0];
}
// read uncompensated temperature value unsigned
int
readUT()
{ writeRegister(0xF4,0x2E); __delay_cycles(54022);
// wait of 4.5ms
return
readIntRegister(0xF6);
}
// read uncompensated pressure value long
readUP()
{ writeRegister(0xF4,0x34+(oversampling_setting<<6));
//_delay_cycles(pressure_converstiontime[oversampling_setting]);
NUM_BYTES_RX = 5; MSData = address; Setup_TX(); RPT_Flag = 0; Transmit();
while
(UCB0CTL1 & UCTXSTP);
Setup_RX(); Receive();
while
(UCB0CTL1 & UCTXSTP);
//return (RxBuffer[0]) <<8 | (int)(RxBuffer[1]);
return (((long)RxBuffer[0] <<16) | ((long)RxBuffer[1]<<8) | ((long
)RxBuffer[2])) >> (8-oversampling_setting);
// unsigned char *msb,*lsb,*xlsb; // Setup_TX(); // unsigned char address = 0xF6; // Transmit(); // // Setup_RX(); // msb = PRxData; // Receive(); // lsb = PRxData; // Receive(); // xlsb = PRxData; // Receive(); // // return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >> (8-oversampling_setting); } // utility functions to get data from the sensor // read temperature and pressure from sensor void
readSensor()
{
long
ut=readUT();
long
up = readUP();
long
x1,x2,x3,b3,b5,b6,p;
unsigned long
b4,b7;
//calculate true temperature
x1 = ((
long)ut - ac6) * ac5 >> 15;
x2 = ((
long) mc << 11) / (x1 + md);
b5 = x1 + x2; temperature = (b5 + 8) >> 4;
//calculate true pressure
b6 = b5 - 4000; x1 = (b2 * (b6 * b6 >> 12)) >> 11; x2 = ac2 * b6 >> 11; x3 = x1 + x2; b3 = ((ac1 * 4 + x3)<<oversampling_setting + 2) >> 2; x1 = ac3 * b6 >> 13; x2 = (b1 * (b6 * b6 >> 12)) >> 16; x3 = ((x1 + x2) + 2) >> 2; b4 = (ac4 * (
unsigned long (x3 + 32768)) >> 15;
b7 = ((
unsigned long) up - b3) * (50000 >> oversampling_setting);