This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430F5438A:I2C 通信错误

Guru**** 2589300 points
Other Parts Discussed in Thread: MSP430F5438A

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/731185/msp430f5438a-i2c-communication-error

器件型号:MSP430F5438A

您好!

我正在尝试通过 I2C 协议与 MAX30101传感器通信。 这里、主设备是 MSP430F5438A、我的 IDE 是 Code Composer Studio。 我正在尝试从传感器获取我必须读取的样本数量。 我正在从头开始构建代码。 出于我的目的、我必须从传感器读取 WR_PTR 和 RD_PTR 数据。 我应该得到一个介于1到32之间的值、但我始终得到这两个值的0。  任何人都可以回答我的 I2C 代码部分是否正确? 如果不是、如何解决?  

以下是传感器的数据表(如有必要):

datasheets.maximintegrated.com/.../MAX30101.pdf

我的代码:

#include  
 #include
#include
 
#define MAX30101_I2C_ADDRESS     0x57
 
#define MAX30101_REG_INT_STS1    0x00
#define MAX30101_REG_INT_STS2    0x01
#define MAX30101_REG_INT_EN1     0x02
#define MAX30101_REG_INT_EN2     0x03
#define MAX30101_REG_FIFO_WR     0x04
#define MAX30101_REG_FIFO_OVF    0x05
#define MAX30101_REG_FIFO_RD     0x06
#define MAX30101_REG_FIFO_DATA   0x07
#define MAX30101_REG_FIFO_CFG    0x08
#define MAX30101_REG_MODE_CFG    0x09
#define MAX30101_REG_SPO2_CFG    0x0a
#define MAX30101_REG_LED1_PA     0x0C
#define MAX30101_REG_LED2_PA     0x0D
#define MAX30101_REG_LED3_PA     0x0E
#define MAX30101_REG_PILOT_PA    0x10
#define MAX30101_REG_MULTI_LED   0x11
#define MAX30101_REG_Tint       0x1f
#define MAX30101_REG_TFRAC      0x20
#define MAX30101_REG_TEMP_CFG    0x21
#define MAX30101_REG_PROX_INT    0x30
 
void Clock_setup();  //默认
void MAX30101_setup(); //传感器配置设置
void I2C_setup();  
void sendByte (char register_add、char data);
int readByte (char wr_add、char rd_add、char register_add);
void burstRead (char wr_add、char rd_add、char register_add、int no_ofsample);
void FIFO_CLEAR();
CHAR LED1 [96];
CHAR LED2 [96];
CHAR LED3 [96];
长 L1[32];
长 L2[32];
长 L3[32];
内部电源;
int rd;
INT NS; //可用样本数
 
void main()
  WDTCTL = WDTPW + WDTHOLD;
  clock_setup();
  I2C_setup();
  //_EINT();
  MAX30101_setup();
  while (1){
  //FIFO_CLEAR();
  WR= readByte (0xAE、0xAF、0x04); //读取 WR_PTR-->我不知道为什么要归零// 0xAE=传感器地址+写入模式,0xAF=传感器地址+读取模式,0x04=写入指针的地址
  RD= readByte (0xAE、0xAF、0x06); //读取 RD_PTR-->我不知道为什么要归零  // 0x06=读取指针的地址
  NS =电源;
  if (ns<0){
    Ns+=32;
      }

void Clock_setup(){
P11DIR |= BIT2;//检查 smclk、默认为1MHz
P11SEL |= BIT2;//检查 smclk,默认为1MHz
P11DIR |= BIT0;//检查 aclk、默认值为32.8KHz
P11SEL |= BIT0;//检查 aclk,默认值为32.8KHz


void I2C_setup(){

P3SEL |= BIT7;// P3.1 (UCB0_SDA)、P3.2 (UCB0_SCL)// 3.7 UCB1_SDA、5.4 UCB1_SCL
P5SEL |= BIT4;
UCB1CTL1 |= UCSWRST;//复位使能
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;//主器件+ I2C 模式+同步
UCB1CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK +仍然复位
UCB1BR0 = 10;//默认 SMCLK 1M/10 = 100KHz
UCB1BR1 = 0;//
UCB1I2CSA = MAX30101_I2C_ADDRESS;// MAX30101 7位地址0x57
UCB1CTL1 &=~UCSWRST;//复位清零
// UCB1IE |= UCTXIE + UCRXIE;//TX 和 RX 中断被启用

//发送单个字节
void sendByte (char register_add、char data){
 
   UCB1I2CSA = MAX30101_I2C_ADDRESS;              // MAX30101 7位地址0x57
   UCB1CTL1     |= UCTR + UCTXSTT;        // I2C 发送(写入)模式+生成起始条件
   UCB1TXBUF    =  REGISTER_ADD;         //寄存器地址以获取返回数据
   while (UCB1CTL1 & UCTXSTT);            //等待启动条件被清除
   while (!(UCB1IFG & UCTXIFG));           //等待寄存器地址被发送
   UCB1TXBUF    =      数据;             //将数据发送到寄存器
   while (!(UCB1IFG & UCTXIFG));              //等待数据被发送
   UCB1CTL1     |=  UCTXSTP;           //生成停止条件
   while (UCB1CTL1 & UCTXSTP);            //等待停止条件被发送
 
//单字节接收(RX)
int readByte (char wr_add、char rd_add、char register_add){
int rx_Byte;
 
  //UCB1I2CSA = MAX30101_I2C_ADDRESS;              // MAX30101 7位地址0x57
  UCB1CTL1  |= UCTXSTT + UCTR;           //生成开始 + I2C 发送(写入)
  UCB1TXBUF  =  wr_add;            //写入寄存器地址
  while (UCB1CTL1 & UCTXSTT);               //等待启动条件被清除
  while (!(UCB1IFG & UCTXIFG));              //等待寄存器地址被发送
  UCB1TXBUF  =  REGISTER_ADD;            //写入寄存器地址
  while (!(UCB1IFG & UCTXIFG));              //等待寄存器地址被发送
  //UCB1I2CSA = MAX30101_I2C_ADDRESS;              // MAX30101 7位地址0x57
  UCB1CTL1  |= UCTXSTT;              //生成重新启动
  UCB1TXBUF  =  rd;            //写入寄存器地址
  while (!(UCB1IFG & UCTXIFG));              //等待寄存器地址被发送
  UCB1CTL1  &=~   UCTR;                //接收模式
  while (UCB1CTL1 & UCTXSTT);              //等待启动条件被清除
  //while (!(UCB1IFG & UCRXIFG));             //等待字节已被读取
  RX_BYTE   =  UCB1RXBUF;            //读取字节
  while (!(UCB1IFG & UCRXIFG));             //等待字节已被读取
  UCB0CTL1 |= UCTXNACK;              //生成 NACK
  UCB1CTL1  |=  UCTXSTP;              //生成停止条件
  while (UCB1CTL1 & UCTXSTP);               //等待停止条件被发送
 
返回 RX_BYTE;
 

void MAX30101_setup(){
sendByte (0x08、0x40);//采样平均= 4.
sendByte (0x09、0x07);//模式=多
sendByte (0x0A、0x0F);//ADC 范围= 2048、采样率= 400、PW 控制= 411
sendByte (0x0C、0x1F);//红色脉冲振幅
sendByte (0x0D、0x1F);// IR 脉冲振幅
sendByte (0x0E、0x1F);//绿色脉冲振幅
sendByte (0x10、0x1F);//接近脉冲振幅
sendByte (0x11、0x77);//时隙01和02
sendByte (0x12、0x07);//插槽03
FIFO_CLEAR();

void FIFO_CLEAR (){
sendByte (0x04、0x00);// FIFO WR_PTR 清除
sendByte (0x05、0x00);// FIFO 过流计数器清零
sendByte (0x06、0x00);// FIFO RD_PTR 清除

 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    为了澄清您的问题、我有一些问题。

    您是否得到了 MAX30101的响应?
    如果没有定义 ISR、为什么要启用中断?
    您的 Clock_setup()和 I2C_setup()函数丢失。

    Andre
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    感谢您的回答。
    抱歉、我从 IDE 复制并粘贴了它、因此错过了这些函数。 已编辑。
    已注释_EINT(),因为我不使用中断
    我还没有得到任何答复。 (不确定您所说的是哪种类型的响应、但我确信传感器良好、因为我在其中测试了一些 Arduino 代码、并做出了响应)

    谢谢。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    我的意思是、您是否可以读出任何值。 在您的代码中、您正在进行大量配置、因此我将逐步介绍。 查看是否可以正确读取、然后写入并检查写入是否成功。 因此、我建议从一个简单得多的程序开始、然后逐步变得更加复杂。 您能否使用示波器或逻辑分析仪检查波形并将其与 Arduino 波形进行比较?
    I2C 协议是否正确?
    起动/停机条件是否正确?
    I2C 的速度是多少?
    SCL/SDA 上是否有上拉电阻器...

    另请查看应用手册: http://www.ti.com/lit/slaa734 ,第5章。

    此致、
    Andre
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    因此、我修整代码并通过将寄存器地址(0xFF)发送到传感器来尝试读取 PARTID。 传感器应返回0x15。 但我认为我可以传输寄存器地址并获得 ACK、但 RX 缓冲器中仍然没有任何内容。  您能告诉我哪里出错了吗?  这是 I2C 编码的问题吗?

    此处我要附加来自逻辑分析器的图片(1=第一个字节,2=我发送用于从寄存器读取数据的最后一个字节 )。 读取传感器 PartID 的代码如下:

    #include
    #include
    #include

    #define MAX30101_I2C_ADDRESS 0x57

    void Clock_setup();//默认
    void I2C_setup();

    int readByte (char wr_add、char rd_add、char register_add);

    Int ID;

    void main()

    WDTCTL = WDTPW + WDTHOLD;
    clock_setup();
    I2C_setup();
    ID = readByte (0xAE、0xAF、0xFF);// 0xFF 是 PartID 的寄存器地址

    void Clock_setup(){
    P11DIR |= BIT2;//检查 smclk、默认为1MHz
    P11SEL |= BIT2;//检查 smclk,默认为1MHz
    P11DIR |= BIT0;//检查 aclk、默认值为32.8KHz
    P11SEL |= BIT0;//检查 aclk,默认值为32.8KHz


    void I2C_setup(){

    P3SEL |= BIT7;// P3.1 (UCB0_SDA)、P3.2 (UCB0_SCL)// 3.7 UCB1_SDA、5.4 UCB1_SCL
    P5SEL |= BIT4;
    UCB1CTL1 |= UCSWRST;//复位使能
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;//主器件+ I2C 模式+同步
    UCB1CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK +仍然复位
    UCB1BR0 = 10;//默认 SMCLK 1M/10 = 100KHz .......... ?
    UCB1BR1 = 0;//
    UCB1I2CSA = MAX30101_I2C_ADDRESS;// MAX30101 7位地址0x57
    UCB1CTL1 &=~UCSWRST;//复位清零
    // UCB1IE |= UCTXIE + UCRXIE;//TX 和 RX 中断被启用

    //单字节接收(RX)
    int readByte (char wr_add、char rd_add、char register_add){
    int rx_Byte;

    //UCB1I2CSA = MAX30101_I2C_ADDRESS;// MAX30101 7位地址0x57
    UCB1CTL1 |= UCTXSTT + UCTR;//生成开始+ I2C 发送(写入)
    UCB1TXBUF = WR_ADD;//写入寄存器地址
    while (!(UCB1IFG & UCTXIFG));//等待寄存器地址被发送
    while (UCB1CTL1 & UCTXSTT);//等待开始条件被清除
    UCB1TXBUF = REGISTER_ADD;//写入寄存器地址
    while (!(UCB1IFG & UCTXIFG));//等待寄存器地址被发送
    //UCB1I2CSA = MAX30101_I2C_ADDRESS;// MAX30101 7位地址0x57
    UCB1CTL1 |= UCTXSTT;//生成重新启动
    UCB1TXBUF = rd;//写入寄存器地址
    while (!(UCB1IFG & UCTXIFG));//等待寄存器地址被发送
    UCB1CTL1 &=~ UCTR;//接收模式
    while (UCB1CTL1 & UCTXSTT);//等待开始条件被清除
    //while (!(UCB1IFG & UCRXIFG));//等待字节已被读取
    RX_BYTE = UCB1RXBUF;//读取字节
    // while (!(UCB1IFG & UCRXIFG));//等待字节已被读取
    UCB1CTL1 |= UCTXNACK;//生成 NACK
    UCB1CTL1 |= UCTXSTP;//生成停止条件
    while (UCB1CTL1 & UCTXSTP);//等待 STOP 条件被发送

    返回 RX_BYTE;

    谢谢、

    Rowshon。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您是否根据 MAX30101数据表实现了协议? 对于读取操作、您无需发送写入寄存器访问。 请参阅下面的内容。