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.

[参考译文] MSP430FR5849:I2C 发送和接收中断

Guru**** 2616675 points

Other Parts Discussed in Thread: MSP430FR5849

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/671009/msp430fr5849-i2c-transmit-and-receive-with-interrupts

器件型号:MSP430FR5849

您好!
我正在尝试在 Driverlib 库上构建一些简单的例程、以便使用中断通过 I2C 通道发送和接收数据。

可用示例仅用于发送或接收、因此我尝试合并中断例程、但没有完全成功。

看起来 Tx 部分工作正常、但我也无法使接收部分工作。

这是我的中断例程:

#pragma vector=USCI_B0_vector
__interrupt void USCIB0_ISR (void)
{
switch (_even_in_range (UCB0IV、0x1E)
){
case 0x00:break; //向量0:无中断中断;
情况0x02:中断; //向量2:ALIFG 中断;
大小写0x04: //向量4:NACKIFG 中断;
EUSCI_B_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);
ptr = 0;
break;
case 0x06:break; //向量6:STT IFG 中断;
大小写0x08:中断; //向量8:STPIFG 中断;
大小写0x0a:中断; //向量10:RXIFG3中断;
大小写0x0c:中断; //向量14:TXIFG3中断;
大小写0x0E:中断; //向量16:RXIFG2中断;
大小写0x10:中断; //向量18:TXIFG2中断;
大小写0x12:中断; //向量20:RXIFG1中断;
大小写0x14:中断; //向量22:TXIFG1中断;
大小写0x16: //向量24:RXIFG0中断;
IF (PTR)
{
* PTR++= EUSCI_B_I2C_masterReceiveSingle (EUSCI_B0_BASE);//获取 RX 数据
if (--cnt =0)
{
EUSCI_B_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
ptr = 0;
}
}
中断;
情况0x18: //向量26:TXIFG0中断;
if (cnt)(如果(cnt) //检查 TX 字节计数器
{
EUSCI_B_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、* PTR++);
CNT--; //减量 TX 字节计数
器}
其他
{
EUSCI_B_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);
ptr = 0;
}
break;
case 0x1c:break; //向量30:时钟低电平超时中断;
大小写0x1E:中断; //向量32:第9位中断;
默认值:
中断;
}

开始接收的代码为:

void I2C_SEN_Read (int len、char * buf)
{
eUSCI_B_I2C_setSlaveAddress (eUSCI_B0_BASE、addr);
eUSCI_B_I2C_setMode (eUSCI_B0_BASE、eUSCI_B_I2C_receive_mode);
eUSCI_B_enable (eUSCI_B0_BASE);
CNT = len;
ptr = buf;
EUSCI_B_I2C_clearInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
EUSCI_B_I2C_enableInterrupt (EUSCI_B0_BASE、 EUSCI_B_I2C_Receive_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
EUSCI_B_I2C_masterReceiveStart (EUSCI_B0_BASE);
}

ptr 变量用于指向缓冲区、但也用于指示接收(或传输)已完成。

问题是、在示波器中、我看到对应于比预期多一个字节的一系列时钟脉冲(即、如果我要求读取一个字节、我会看到两个8位+ACK 脉冲。

但主要问题是 SDA 和 SCL 线路保持低电平。 看起来、EUSCI_B_I2C_masterReceiveMultiByteStop 不执行任何操作。

有人可以帮帮我吗?

谢谢你。
此致。
Mau。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Maurizio
    何时 SDA 和 SCL 线路保持低电平? 什么是从器件? 您能向我展示 I2C 的所有配置代码吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回答。
    初始化代码为:

    void I2C_SEN_Init (void)
    {
    EUSCI_B_I2C_initMasterParam;
    param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
    param.i2cClk = CS_getSMCLK ();
    param.datarate = EUSCI_B_I2C_SET_DATA_RATE_RATE_RATE_400BP.param;param.param
    0;param.param.param 0
    param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
    EUSCI_B_I2C_initMaster (EUSCI_B0_BASE、&param);
    }
    

    同时、我发现一个看起来稍有不同的示例、我将中断更改为:

    #pragma vector=USCI_B0_vector
    __interrupt void USCIB0_ISR (void)
    {
    switch (_even_in_range (UCB0IV、USCI_I2C_UCBIT9IFG))
    {
    案例0x00:break; //向量0:无中断中断中断;
    实例 USCI_I2C_UCALIFG:中断; //矢量2:ALIFG 中断;
    案例 USCI_I2C_UCNACKIFG: //向量4:NACKIFG 中断;
    EUSCI_B_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);
    ptr = 0;
    中断;
    案例 USCI_I2C_UCSTTIFG:中断; //向量6:STT IFG 中断;
    实例 USCI_I2C_UCSTPIFG:中断; //向量8:STPIFG 中断;
    实例 USCI_I2C_UCRXIFG3:中断; //向量10:RXIFG3中断;
    案例 USCI_I2C_UCTXIFG3:中断; //向量14:TXIFG3中断;
    案例 USCI_I2C_UCRXIFG2:中断; //向量16:RXIFG2中断;
    实例 USCI_I2C_UCTXIFG2:中断; //向量18:TXIFG2中断;
    案例 USCI_I2C_UCRXIFG1:中断; //向量20:RXIFG1中断;
    实例 USCI_I2C_UCTXIFG1:中断; //向量22:TXIFG1中断;
    实例 USCI_I2C_UCRXIFG0: //向量24:RXIFG0中断;
    if (--cnt =0)
    EUSCI_B_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    * PTR++= EUSCI_B_I2C_masterReceiveMultiByteNext (EUSCI_B0_BASE);
    if (cnt = 0)
    {
    EUSCI_B_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0);
    ptr = 0;
    }
    中断;
    案例 USCI_I2C_UCTXIFG0: //向量26:TXIFG0中断;
    if (cnt)(如果(cnt) //检查 TX 字节计数器
    {
    EUSCI_B_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、* PTR++);
    CNT--; //减量 TX 字节计数
    器}
    其他
    {
    EUSCI_B_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);
    成功= true;
    ptr = 0;
    }
    中断;
    案例 USCI_I2C_UCBCNTIFG:中断; //向量28:
    case USCI_I2C_UCCLTOIFG:break; //向量30:时钟低电平超时中断;
    案例 USCI_I2C_UCBIT9IFG:中断; //向量32:第9位中断;
    默认值:
    中断;
    }
    
    

    主要区别在于、在最后一次 EUSCI_B_I2C_masterReceiveMultiByteStop 调用之前调用了 EUSCI_B_I2C_masterReceiveMultiByteNext。
    因此、它可能只是一个标记、允许在最后一个字节后发送 STOP。

    我仍然有一个问题、即使我尝试读取一个字节、我也会在总线上看到地址阶段和读取两个令人清醒的字节、然后是 STOP。

    此外、我刚刚注意到、如果我必须读取更多字节(比如说5)、总线在第二次读取后卡住、并且两条线都保持低电平。

    我会继续调查此问题、但我们非常感谢您提供任何提示或帮助

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

    您好 Maurizio

    您能否在 您的硼上测试单个读取和写入代码示例。示例如下所示(只需将器件更改为 MSP430FR5849)  

    如果示例代码运行良好、您可以将它们组合在一起。