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.

[参考译文] MSP430FR2353:无 I2C 中断

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1036776/msp430fr2353-no-i2c-interrupts

器件型号:MSP430FR2353
主题中讨论的其他器件:MSP430FR2355HDC2080HDC2022

我正在尝试将/msp430fr2355_demo_wo_hdc2080/main.c 中的示例代码移植到我们的硬件(FR2353、HDC2022)。 我将使用 USCI_B1。

I2C 外设不会生成中断(从不命中我在 ISR 中第一条语句上设置的断点)。

首先、我是否在下面的语句中使用了正确的关键字:

#pragma vector = USCI_B1_Vector

这是怎么回事?

#pragma vector = EUSCI_B1_Vector

两者都指向同一个中断矢量吗?  两个构建都没有错误。

下面是一些代码片段、这些代码片段经过修改以与我的硬件相匹配。

void initGPIO()
{

......... skipped lines

// I2C pins (P4.7 is SCL, P4.6 is SDA)
P4SEL0 |= BIT6 | BIT7;
P4SEL1 &= ~(BIT6 | BIT7);

.......skipped lines

}

void initI2C()
{
UCB1CTLW0 = UCSWRST; // Enable SW reset
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
UCB1BRW = 160; // fSCL = SMCLK/160 = ~100kHz
UCB1I2CSA = SLAVE_ADDR; // Slave Address
UCB1CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCNACKIE;
}

//******************************************************************************
// I2C Interrupt ***************************************************************
//******************************************************************************

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
//Must read from UCB1RXBUF
uint8_t rx_val = 0;
switch(__even_in_range(UCB1IV, USCI_I2C_UCBIT9IFG))       <<<<<<<<<<<Breakpoint set here.....
{

.......

......

}





I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
/* Initialize state machine */
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;

//Copy register data to TransmitBuffer
CopyArray(reg_data, TransmitBuffer, count);

TXByteCtr = count;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;

/* Initialize slave address and interrupts */
UCB1I2CSA = dev_addr;
UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
UCB1IE &= ~UCRXIE; // Disable RX interrupt
UCB1IE |= UCTXIE; // Enable TX interrupt

UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts   <<<<<<<<<<<< HANGS HERE...............

return MasterMode;
}

当我运行程序时、它会在以下行上挂起:

_bis_SR_register (LPM0_bits + GIE);//输入 LPM0、带中断

未命中断点。

这是第一次尝试使用 I2C 与 HDC2022通信)。

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

    您好 Jing、

    在论坛发布代码时、请使用插入- 代码选项、以便为可读性对代码进行格式化。 我已编辑了您的帖子以反映这一点。  

    对于您的问题、我建议您查看以下资源、以帮助您调试问题。

    《MSP430 MCU 上常见 eUSCI 和 USCI 串行通信问题的解决方案  》、特别是第2节和第5节。  

    查看此器件的标准 I2C 示例: https://dev.ti.com/tirex/explore/node?node=AJwbT2zPMZ72BhFoNsQCdA__IOGqZri__LATEST

    此外、我们的 MSP Academy 还将向您介绍如何在 MSP430上使用 I2C -尤其是类似于您的情况的任务3: https://dev.ti.com/tirex/explore/node?node=ANn42uDC4eb.Ph7o71nKTg__IOGqZri__LATEST

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

    I2C 硬件将在线路上生成一个 START 条件后生成一个发送中断。 因此、如果您没有中断、那么 MSP430就无法赢得仲裁。 您可以为此启用中断。

    但是、如果您没有超过启动条件、则硬件级别存在问题。 SDA 和 SCL 上缺少上拉电阻器是一种常见的故障。 此外、大多数 MSP430FR 系列器件会锁定端口、直到 LOCKLPM5被清除。 您不会在代码段中显示您在何处执行该操作。

    至于中断例程使用哪个符号、请检查器件头文件:msp430fr2553.h 我检查了 GNU 版本、它仅定义了 USCI 符号。

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

    感谢您的回复。

    我在 initGPIO()函数中确实有 PM5CTL0 &=~LOCKLPM5;语句。

    msp430fr2353.h 文件也只有 EUSCI_B0_vector。  但是、如果我使用 USCI_B0_vector、程序也会编译而不会出现错误。

    明天我将获得另一个电路板。  将看到这是否是硬件问题。  SDA 和 SCL 上存在4.7K 电阻器。

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

    检查 SDA 和 SCL 的状态非常简单、只需读取 P4IN 即可。 如果在端口空闲时得到除1以外的任何值、则说明您存在硬件问题。

    提供一些便利定义是相当常见的、以防您使用在旧硬件上有意义的符号。 如果您真的很担心、请检查标头或查看 C 编译器的输出以查看其执行的操作。

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

    感谢您的建议。

    我终于弄清楚了导致问题的原因。  我在调试时检查了 I2C 寄存器、并注意到有一些错误的值。  然后我意识到我忘记了在 main 中调用 initI2C()函数!