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/MSP430FR6989:使用MSP430Ware MSP430FR5xx_6xx Driverlib的I2C示例代码

Guru**** 2024750 points
Other Parts Discussed in Thread: MSP430FR6989, ENERGIA
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/655536/ccs-msp430fr6989-i2c-sample-code-using-msp430ware-msp430fr5xx_6xx-driverlib

部件号:MSP430FR6989
主题中讨论的其他部件:MSP430WAREENERGIA

工具/软件:Code Composer Studio

你好

有人能帮我用MSP430FR5xx_6xx Driverlib进行I2C通信的示例代码吗? 我正在尝试连接到具有0x48地址的I2C从属设备并读取寄存器0x10。 我进行了广泛的搜索,但找不到任何可以帮助我入门的示例代码。

此致

维贾伊

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

    MSP430WARE ->库->驱动程序库->MSP430FR5xx_6xx ->示例项目-> EUSCI_B_I2C有几个示例可帮助您入门。

    此致,
    Ryan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很抱歉打扰你。 我的问题是从属设备本身不发送任何数据。 我们必须从从属设备的寄存器中检索数据。 库中的所有示例都等待从从属设备生成中断。 我使用的传感器不是这样。 例如,我必须读取地址为0x77的从属设备上的芯片地址0xd0。 如果您分享一些代码,我将非常感谢。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您所说的不是真的,尽管在没有主设备提供时钟的情况下,I2C从属设备都不会发送数据。 您使用的从属设备是什么? 我将使用示例eusci_b_i2c_ex4_masterTxSingle (发送寄存器地址),后跟eusci_b_i2c_ex4_masterRxMultiple (从寄存器读取数据)。 启动->从地址+写入->寄存器地址->停止/启动或重新启动->从地址+读取->读取数据->停止。

    此致,
    Ryan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    下面的代码只对我有效一次。 我不使用中断,因为我只需要设置一次寄存器值。
    我能够从BME280模块读取芯片ID。 但是,它现在返回0x00。 您能提出可能的问题吗?


    ----------------------------------
    #include <stdio.h>
    #include <msp430fr6989.h>
    #define slaver_address 0x77
    #define CHIP_ADDRESS 0xd0

    无符号int RX_Data;
    volatile unsigned char Com_Flag =0;

    内部主(无效)

    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

    printf ("设置I2C引脚\n");

    P1SEL0 || BIT6 | BIT7; //将GPIO 1.6 SDA 1.7 SCL配置为I2C引脚

    PM5CTL0 &=~LOCKLPM2;

    //为I2C模式配置USI_B0
    UCB0CTLW0 = UCSWRST; //将eUSI_B置于重置状态
    UCB0CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK;// I2C主模式,SMCLK
    UCB0BRW = 0x8; //波特率= SMCLK / 8
    //UCB0CTLW0 = UCASTP_2; //自动停止声明
    UCB0CTLW0 &=~UCSWRST; //清除复位寄存器
    UCB0IE |= UCTXIE0 | UCNACKIE; //传输和nack中断启用
    UCB0I2CSA =从属地址; //配置从属地址

    printf ("I2C已初始化!\n");

    while (UCB0CTLW0和UCTXSTP); //确保停止条件已发送
    UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX,启动条件
    printf ("已发送开始!\n");
    __DELAY周期(1000);
    UCB0TXBUF =芯片地址;
    __DELAY周期(1000);
    //UCB0CTLW0 |= UCTXSTP; // I2C停止条件
    //while (UCB0CTLW0和UCTXSTP);
    UCB0IFG &=~UCTXIFG; //清除USI_B0 TX int标志
    UCB0CTLW0 &=~UCTR;
    UCB0CTLW0 |= UCTXSTT; //重复启动
    __DELAY周期(1000);
    RX_Data = UCB0RXBUF; //获取RX数据
    printf ("芯片ID是:0x%02x\n",RX_Data);
    }
    ----------------------------------

    输出

    设置I2C引脚
    I2C已初始化!
    发送开始!
    芯片ID为:0x00
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果BME280设备的SDO引脚连接到GND,则从属地址应为0x76,如果改为连接到VDDIO,则仅为0x77。 您应该使用逻辑分析仪或示波器屏幕截图来确认从属地址是否确认I2C通信并正确响应。 您提供的代码可以通过检查UCBUSY或TX/RX IFG位而不是依赖延迟来进行改进。

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

    亲爱的Ryan

    BME280与具有Energia代码的同一个启动板完美配合。 我在CCS中使用此代码时遇到问题。 即使我导入到CCS时,Energia代码也能正常工作。 运行多次之后,代码只工作一次。 目前我使用10K上拉电阻器,我也尝试了4.7K电阻器。 两人都在使用Energia,但没有使用此代码。 我还尝试了下面的代码,其中包含您提到的示例中的中断,但它在__BIC_SR_REGISTER_ON_EXIT (LPM0_bits)处卡住;我无法获得TXIFG0中断。

    抱歉,我没有示波器,也不知道如何使用。 我是一名医学博士,从事一个污染感测项目。

    请参阅下面的代码,并在此处告诉我我做了什么错误。 我花了2周时间才达到这个水平:)

    我没有添加任何重新启动以接收。 此代码本身在GEE中被卡住。

    ________________________________________________________________

    #include <msp430fr6989.h>
    
    #define BME280_address 0x77
    #define chip_address 0xd0
    
    volatile unsigned TXchar ByteCtr;
    unsigned char RX_Data;
    
    int main(void)
    {
    WDTCTL = WDTPW | WDTHOLD;
    P1SEL0 |= BIT6 | BIT7;
    PM5CTL0 &=~LOCWS=UCST0
    //启用软件重置
    UCB0CTLW0 |= UCMODE_3 | UMST | UCSSEL__SMCLK; // I2C主控,同步模式
    UCB0BRW = 0x8; // fSCL = SMCLK/12 =~100kHz
    UCB0CTLW0 &=~UCSWRST; //清除软件重置,恢复操作
    UCB0IE |= UCTXIE0 | UCRXIE0 | UCNACKIE; //启用RX和TX中断
    
    ,同时(1)
    {
    __DELAY周期(1000); //传输之间的延迟
    UCB0I2CSA = BME280_address;//配置从属地址
    TXByteCtr = 1; //加载TX字节计数器
    While (UCB0CTLW0和UCTXSTP); //确保停止条件已发送
    
    UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX,启动条件
    
    __bis_sr_register(LPM0_bits | GIE);
    }
    #if
    
    defined(__TI_Compiler_version__)|| defined(__IAR_systems_icc__)
    #pragma vector = UISR_B0_vector
    __interrupt void USI_B0(SCI)
    #Elif defined(__GNU_system_ICC__)#vector = UISR_BUISR_BUVEC_BUVEC_0
    
    
    
    #endif
    {
    Switch(__偶 数_in_range(UCB0IV, USI_I2C_UCBIT9IFG))
    {
    案例USI_NONE: 中断; //矢量0:无中断
    案例USI_I2C_UCALIFG:中断; //矢量2:ALIFG
    案例USI_I2C_UCNACKIFG: //矢量4:NACKIFG
    UCB0CTLW0 |= UCTXSTT; //如果不确认,请重新发送启动
    中断;
    案例USI_I2C_UCSTIFG:中断; //向量6:STTIFG
    案例USI_I2C_UCSTPIFG:中断; //矢量8:STPIFG
    案例USI_I2C_UCRXIFG3:中断; //矢量10:RXIFG3
    案例USI_I2C_UCTXIFG3:中断; //矢量12:TXIFG3
    案例USI_I2C_UCRXIFG2:中断; //矢量14:RXIFG2
    案例USI_I2C_UCTXIFG2:中断; //矢量16:TXIFG2
    案例USI_I2C_UCRXIFG1:中断; //矢量18:RXIFG1
    案例USI_I2C_UCTXIFG1:中断; //矢量20:TXIFG1
    案例USI_I2C_UCRXIFG0:中断; //矢量22:RXIFG0
    案例USI_I2C_UCTXIFG0: //矢量24:TXIFG0
    IF (TXByteCtr) //检查TX字节计数器
    {
    UCB0TXBUF =芯片地址; //加载TX缓冲区
    TXByteCtr // Decrement TX字节计数
    器}
    否则
    {
    UCB0CTLW0 |= UCTXSTP; // I2C停止条件
    UCB0IFG &=~UCTXIFG; //清除USI_B0 TX int标志
    __BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出LPM0
    }
    中断;
    默认值:break;
    }
    }
    

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

    我按实际情况调试了您的代码,并输入了USI_B0_Vector ISR的USSCI_I2C_UCTXIFG0案例,没有出现任何问题。 请注意,这只会在连接上拉电阻时发生。

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

    Ryan

    让我感到困惑的是,它采用10K拉杆的Launchpad在Energia工作,而不是在CCS中工作? 我是否需要在CCS中执行任何其他项目/构建配置?

    此致
    Vijay博士

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

    我的LaunchPad上的10k电阻器在CCS中工作。 您的IDE和编译器版本是什么?  您可以尝试将您的CCS项目文件发送给我,以便查看是否有用。

    此致,
    Ryan

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

    Ryan

    下面的代码解决了我的问题。 我仍然想知道为什么以前的代码被卡住了。 如果您发现错误,请告诉我。

    unsigned char i2c_read(unsigned char slv_addr, unsigned char reg_addr){
    
    无符号char数据=0;
    
    (UCB0STAT和UCBBUSY);
    UCB0I2CSA = SLV_addr;
    UCB0CTLW0 |= UCTR | UCTXSTT;
    
    while (UCB0CTLW0和UCTXSTT);
    UCB0TXBUF = REG_ADDR;
    while (!(UCB0IFG和UCTXIFG0));
    
    UCB0CTLW0 &=~UCTR;
    UCB0CTLW0 |= UCTXSTT;
    
    while (UCB0CTLW0和UCTXSTT);
    UCB0CTLW0 |= UCTXSTP;
    while (!(UCB0IFG和UCRXIFG0));
    数据= UCB0RXBUF;
    
    while (UCB0CTLW0和UCTXSTP);
    
    返回数据;
    }