Tool/software: Code Composer Studio
Hi, Im working on an I2C communication with MS5803-01BA pressure sensor using cc430f5137 prossesor.
I constructed a code with some examples, and I has erro #10234-D
I think I did something wrong with the code, but I can't find what the problem is.
here is the code.
If anyone knows the problem, reply for me please:)
#include "MS5803.h"
#include <cc430f5137.h>
#include <stdint.h>
#include <stdio.h>
#include "General.h"
//global variables
uint16_t sensorCoeff[8]; //array for MS5803 calilbration coefficients
uint8_t HighByte = 0; //placeholder for MS5803 data reads
uint8_t MidByte = 0; //placeholder for MS5803 data reads
uint8_t LowByte = 0; //placeholder for MS5803 data reads
//failsafe flags defined in main file
//extern uint8_t no_timeout;
//extern uint8_t sensor ;
uint8_t SHT_wait = 0;
uint8_t MS5803_wait = 0;
uint8_t failsafe = 0;
//-----------------------------------------------------------------------
// MS5803_coeff()
//
// function to read factory calibration coefficients and store
// into sensorCoeff[] array
//-----------------------------------------------------------------------
void MS5803_coeff(void) {
unsigned int c;
//reset sensor
//enable watchdog timer with half-second timeout
WDTCTL = WDTPW | WDTCNTCL | WDTIS1 | WDTIS0;
I2Ctx(MS5803_ADDRESS, MS5803_RESET);
//disable watchdog timer
WDTCTL = WDTPW | WDTHOLD;
delay(1000);
for(c = 0; c < 8; c++) {
//transmit read coefficient command
I2Ctx(MS5803_ADDRESS, (MS5803_PROM_READ_BASE + (c * 2)));
//receive two bytes
//enable watchdog timer with half-second timeout
WDTCTL = WDTPW | WDTCNTCL | WDTIS1 | WDTIS0;
//clear UCTR for receive mode
UCB0CTL1 &= ~0x10;
//set UCTXSTT to send slave address and READ bit
UCB0CTL1 |= 0x02;
//read first byte
//wait for RXBUF to be filled
while((UCB0IFG & 0x01) == 0x00);
//reset active watchdog timer
WDTCTL = WDTPW | WDTCNTCL | WDTIS1 | WDTIS0;
//read value from RXBUF
HighByte = UCB0RXBUF;
//read second byte
//set STP flag to send NACK and STOP
UCB0CTL1 |= 0x04;
//wait for RXBUF to be filled
while((UCB0IFG & 0x01) == 0x00);
//read value from RXBUF
LowByte = UCB0RXBUF;
//disable watchdog timer
WDTCTL = WDTPW | WDTHOLD;
sensorCoeff[c] = ((unsigned int)HighByte <<8) + LowByte;
}
uint8_t p_crc = sensorCoeff[7] & 0x000F;
uint8_t n_crc = MS5803_CRC(sensorCoeff);
if(p_crc != n_crc) {
WDTCTL = 10; //reset microcontroller
}
}
//-----------------------------------------------------------------------
// MS5803_CRC()
//
// function to perform CRC check on MS5803 coefficients
// if error is found, the program will be halted as faulty
// communications and calculations will take place
//-----------------------------------------------------------------------
uint8_t MS5803_CRC(uint16_t n_prom[]) {
unsigned int cnt;
unsigned int n_rem;
unsigned int crc_read;
unsigned char n_bit;
n_rem = 0x00;
crc_read = n_prom[7];
sensorCoeff[7] = (0xFF00 & (n_prom[7]));
for(cnt = 0; cnt < 16; cnt++) {
if(cnt%2 == 1) {
n_rem ^= (unsigned short)((n_prom[cnt>>1]) & 0x00FF);
}
else {
n_rem ^= (unsigned short)(n_prom[cnt>>1] >> 8);
}
for(n_bit = 8; n_bit > 0; n_bit--) {
if(n_rem & (0x8000)) {
n_rem = (n_rem <<1) ^ 0x3000;
}
else {
n_rem = (n_rem <<1);
}
}
}
n_rem = (0x000F & (n_rem >>12));
n_prom[7] = crc_read;
return (n_rem ^ 0x00);
}
//-----------------------------------------------------------------------
// MS5803_read_data()
//
// function to read in 3 bytes of data from MS5803 sensor
// data is returned as an argument for use in calculations
//-----------------------------------------------------------------------
unsigned long MS5803_read_data(void) {
long result = 0;
//transmit command to read the MS5803 ADC
I2Ctx(MS5803_ADDRESS, MS5803_ADC_READ);
delay(10);
if(no_timeout) {
//receive 3 bytes
//enable timeout timer interrupt - 0.5 sec
TA0CCR2 = TA0R + 16384;
TA0CCTL2 = CCIE;
__bis_SR_register(GIE);
//clear UCTR for receive mode
UCB0CTL1 &= ~0x10;
//set UCTXSTT to send slave address and READ bit
UCB0CTL1 |= 0x02;
//read first byte
//wait for RXBUF to be filled
while(((UCB0IFG & 0x01) == 0x00) && no_timeout);
if(no_timeout) {
//read value from RXBUF
HighByte = UCB0RXBUF;
//read second byte
//wait for RXBUF to be filled
while(((UCB0IFG & 0x01) == 0x00) && no_timeout);
if(no_timeout) {
//read value from RXBUF
MidByte = UCB0RXBUF;
//set STP flag to send NACK and STOP
UCB0CTL1 |= 0x04;
//wait for RXBUF to be filled
while(((UCB0IFG & 0x01) == 0x00) && no_timeout);
if(no_timeout) {
//read third byte from RXBUF
LowByte = UCB0RXBUF;
}
}
}
}
//disable timeout timer
TA0CCTL2 = 0;
__bic_SR_register(GIE);
//parse sensor data
result = ((long)HighByte << 16) + ((long)MidByte << 8) + (long) LowByte;
return result;
}
//-----------------------------------------------------------------------
// MS5803_calc()
// function for the calculation of temperature and pressure with
// calibration coefficients and measured data.
// temperature values are calculated first and used as parameters
// to calibrate the pressure calculation
//-----------------------------------------------------------------------
void MS5803_calc(uint32_t D1, uint32_t D2, float Array[]) {
//local variables
int32_t dT = 0;
int32_t TEMP = 0;
int64_t Offset = 0;
int64_t Sensitivity = 0;
int64_t T2 = 0;
int64_t OFF2 = 0;
int64_t Sens2 = 0;
int32_t mbarInt = 0;
//calculate 1st order temperature, dT as a long signed integer
dT = (int32_t)D2 - ( (int32_t)sensorCoeff[5] * 256 ); //(int32_t)((uint32_t)D2 - ( (uint32_t)sensorCoeff[5] * 256UL ));
//use integer division to calculate TEMP
TEMP = 2000 + ((int64_t)dT * sensorCoeff[6]) / 8388608LL; // 2000 + (int64_t)(((int64_t)dT * (uint64_t)sensorCoeff[6]) / 8388608LL);
TEMP = (int32_t)TEMP;
//2nd order temperature compensation
if( TEMP < 2000) {
T2 = ((int64_t)dT * dT) / 2147483648ULL; // ((int64_t)dT * (int64_t)dT) / 2147483648ULL;
T2 = (int32_t)T2;
OFF2 = 3*((TEMP - 2000) * (TEMP - 2000));
Sens2 = 7 * ((TEMP - 2000) * (TEMP - 2000)) / 8;
}
else {
T2 = 0;
OFF2 = 0;
Sens2 = 0;
if(TEMP > 4500) {
Sens2 = Sens2 - ((TEMP - 4500) * (TEMP - 4500)) / 8;
}
}
//additional compensation for very low temperature
if (TEMP < -2500) {
Sens2 = Sens2 + 2 * ((TEMP + 1500) * (TEMP + 1500));
}
//calculate initial Offset and Sensitivity
Offset = (int64_t)sensorCoeff[2] * 65536 + (sensorCoeff[4] * (int64_t)dT) / 128; // (int64_t)((uint64_t)sensorCoeff[2] * 65536ULL + ((uint64_t)sensorCoeff[4] * (int64_t)dT) / 128LL);
Sensitivity = (int64_t)sensorCoeff[1] * 32768 + (sensorCoeff[3] * (int64_t)dT) / 256; //Sensitivity = (int64_t)((uint64_t)sensorCoeff[1] * 32768ULL + ((uint64_t)sensorCoeff[3] * (int64_t)dT) / 256LL); //
//adjust TEMP, Offset, Sensitivity values based on 2nd order correction above
TEMP = TEMP - T2;
Offset = Offset - OFF2;
Sensitivity = Sensitivity - Sens2;
//final calculations
mbarInt = ((D1 * Sensitivity) / 2097152 - Offset) / 32768; //mbarInt = (int32_t)((((uint64_t)D1 * Sensitivity) / 2097152LL - Offset) / 32768LL);
Array[0] = (float)mbarInt / 100; //mbar
Array[1] = (float)TEMP / 100; //tempC
Array[2] = (Array[1] * 1.8) + 32; //tempF
}
void Pin_init(void) {
//write access code to access Port Map registers
PMAPKEYID = 0x02D52;
//map ports to secondary functions
P1MAP3 = PM_UCB0SDA; //set P1.3 as SDA
P1MAP2 = PM_UCB0SCL; //set P1.2 as SCL
P1SEL |= 0x6C; //enable P1.2, P1.3, P1.5, P1.6
//set all other pins to output mode, low to minimize power
P1DIR |= 0x93; //all but P1.2,3,5,6
}
void Timer_init() {
//ensure Timer is disabled
TA1CTL &= ~(MC0 | MC1);
//TA1CTL |= TASSEL1; //set clock source to SMCLK (1.048576 MHz)
//TA1CTL |= ID1 | ID2; //set prescaler to /8
TA1CTL |= TASSEL1 | ID1 | ID0;
TA1EX0 |= TAIDEX1 | TAIDEX0; //set prescaler to 4
//Clear counter to reset logic
TA1CTL |= TACLR;
//enable counting in up mode
TA1CTL |= MC1;
//Timer A0 setup for 32kHz (same as above)
//TA0CTL &= ~(MC0 | MC1);
TA0CTL |= TASSEL1 | ID1 | ID0 | MC1;
TA0EX0 |= TAIDEX1 | TAIDEX0;
TA0CTL |= TACLR;
//enable interrupts on CCR1
TA0CCR1 = 65535;
TA0CCTL1 = CCIE;
}
void I2C_init(void) {
//set UCSWRST bit to reset USCI module
UCB0CTL1 |= 0x01;
//configure Control registers
//Tables 24-3 and 24-4 in CC430 Family User Guide
//UCB0CTL0 &= ~0x80; //own address set to 7 bits
//UCB0CTL0 &= ~0x40; //slave address length set to 7 bits
//UCB0CTL0 &= ~0x20; //single master environment
//UCB0CTL0 |= 0x08; //master mode selected
//UCB0CTL0 |= 0x06; //I2C mode chosen (11)
//UCB0CTL0 |= 0x01; //Synchronous mode chosen
UCB0CTL0 |= 0x0F; //these two lines accomplish all
UCB0CTL0 &= ~0xE0; //of the setup in two instructions
//define clock prescaler
// UCBR0 = (UCB0BR0 + 256 * UCB0BR1)
// f(bit_clock) = f(BR_clock) / UCBR0
UCB0CTL1 |= 0xC0; //choose SMCLK for BRCLK source (1.048576 MHz)
UCB0BR1 = 0; //set UCBR0 to 10 to achieve
UCB0BR0 = 10; //bit frequency of 100 kHz
//define Master address
UCB0I2COA &= ~0x83FF; //disable General call response
UCB0I2COA |= 0x003A; //set I2C address to 0x3A
//clear UCSWRST to power up module
UCB0CTL1 &= ~0x01;
}