工具/软件:Code Composer Studio
大家好、我正在使用 cc430f5137 假体与 MS5803-01BA 压力传感器进行 I2C 通信。
我用一些示例构建了一个代码、我有 erro #10234-D
我认为我的代码出了点问题、但我找不到问题所在。
这是代码。
如果有人知道问题、请为我回复:)
#include "MS5803.h"
#include
#include
#include
#include "General.h"
//全局变量
uint16_t sensorCoeff[8];// MS5803校准系数的数组
uint8_t HighByte = 0;// MS5803数据读取占位符
uint8_t MidByte = 0;// MS5803数据读取占位符
uint8_t LowByte = 0;// MS5803数据读取占位符
//主文件中定义的失效防护标志
//extern uint8_t no_timeout;
//extern uint8_t 传感器;
uint8_t SHT_WAIT = 0;
uint8_t MS5803_WAIT = 0;
uint8_t failsafe = 0;
///---------------------------------------------------------
// MS5803_coeff ()
//
//函数读取出厂校准系数并进行存储
//放入 sensorCoeff[]数组
///---------------------------------------------------------
void MS5803_coeff (void){
unsigned int c;
//重置传感器
//启用具有半秒超时的看门狗计时器
WDTCTL = WDTPW | WDTCNTCL | WDTIS1 | WDTIS0;
I2Ctx (MS5803_ADDRESS、MS5803_RESET);
//禁用看门狗计时器
WDTCTL = WDTPW | WDTHOLD;
延迟(1000);
对于(c = 0;c < 8;c++){
//发送读取系数命令
I2Ctx (MS5803_ADDRESS、(MS5803_PROM 读取_BASE +(c * 2)));
//接收两个字节
//启用具有半秒超时的看门狗计时器
WDTCTL = WDTPW | WDTCNTCL | WDTIS1 | WDTIS0;
//清除接收模式的 UCTR
UCB0CTL1 &=~0x10;
//将 UCTXSTT 置位以发送从器件地址和读取位
UCB0CTL1 |= 0x02;
//读取第一个字节
//等待 RXBUF 被填满
while (((UCB0IFG & 0x01)=0x00);
//复位活动的看门狗计时器
WDTCTL = WDTPW | WDTCNTCL | WDTIS1 | WDTIS0;
//从 RXBUF 读取值
高字节= UCB0RXBUF;
//读取第二个字节
//设置 STP 标志以发送 NACK 和 STOP
UCB0CTL1 |= 0x04;
//等待 RXBUF 被填满
while (((UCB0IFG & 0x01)=0x00);
//从 RXBUF 读取值
低字节= UCB0RXBUF;
//禁用看门狗计时器
WDTCTL = WDTPW | WDTHOLD;
sensorCoeff[c]=(无符号整型)高字节<<8)+低字节;
}
uint8_t p_crc = sensorCoeff[7]和0x000F;
uint8_t n_CRC = MS5803_CRC (sensorCoeff);
if (p_crc!= n_crc){
WDTCTL = 10;//复位微控制器
}
}
///---------------------------------------------------------
// MS5803_CRC()
//
//对 MS5803系数执行 CRC 校验的函数
//如果发现错误,程序将因故障而停止
//将进行通信和计算
///---------------------------------------------------------
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]));
对于(cnt = 0;cnt < 16;cnt++){
if (cnt%2 = 1){
n_rem ^=(无符号短整型)((n_prom[cnt>>1])& 0x00FF);
}
否则{
n_rem ^=(无符号短整型)(n_prom[cnt>1]>8);
}
对于(n_bit = 8;n_bit > 0;n_bit--){
if (n_rem &(0x8000)){
n_rem =(n_rem <1)^ 0x3000;
}
否则{
n_rem =(n_rem <1);
}
}
}
n_rem =(0x000F &(n_rem >>12));
n_prom[7]= CRC_READ;
返回(n_rem ^ 0x00);
}
///---------------------------------------------------------
// MS5803_READ_DATA ()
//
//函数从 MS5803传感器读取3个字节的数据
//数据作为参数返回以用于计算
///---------------------------------------------------------
unsigned long MS5803_read_data (void){
长整型结果= 0;
//发送命令来读取 MS5803 ADC
I2Ctx (MS5803_ADDRESS、MS5803_ADC_READ);
延迟(10);
if (no_timeout){
//接收3个字节
//启用超时计时器中断-0.5秒
TA0CCR2 = TA0R + 16384;
TA0CCTL2 = CCIE;
_bis_SR_register (GIE);
//清除接收模式的 UCTR
UCB0CTL1 &=~0x10;
//将 UCTXSTT 置位以发送从器件地址和读取位
UCB0CTL1 |= 0x02;
//读取第一个字节
//等待 RXBUF 被填满
while ((((UCB0IFG & 0x01)=0x00)&& NO_TIMEOUT);
if (no_timeout){
//从 RXBUF 读取值
高字节= UCB0RXBUF;
//读取第二个字节
//等待 RXBUF 被填满
while ((((UCB0IFG & 0x01)=0x00)&& NO_TIMEOUT);
if (no_timeout){
//从 RXBUF 读取值
中间字节= UCB0RXBUF;
//设置 STP 标志以发送 NACK 和 STOP
UCB0CTL1 |= 0x04;
//等待 RXBUF 被填满
while ((((UCB0IFG & 0x01)=0x00)&& NO_TIMEOUT);
if (no_timeout){
//从 RXBUF 读取第三个字节
低字节= UCB0RXBUF;
}
}
}
}
//禁用超时计时器
TA0CCTL2 = 0;
_BIC_SR_register (GIE);
//解析传感器数据
结果=((长)高字节<< 16)+((长)中字节<< 8)+(长)低字节;
返回结果;
}
///---------------------------------------------------------
// MS5803_calc ()
//使用计算温度和压力的函数
//校准系数和测量数据。
//首先计算温度值并将其用作参数
//校准压力计算
///---------------------------------------------------------
void MS5803_calc (uint32_t d1、uint32_t d2、float Array[]){
//局部变量
int32_t dT = 0;
int32_t TEMP = 0;
int64_t 偏移= 0;
int64_t 灵敏度= 0;
int64_t t2 = 0;
int64_t OFF2 = 0;
int64_t Sens2 = 0;
int32_t mbarInt = 0;
//计算一阶温度,dT 为一个长有符号整数
dt =(int32_t) d2 -((int32_t) sensorCoeff[5]* 256);//(int32_t)(((uint32_t) d2 -((uint32_t) sensorCoeff[5]* 256UL);
//使用整数除法来计算 TEMP
temp = 2000 +((int64_t) dT * sensorCoeff [6])/ 8388608LL;// 2000 +(int64_t)(((int64_t) dT *(uint64_t) sensorCoeff [6])/ 8388608LL);
temp =(int32_t) TEMP;
//二阶温度补偿
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;
}
否则{
T2 = 0;
OFF2 = 0;
Sens2 = 0;
if (TEMP > 4500){
Sens2 = Sens2 -((TEMP - 4500)*(TEMP - 4500))/ 8;
}
}
//在极低温度下进行额外补偿
if (TEMP <-2500){
Sens2 = Sens2 + 2 *((TEMP + 1500)*(TEMP + 1500));
}
//计算初始偏移和灵敏度
偏移=(int64_t) sensorCoeff [2]* 65536 +(sensorCoeff [4]*(int64_t) dT)/128;//(int64_t)(((uint64_t) sensorCoeff [2]* 65536ULL +(((uint64_t) sensorCoeff *)))/t (int64_t)) t)
灵敏度=(int64_t) sensorCoeff [1]* 32768 +(sensorCoeff [3]*(int64_t) dT)/256;//灵敏度=(int64_t)(((uint64_t) sensorCoeff [1]* 32768ULL +(((uint64_t) sensorCoeff))*/t (int64_t))))/int64_t)/t
//根据上面的二阶校正调整 TEMP、Offset、Sensitivity 值
温度=温度- T2;
偏移=偏移- OFF2;
灵敏度=灵敏度- Sens2;
//最终计算
MbarInt =((D1 *灵敏度)/ 2097152 -偏移量)/ 32768;//mbarInt =(int32_t)(((((uint64_t) D1 *灵敏度)/ 2097152LL -偏移量)/ 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){
//写入访问代码以访问端口映射寄存器
PMAPKEYID = 0x02D52;
//将端口映射到辅助功能
P1MAP3 = PM_UCB0SDA;//将 P1.3设置为 SDA
P1MAP2 = PM_UCB.S;//将 P1.2设置为 SCL
P1SEL |= 0x6C;//启用 P1.2、P1.3、P1.5、P1.6
//将所有其它引脚设置为输出模式、低电平以最大限度地降低功耗
P1DIR |= 0x93;//除 P1.2、3、5、6之外的所有
}
void Timer_init(){
//确保禁用计时器
TA1CTL &=~(MC0 | MC1);
//TA1CTL |= TASSEL1;//将时钟源设置为 SMCLK (1.048576MHz)
//TA1CTL |= ID1 | ID2;//将预分频器设置为/8
TA1CTL |= TASSEL1 | ID1 | ID0;
TA1EX0 |= TAIDEX1 | TAIDEX0;//将预分频器设置为4
//清除计数器以重置逻辑
TA1CTL |= TACLR;
//启用向上计数模式中的计数
TA1CTL |= MC1;
针对32kHz 的//计时器 A0设置(与上面一样)
//TA0CTL &=~(MC0 | MC1);
TA0CTL |= TASSEL1 | ID1 | ID0 | MC1;
TA0EX0 |= TAIDEX1 | TAIDEX0;
TA0CTL |= TACLR;
//启用 CCR1上的中断
TA0CCR1 = 65535;
TA0CCTL1 = CCIE;
}
void I2C_init (void){
//将 UCSWRST 位置位来复位 USCI 模块
UCB0CTL1 |= 0x01;
//配置控制寄存器
//CC430系列用户指南中的表24-3和24-4
//UCB0CTL0 &=~0x80;//自身地址设置为7位
//UCB0CTL0 &=~0x40;//从地址长度设置为7位
//UCB0CTL0 &=~0x20;//单主器件环境
//UCB0CTL0 |= 0x08;//选择主控模式
//UCB0CTL0 |= 0x06;选择//I2C 模式(11)
//UCB0CTL0 |= 0x01;//选择同步模式
UCB0CTL0 |= 0x0F;//这两行全部完成
UCB0CTL0 &=~0xE0;//两条指令中的设置
//定义时钟预分频器
// UCBR0 =(UCB0BR0 + 256 * UCB0BR1)
// f (bit_clock)= f (BR_clock)/UCBR0
UCB0CTL1 |= 0xC0;//为 BRCLK 源选择 SMCLK (1.048576MHz)
UCB0BR1 = 0;//将 UCBR0设置为10以实现
UCB0BR0 = 10;//位频率为100kHz
//定义主地址
UCB0I2COA &&~0x83FF;//禁用常规调用响应
UCB0I2COA |= 0x003A;//将 I2C 地址设置为0x3A
//清除 UCSWRST 以为模块加电
UCB0CTL1 &=~0x01;
}