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.

[参考译文] MSP430FR6989:为什么要触发 I2C 中断标志?

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/959925/msp430fr6989-why-isn-t-the-i2c-interrupt-flag-triggering

器件型号:MSP430FR6989

下面是我用于初始化系统的一些设置函数:

void accel_init(){//

P4.0和4.1上 I2C 的 PIN 配置。 注4.0是 SDA、4.1是 SCL
P4SEL1 |=(SDA | SCL);
P4SEL0 &=~(SDA | SCL);

UCB1CTLW0 |= UCSWRST;//此命令启用 UCB 的设置。
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSYNC | UCSSEL_2;//I2C 模式|主器件|同步| SMCLCK
UCB1CTLW0 &=~

^UCTR;//接收数据模式 UCB1CTLW1 |= UCSTP_2;//自动生成的停止条件 UCB1CTLW0 = 3.1BRW = 3、UCB331BR1 = 3;/设置为
3;UCB331BR1 = 1 = 1 = 1 = 1 / 1 = 1;//

UCB1TBCNT = 1;//一次发送一个字节到从
器件 UCB1I2CSA = 0x26;//从器件的地址。

UCB1CTLW0 &=~UCSWRST;//禁用 UCB 设置。

//中断:
UCB1IE |= UCRXIE | UCNACKIE | UCBCNTIE | UCSTPIE;//当前接收中断| NACK 中断| cnt 值到达中断|开始中断

}

void initMSP430 (void){

/******* 测试数据发生器1kHz ***** /
P9DIR |= BIT1 | BIT2 | BIT3 | BIT4;//测试数据输出
TA2CTL = tassel__SMCLK | MC__Continous | TACLR;
TA2CCR1 = 1000; // 1MHz * 1/1000Hz
TA2CCTL1 = CCIE; //启用中断
testcnt = 0; //开始测试计数器为0

/********* PWM 背光******** /

P1DIR |= BIT3;
P1SEL0 |= BIT3;
P1SEL1 &=~BIT3;
TA1CCR0 = 511;
TA1CCTL2 = OUTMOD_7;
TA1CCR2 = 255;
TA1CTL = tassel__ACLK | MC__UP | TACLR;

/******** SPI /

P2DIR |= LCD_CS_PIN;// DC 和 CS
P4DIR |= LCD_DC_PIN;
P1SEL0 |= LCD_MOSI_PIN | LCD_UCBCLK_PIN; // MOSI 和 UCBOCLK
P1SEL1 &=~(LCD_MOSI_PIN | LCD_UCBCLK_PIN);

UCB0CTLW0 |= UCSWRST;//重置 UCB0

/*
* UCBxCTLW0- eUSCI_Bx 控制寄存器0
* UCSSEL__SMCLK -主控模式下的 SMCLK
* UCCKPL-时钟极性选择
* UCMSB- MSB 优先选择
* UCMST-主控模式选择
* UCMODE_0 - eUSCI 模式3引脚 SPI 选择
* UCSYNC-同步模式使能
*
//UCB0CTLW0 |= UCSSEL__SMCLK | UCCKPL | UCMSB | UCMST | UCMODE_0 | UCSYNC;
UCB0CTLW0 |= UCSSEL_SMCLK | UCCKPH | UCMSB | UCMST | UCMODE_0 | UCSYNC;
// UCB0CTLW0 = UCCKPH + UCMSB + UCMST + UCSYNC + UCSSEL_2;// 3引脚8位 SPI 主


器件 UCB0BR0 |= 0x01; //时钟= SMCLK/1
UCB0BR1 = 0;
UCB0CTL1 &=~Ω UCSWRST; //清除 UCSWRST 以释放 eUSCI 以运行
PM5CTL0 &=~LOCKLPM5;//从电源管理

器___ ENABLE_INTERRUPT ()解锁端口

;} 

这是我的主要函数:

void main (void){
WDTCTL = WDTPW | WDTHOLD;//终止看门狗

initmsp430();
ACCEL_INIT();

__DELAY_CYCLES (10);

/*现在的目标是在启用中断时发送所需的信息
*我将尝试使用 cnt 中断系统来执行此操作*/
UCB1CTLW0 |= UCTR | UCTXSTT;//开始发送
UCB1TXBUF = 0x01;//发送1



while (true){
P6DIR Δ^= BIT1;//诸如此类。 _nop()在这里也可能还不错
。}
}

我只是想让 UCBCNTIFG 触发。 在调试模式下、永远不会抛出该标志。 我不明白为什么。 根据系列用户指南(第841页、2020年4月修订版)、此中断在主控模式下可用。 由于我已经设置了 UCB1TBCNT = 1、并且正在根据 UCB1CTLW1 |= UCASTP_2生成自动停止条件、所以它应该在发送一个字节后发生。 启用中断的是 accel_init()函数,并且在 initmsp430()函数中调用__enable_interrupt (),因此应设置 GIE。 我将系统设置为传输模式,并在 main()中调用 START 条件。 缓冲区可以包含任何内容、但恰好是0x01。

由于我要发送一个字节、并且 UCB1连接到 smclk、我的预期是、它需要大约8个时钟周期才能发送一个字节。 因此、中断标志应该会在该时间附近、它应该会进入我的 ISR (这是一个无限 while 循环、我在调试器中遇到了断点)。 但是、它不会。 中断根本不会触发、我不明白为什么。 相反,该程序会进入仅切换未使用引脚方向的 main() while ()循环。  

有人能不能对此有所了解? 对于我的器件、在尝试 I2C 通信时无法触发任何中断标志、我担心在设置中做了一些不当操作。 我无法排除硬件问题、但如果标志应该出现在这里、并且软件没有任何问题、那么这就意味着硬件问题。

如果有任何帮助,将不胜感激。

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

    我建议您在设置 STT 和设置 TXBUF 之间插入类似"while (!(UCB1IFG & UCTXIFG))/*empty*/;"的内容。

    尽管用户指南(SLAU367P)图32-12有所不同、但我不相信 TXIFG=1是瞬时的。

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

    实际上、我已经尝试仅使用这样一个环路。 不幸的是、UCTXIFG 标志永远不会升高、因此它一直位于该环路中。 这是我探讨基于中断的选项的部分原因、也是我怀疑硬件问题的部分原因。 遗憾的是、我没有第二个要与之进行比较的传感器副本、因此-目前、我正在尝试确保软件配置不正确。

    无论如何、我将添加循环以查看它是否会改变任何行为、因为我尚未在该上下文中尝试过它。 也许会产生影响。

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

    我可以想到 TXIFG 不置位(UCTR=1)的唯一原因是总线本身处于不良状态、因此 I2C 单元无法发出启动命令。 您有范围吗?

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

    我确实有一个示波器。 我已经检查了各行上的活动、没有发现任何活动迹象。 基本而言、配置完成后、系统将保持 I2C 空闲状态。 即使在一个边沿(针对 SCL 和 SDA 线路)上触发示波器、我也看不到任何活动、除非我按下 MSP430复位按钮、在这种情况下、当系统从空闲变为复位并返回空闲状态时、我将检测上升/下降边沿。

    最令人惊讶的结果可能是 SCL 线没有变化。 这应该绑定到 SMCLK、但线路上根本没有发生任何事情。 我可能错了、但我对该功能的理解是、我不需要计时器来驱动 SCL 线路(或 SDA 线路)。 相反、当我将其"绑定"到时钟(在本例中为 ssel_2)时、该时钟应自动驱动所有内容、并且我只需要发送启动/停止条件、选择数据、选择发送/接收模式等

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

    但是、为了增加一个额外的想法、我想如果 MSP430在我设置它时看到启动条件时出现问题、这意味着事情将保持在空闲状态。 不过、如果是这种情况、我认为这意味着问题出在 MSP430、而不是我的外设。

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

    我将您的代码放在连接有 LIS3DH 分接板的 Launchpad 上。 我没有添加 UCB1 ISR、我只是让它进入 ISR_TRAP 并查看寄存器。  

    当代码按原样时、它在请求 TXIFG 时挂起(无 CNTIFG)。

    当我添加我建议的行时、它会完成整个事务、并在 CNTIFG=1 (和 STPIFG=1)时按 ISR。

    我不知道我们在做什么不同。

    下面是第二个(成功)案例:

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

    "空闲"我认为您是"高电平"。 如果 I2C 单元将一根导线拉低、但它不会变为低电平、它实际上只能得出结论"我不控制总线"、这是一个稍微弱的说法。 这是一个相当不寻常的情况,它可能(例如)意味着有一些东西在主动将总线驱动为高电平--这不应该发生,但这不是 I2C 单元的权限。

    更常见的情况是它释放了总线、但它不会变为高电平。 如果我们讨论的是 SCL、这就是时钟展宽。 如果是 SDA、在 UM10204 [3.1.16]中有一个相关的部分、其中 A (有点 glib)的措辞将为"您被灌入"。

    [编辑:添加了章节编号]