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.

[参考译文] CCS/MSP432P401R:ADXL345 I2C 通信问题

Guru**** 2597745 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/647014/ccs-msp432p401r-adxl345-i2c-communication-issues

器件型号:MSP432P401R

工具/软件:Code Composer Studio

您好!  

我正在尝试使用 I2C 与 ADXL345进行通信、但无法以任何身份发送或接收数据。 我已经连接了一个逻辑分析仪、无论我要传输什么、都能获得相同的数据、而且数据非常随机。 我使用了 MSP432随附的 I2C 示例代码、甚至在逻辑分析仪上运行该代码、在该分析仪上我会得到随机不清楚的数据。  

我在下面附上了我的代码。 如果您有任何建议或帮助、请告诉我、我真的需要它!

  1. /*  
  2.  * i2c.c  
  3.  *  
  4.  *  创建 日期:   2017年11月18日  
  5.  *      作者: noamargalit  
  6.  *   
  7.   
  8. //从( 加速计)  
  9. //主 控方(msp432p401r)   
  10.   
  11. #include "msp.h"   
  12. #include "i2cmaster.h"   
  13.   
  14. #define PWR_CTRL 0x2D   
  15.   
  16.   
  17. volatile uint8_t rxbuf[6];   
  18. uint8_t *rxdata;   
  19. volatile uint8_t transmit [2];   
  20.   
  21. void i2c_data_transmission (){   
  22.     uint8_t i;   
  23.     P1->SEL0 |= BIT6 | BIT7;   
  24.     __ENABLE_IRQ();   
  25.     //通电 :   
  26.     I2C_Receive_configure ();   
  27.     I2C_Transmit 配置();   
  28.   
  29.     Transmit 两个数据(0x00、PWR_CTRL); //唤醒    
  30.     while (EUSCI_B0->CTLW0 和 EUSCI_B_CTLW0_TXSTP);   
  31.     Transmit 两个数据(0x10、 PWR_CTRL); //自动 睡眠   
  32.     while (EUSCI_B0->CTLW0 和 EUSCI_B_CTLW0_TXSTP);   
  33.     Transmit 两个数据(0x08、 PWR_CTRL); //测量 数据   
  34.     while (EUSCI_B0->CTLW0 和 EUSCI_B_CTLW0_TXSTP);   
  35.   
  36.     while (1){   
  37.   
  38.        uint8_t test_BYTE = (0x32<1) + 1; //发送 读取 请求 到   地址 0x32: x_data 的寄存器   
  39.        uint8_t datarequest = 0x32;   
  40.   
  41.         //transmit array (&test_Byte、 1); //数据 请求   
  42.         Transmit _One_data (test_Byte);   
  43.         for (i=0; i < 20; i++);   
  44.         while (EUSCI_B0->CTLW0 和 EUSCI_B_CTLW0_TXSTP);   
  45.         receive_data();   
  46.         while (EUSCI_B0->CTLW0 和 EUSCI_B_CTLW0_TXSTP);   
  47.     //    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTP;//  结束后停止   
  48.   
  49. *   
  50.   
  51.     }   
  52. }   
  53.   
  54. void i2c_transmit 配置(){   
  55.   
  56.     EUSCI_B0->CTLW0 = EUSCI_A_CTLW0_SWRST;   
  57.     EUSCI_B0->CTLW0 = EUSCI_B_CTLW0_MODE_3 | EUSCI_B_CTLW0_SYNC | EUSCI_B_CTLW0_ssel_SMCLK;   
  58.     EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;   
  59.   
  60.     EUSCI_B0->IE |= EUSCI_B_IE_TXIE0;   
  61.   
  62.   
  63. }   
  64.   
  65. void i2c_receive_configure (){   
  66.     EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SWRST; //复位 状态   
  67.     EUSCI_B0->CTLW0 =  EUSCI_B_CTLW0_MST | EUSCI_B_CTLW0_SYNC | EUSCI_B_CTLW0_ssel_SMCLK; //主控、同步、SMCLK 模式   
  68.     EUSCI_B0->CTLW1 |= EUSCI_B_CTLW1_ASTP_2; //   达到 阈值时自动停止   
  69.     EUSCI_B0->CTLW1 |= EUSCI_B_CTLW1_SWACK;   
  70.     EUSCI_B0->BRW = 30; //使用   SMCLK 的波特率   
  71.     EUSCI_B0->TBCNT = 6; 每个     方向接收到/6个字节   
  72.     EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;   
  73.   
  74.     EUSCI_B0->IE |= EUSCI_B_IE_RXIE0| EUSCI_B_IE_NACKIE; //  我 是否需要 其他 中断?  NACK?  EUSCI_B_IE_NACKIE 字节 计数器?   
  75.   
  76.   
  77. }   
  78.   
  79. void transmit 两个数据(uint8_t 用途、 uint8_t power_control){   
  80.     Transmit [0] = 用途;   
  81.     Transmit [1] = power_control;   
  82.     EUSCI_B0->I2CSA = (0x53 <<1  )| I2C_READ;   
  83.     while (EUSCI_B0->CTLW0 和 EUSCI_B_CTLW0_TXSTP); //发送 停止 条件    
  84.     EUSCI_B0->CTLW0 |= UCTR;   
  85.     EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT; //开始 发送   
  86.     NVIC_EnableIRQ (EUSCIB0_IRQn); //输入 中断 处理程序   
  87. }   
  88.   
  89. void transmit 一个数据(uint8_t data){   
  90.     发送[0] = 数据;   
  91.     while (EUSCI_B0->CTLW0 和 EUSCI_B_CTLW0_TXSTP);   
  92.     EUSCI_B0->I2CSA = (0x53 <<1  )| I2C_READ;   
  93.     EUSCI_B0->CTLW0 |= UCTR;   
  94.     EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT;   
  95.     NVIC_EnableIRQ (EUSCIB0_IRQn);   
  96. }   
  97.   
  98.   
  99. void receive_data (void){   
  100.     rxdata = (uint8_t *) rxbuf;   
  101.     while (EUSCI_B0->CTLW0 和 EUSCI_B_CTLW0_TXSTP);   
  102.     EUSCI_B0->CTLW0 &= ~UCTR;   
  103.     EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT;   
  104.     NVIC_EnableIRQ (EUSCIB0_IRQn);   
  105. }   
  106.   
  107. void EUSCIB0_IRQHandler (void){   
  108.   
  109.     IF (EUSCI_B0->IFG 和 EUSCI_B_IFG_NACKIFG)   
  110.         {   
  111.             EUSCI_B0->IFG &= ~ EUSCI_B_IFG_NACKIFG; //检查      从器件接收到的 NACK 标志 是否   发生 这种情况,txbuf  是否被清除   
  112.             EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT; //完成 重新启动 条件   
  113.   
  114.            IF (EUSCI_B0->IFG 和 EUSCI_B_IFG_TXIFG0) //检查 TX 标志   
  115.                 {   
  116.                     EUSCI_B0->TXBUF = 发送[0];   
  117.                     EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_TXSTT;   
  118.   
  119.                 }   
  120.   
  121.   
  122.         }   
  123.   
  124.     否则 {   
  125.         EUSCI_B0->TXBUF = 0x00;   
  126.         EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_TXSTT;   
  127.         EUSCI_B0->IFG  |= EUSCI_B_IFG_TXIFG0;   
  128.   
  129.     }   
  130.   
  131.   
  132.     IF (EUSCI_B0->IFG 和 EUSCI_B_IFG_RXIFG0)   
  133.     {   
  134.         EUSCI_B0->IFG &= ~EUSCI_B_IFG_RXIFG0; //清除 标志   
  135.         *rxdata++ = EUSCI_B0->RXBUF;   
  136.   
  137.   
  138.     }   
  139.   
  140.     IF (EUSCI_B0->IFG 和 EUSCI_B_IFG_TXIFG0)   
  141.     {   
  142.   
  143.         EUSCI_B0->TXBUF = 发送[0];   
  144.         UCB0IFG &= ~UCTXIFG;   
  145.   
  146.     }   
  147.   
  148.   
  149.   
  150. }   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    NOA、
    在深入了解此代码之前、您是否已使用两个红色 LaunchPad 成功尝试过其中一个主从示例? (假设您没有使用旧的黑色 MSP432 LaunchPad、它们是预制的、与生产器件有一些差异。) 您使用哪个示例作为代码的基础?

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

    尊敬的 Bob:

    我使用主从示例尝试编写此新代码、但实际上没有使用两个 LaunchPad 对其进行测试。 但是、我曾尝试一次直接修改该特定代码、尝试在逻辑分析仪上查看数据并接收到相同的随机数据。 我用 msp432p401x_euscib0_i2c_10和_11作为示例、我从其他学生那里听说过类似的问题、即他们在逻辑分析仪上获取预期数据时遇到了问题。 我已经在我的黑色 MSP 和红色 MSP 上测试了代码。 我目前还在尝试使用来自其中一个论坛的不同示例代码、以查看该代码是否起作用。

    如果您看到任何看起来不正确的内容、请告诉我。

    谢谢、

    NOA Margalit

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

    您是否在 I2C 线路上使用上拉电阻器? 我们还强烈建议您不要使用黑色 launchpad。 开始工作的最佳方式是将两个示例代码(主从)组合在一起、一个两个单独的红色 LaunchPad 和测试。 确保您具有用于 SDA 和 SCL 的上拉电阻器。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Evan、

    我在 I2C 线路上有上拉电阻器。 我没有使用黑色 launchpad、我已经使用这两种方法进行了测试。 没有人成功使用示例代码、包括我们的嵌入式系统专家教师。 是否有任何没有中断的示例代码? 只需基本配置即可成功发送和接收数据?

    我现在可以传输从地址、但它是我唯一可以发送的内容:  

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

    您能解释一下您到底在做什么吗?

    您正在使用哪些示例来实现主器件和从器件?

    您的上拉电阻器有什么价值?

    您是否正在使用最新的 SimpleLink MSP432 SDK?

    您是否使用了两个红色 launchpad (答案是"是"、因此没有操作)

    您建立了哪些连接?

    我今天早上测试了这些示例、以便它们正常工作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    NOA、

     如果您只看到从器件地址、则意味着在发送时不会从从器件获得应答。  对于这些示例、您需要以下配置(如果其中某些配置明显、请原谅我):

    下面是我要使用的内容:

    1.两个红色 Launchpad:1个从设备、1个主设备

    2.上拉- 10kohm 至3.3V Vcc (Launchpad 的3.3V 电源)

    3. LaunchPad 上的接地端相互连接(避免非常见的接地问题、尽管这在这里并不是真正的问题)

    4.打开 CCS 7.3的2个实例(让我们将它们称为 CCS-Mstr 和 CCS-SLV)

      -注意-您需要为每个实例创建单独的工作区,并将相应的示例导入其中

    5.如果尚未断开两个 LP (USB)连接,请将其断开

    6.从 CCS-Slave-

    a.仅连接从 LaunchPad
    b.导入并编译 msp432p401x_euscib0_i2c_11  
    c.连接调试器(Run->Debug)
    d.启动从站代码  

    7.启动 CCS-主站

    a.连接主 LaunchPad、同时保持连接从器件 LP
    b.导入并编译  msp432p401x_euscib0_i2c_10
    c.连接调试器(Run->Debug)
    d.在 SCL HL 边沿上启动逻辑分析仪
    e.启动主代码  

    请注意、编程完成后、您当然不需要将从设备连接到 PC、但在运行主设备之前仍需要启动它。

    如果您的程序与上述程序有任何不同、请告诉我。

    此致、

     Bob L.

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

    您是否已经对此进行了进一步的研究? 我们有兴趣帮助所有人都能做到这一点。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我有。 我在试验电路板上的某些东西连接不正确、但当总线不在时、我仍然会遇到很多问题。 我拔下电路板、重新插上电路板、总线仍然很忙。 我已经尝试重新配置引脚、以便使其使总线恢复到一个不忙状态、但它会导致意外电压并将 SCL 降低至低电平。 以下是我的较新代码:  

    #include "msp.h"

    /**

     * main.c

     *

    void i2c_configure();

    void i2c_multiple_write (uint8_t 寄存器、uint16_t val);

    void i2c_read_single_Byte (uint8_t 寄存器、uint8_t 方向);

    volatile uint8_t data[6];

    volatile int i=0;

    #define X 0

    #define Y 1.

    #define Z 2.

    void main (void)

    WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;//停止看门狗计时器

     // if (eUSCI_B1->STATW & EUSCI_B_STATW_BBUSY){

    // P1->OUT &=~BIT5;

    // P1->OUT |= BIT5;

      P6->SEL1 &=~BIT4;

      P6->SEL1 &=~BIT4;

      P6->OUT |= BIT5;

      P6->OUT |= BIT4;

      P6->SEL0 |= BIT5;

      P6->SEL0 |= BIT4;

    while (1){

      I2C_CONFIG();

        // i2c_multiple_write (0x2D、0x00);

       // i2c_multiple_write (0x2D、0x10);

        I2C_MULTIPLE_WRITE (0x2D、0x08);

      I2C_READ_SINGLE_BYTE (0x32、X);

     // for (i=0;i<20;i++);

      I2C_READ_SINGLE_BYTE (0x34、Y);

      I2C_READ_SINGLE_BYTE (0x36、Z);

     // *x =(int16_t)((((int) data[1])<< 8)| data[0]);

     // * y =(int16_t)((((int) data[3])<< 8)| data[2]);

     // *z =(int16_t)((((int) data[5])<< 8)| data[4]);

    void i2c_configure (){

        // P1->SEL1 |= BIT7 | BIT6;

        /*启用复位、主器件、I2C (模式3)、SMCLK*/

        EUSCI_B1->CTLW0 =(EUSCI_B_CTLW0_SWRST |EUSCI_B_CTLW0_MST|EUSCI_B_CTLW0_MODE_3 | EUSCI_B_CTLW0_ssel_SMCLK);

        /*no Autostop*/

        EUSCI_B1->CTLW1 = EUSCI_B_CTLW1_ASTP_0;

        /*为 SMCLK 设置时钟,为100KBPS 速率设置3MHz */

        EUSCI_B1->BRW = 30;

        /*配置引脚1.6 (SDA) 1.7 (SCL)(这些是次级模式引脚)*/

        //P6->SEL0 |= BIT5 | BIT4;

        // P1->SEL1 &=~(BIT7 | BIT6);

    /*

        P6->SEL1 &=~BIT4;

        P6->SEL1 &=~BIT4;

        P6->OUT |= BIT5;

        P6->OUT |= BIT4;

        P6->SEL0 |= BIT5;

        P6->SEL0 |= BIT4;

        *

        /*软件复位 DISABELE*/

        EUSCI_B1->CTLW0 &=~EUSCI_B_CTLW0_SWRST;

        //EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP;

        /*从地址*/

        EUSCI_B1->I2CSA = 0x53;

      }

    void i2c_multiple_write (uint8_t 寄存器、uint16_t val)

         /*从器件地址和寄存器读取地址的发送模式*/

         EUSCI_B1->IE &=~EUSCI_B_IE_TXIE0;

         EUSCI_B1->CTLW0 |= UCTR;

         EUSCI_B1->IFG &=~EUSCI_B_IFG_TXIFG0;

         while (EUSCI_B1->STATW 和 EUSCI_B_STATW_BBUSY);

         /*开始*/

         EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT;

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IFG_TXIFG0));

         /*将寄存器写入 TXBUF*/

         EUSCI_B1 ->TXBUF =寄存器;

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IFG_TXIFG0));

         /*将值写入寄存器*/

         EUSCI_B1->TXBUF = val;

         /*空 TX BUF? 发送 STOP*/

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IFG_TXIFG0));

         EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP;

    void i2c_read_single_Byte (uint8_t 寄存器、uint8_t 方向)

         /*从器件地址和寄存器读取地址的发送模式*/

         EUSCI_B1->IE &=~EUSCI_B_IE_TXIE0;

         EUSCI_B1->CTLW0 |= UCTR;

         EUSCI_B1->IFG &=~EUSCI_B_IFG_TXIFG0;

         while (EUSCI_B1->STATW 和 EUSCI_B_STATW_BBUSY);

         /*开始*/

         EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT;

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IFG_TXIFG0));

         EUSCI_B1 ->TXBUF =寄存器;

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IFG_TXIFG0));

         EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP;

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IFG_TXIFG0));

         /*接收器模式*/

         EUSCI_B1->CTLW0 &=~UCTR;

         EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT;

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IE_RXIE0));

         if (X){

           //for (i=0;i<1;i++)

           //{

             DATA[X]=(EUSCI_B1->RXBUF);

           //}

         }

         if (Y){

           DATA[Y]=(EUSCI_B1->RXBUF);

         }

         if (Z){

            DATA[Z]=(EUSCI_B1->RXBUF);

         }

         EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP;

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IFG_TXIFG0));

         while (!(EUSCI_B1->IFG 和 EUSCI_B_IE_RXIE0));

    它仅在某些时间收集数据、其余时间线保持繁忙状态。 如果您对如何配置引脚有任何建议、请告诉我。