MSP430 I2C读取多字节通信问题
我正在尝试使用MSP430F249的温度传感器(PCT2075) 为了得到一个温度,我从这个传感器得到一个2字节的信号 我从这个链接写了一段代码 我用的是MSP430F249。所以我修改了这个链接中的一个代码 然而,我只得到了两个相同的值。我想是的 有没有办法从传感器获取2字节的数据 我的代码在这里MSP430 I2C读取多字节通信问题,c,i2c,msp430,C,I2c,Msp430,我正在尝试使用MSP430F249的温度传感器(PCT2075) 为了得到一个温度,我从这个传感器得到一个2字节的信号 我从这个链接写了一段代码 我用的是MSP430F249。所以我修改了这个链接中的一个代码 然而,我只得到了两个相同的值。我想是的 有没有办法从传感器获取2字节的数据 我的代码在这里 void i2c_read_multi(uint8_t slv_addr, uint8_t reg_addr, uint8_t l, uint8_t *arr) { uint8_t i;
void i2c_read_multi(uint8_t slv_addr, uint8_t reg_addr, uint8_t l, uint8_t *arr)
{
uint8_t i;
while(UCB0STAT & UCBBUSY);
UCB0I2CSA = slv_addr; // set slave address
UCB0CTL1 |= UCTR | UCTXSTT; // transmitter mode and START condition.
while(UCB0CTL1 & UCTXSTT);
UCB0TXBUF = reg_addr;
while(!(UCB0CTL1 & UCTXSTT));
UCB0CTL1 &= ~UCTR; // receiver mode
UCB0CTL1 |= UCTXSTT; // START condition
while(UCB0CTL1 & UCTXSTT); // make sure start has been cleared
for (i = 0; i < l; i++) {
while(!(IFG2 & UCB0RXIFG));
if(i == l - 1){
UCB0CTL1 |= UCTXSTP; // STOP condition
}
arr[i] = UCB0RXBUF;
}
while(UCB0CTL1 & UCTXSTP);
}
void i2c_read_multi(uint8_t slv_addr,uint8_t reg_addr,uint8_t l,uint8_t*arr)
{
uint8_t i;
while(UCB0STAT和UCBBUSY);
UCB0I2CSA=slv_addr;//设置从机地址
UCB0CTL1 |=UCTR | UCTXSTT;//变送器模式和启动条件。
while(UCB0CTL1&UCTXSTT);
UCB0TXBUF=注册地址;
而(!(UCB0CTL1&UCTXSTT));
UCB0CTL1&=~UCTR;//接收器模式
UCB0CTL1 |=UCTXSTT;//启动条件
while(UCB0CTL1&UCTXSTT);//确保已清除启动
对于(i=0;i
有两个问题
链接到的代码假定端口只需要为每个输出值读取一个字节
但是,根据您展示的传感器文档,对于数组的每个值输出,我们需要读取两个字节(一个用于MSB,一个用于LSB)
我们需要将这两个字节的值合并成一个16位的值。请注意,arr
现在是uint16\u t
,而不是uint8\u t
。现在,l
是[16位]采样数(与字节数相比)。因此,可能需要相应地调整此调用方
此外,请注意,我们必须“忽略”lsb的低5位。我们通过将16位值右移5位来实现这一点(例如,val16>>=5
)。我想这是正确的方法。或者,它可能只是val16&=~0x1F
[不太可能]。你可能需要做一点实验
下面是重构后的代码
注意,这假设数据以“大端”顺序到达[基于我的最佳猜测]。如果它实际上是little endian,则反转msb=
和lsb=
语句
此外,可能需要调整“停止”条件代码的位置。我不得不猜测它是否应该放在LSB读取或MSB读取之上
我选择了LSB——最后一个字节,因为它最接近于链接的通用i2c读取的方式。(即)i2c不知道或不关心有关设备的MSB/LSB多路复用。它希望在最后一个字节[而不是16位样本]之前停止
void
i2c读多(uint8\u t slv\u地址、uint8\u t注册地址、uint8\u t l、,
uint16_t*arr)
{
uint8_t i;
uint8_t msb;
uint8_t lsb;
uint16_t val16;
while(UCB0STAT和UCBBUSY);
//设置从机地址
UCB0I2CSA=slv\u地址;
//变送器模式和启动条件。
UCB0CTL1 |=UCTR | UCTXSTT;
while(UCB0CTL1&UCTXSTT);
UCB0TXBUF=注册地址;
而(!(UCB0CTL1&UCTXSTT));
//接收机模式
UCB0CTL1&=~UCTR;
//启动条件
UCB0CTL1 |=UCTXSTT;
//确保已清除“开始”
while(UCB0CTL1&UCTXSTT);
对于(i=0;i
谢谢你的帮助。它工作得很好。我实现了如何从I2C中获取多个字节。
void
i2c_read_multi(uint8_t slv_addr, uint8_t reg_addr, uint8_t l,
uint16_t *arr)
{
uint8_t i;
uint8_t msb;
uint8_t lsb;
uint16_t val16;
while (UCB0STAT & UCBBUSY);
// set slave address
UCB0I2CSA = slv_addr;
// transmitter mode and START condition.
UCB0CTL1 |= UCTR | UCTXSTT;
while (UCB0CTL1 & UCTXSTT);
UCB0TXBUF = reg_addr;
while (!(UCB0CTL1 & UCTXSTT));
// receiver mode
UCB0CTL1 &= ~UCTR;
// START condition
UCB0CTL1 |= UCTXSTT;
// make sure start has been cleared
while (UCB0CTL1 & UCTXSTT);
for (i = 0; i < l; i++) {
while (!(IFG2 & UCB0RXIFG));
msb = UCB0RXBUF;
while (!(IFG2 & UCB0RXIFG));
// STOP condition
if (i == l - 1) {
UCB0CTL1 |= UCTXSTP;
}
lsb = UCB0RXBUF;
val16 = msb;
val16 <<= 8;
val16 |= lsb;
// use only most 11 significant bits
// NOTE: this _may_ not be the correct way to scale the data
val16 >>= 5;
arr[i] = val16;
}
while (UCB0CTL1 & UCTXSTP);
}