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.

[参考译文] MSP430G2553:I2C ISR未运行。 已设置GIE位,已设置TXIE,已设置TXIFG

Guru**** 2535160 points
Other Parts Discussed in Thread: MSP430G2553, TMP100

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/580998/msp430g2553-i2c-isrs-not-running-gie-bit-is-set-txie-is-set-txifg-is-set

部件号:MSP430G2553
主题中讨论的其他部件:TMP100MSP430WARE

在我的代码中,我启用了所有USI_B模块的中断,设置了GIE位,并有一个具有正确中断向量的ISR。 (使用TI示例代码中的矢量和ISR名称)目前我使用轮询来实现I2C。 但是我想以正确的方式使用中断来节省电能,因为这将是一个电池供电的设备。

使用轮询,我已验证正在设置对应的TX标志,并通过逻辑分析器验证从属设备确认了每个字节。 我无法理解为什么ISR不能运行。 下面的相关代码块:

USI_B初始化块:

//初始化USI_B0到标准速度I2C主模式。 PIN已分配给SCL和SDA。
UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC; // 7位寻址,单主
UCB0CTL1 || UCSSEL_2 | UCTR | UCSWRST; //发送器模式,来自SMCLK
UCB0BR1 =0; //将高波特率寄存器设置为0
UCB0BR0 = I2C_CLOCK_DIV; // 100KHz总线频率,源自16MHz SMCLK除以40
UCB0STAT = 0; //重置状态更改标记
IFG2 &=~(UCB0TXIFG | UCB0RXIFG); //重置传输和接收标记
UCB0I2CIE = UCNACKIE | UCSTPIE | UCSTIE | UCALEI;//为所有总线状态更改启用中断
IE2 |= UCB0RXIE | UCB0TXIE; //启用I2C接收和传输的中断(默认情况下启用传输)
UCB0I2CSA = 0; //将从属地址初始化为0
UCB0CTL1 &=~UCSWRST; //重置UCSWRST,启动I2C通信 
__bis_sr_register (GIE); //启用全局中断

I2C总线初始化环路:

同时(~status和MCP2.3018万_init){ //当MCP2.3018万未初始化时
如果(IFG2和UCB0TXIFG || INTERRUCK_TEST > 0){ //如果是加载TXBUFFER的时间
如果(~status & MCP2.3018万_init){ //如果MCP2.3018万未初始化:
如果(i2c_i > OLATB+1){ //如果这是最后一个寄存器之后的位:
I2C_I = 0; //重置i2c迭代器
UCB0CTL1 || UCTXSTP; //传输停止信号
status |= MCP2.3018万_init;
}
UCB0TXBUF = MCP2.3018万_INIT_DATA[i2c_i]; //将init数据数组中的相应字节放入TX缓冲区
I2C_I++; //递增i2c迭代
器}
}否则,如果(UCB0I2CSA ==0){ //否则:如果从地址为0
UCB0I2CSA = MCP2.3018万_opcode; //写入模式的加载从属地址+0
UCB0CTL1 || UCTXSTT; //发送I2C启动条件
} 如果(UCB0STAT和UCNACKIFG){ //如果收到了nack
UCB0STAT &=~UCNACKIFG; //清除标记
I2C_I = 0; //将地址迭代器重置为0
UCB0CTL1 || UCTXSTT; //设置启动条件
IFG2 |= UCB0TXIFG; //设置TX标志
} 
//__bis_sr_register (LPM0_bits + GIE);         //关闭CPU以节省电源,启用全局中断 } P1OUT |= BIT0; //初始化时亮起LED1

I2C数据ISR:

#pragma vector=USCIAB0TX_vector //由于USI_B处于I2C模式,因此这是I2C数据ISR
__interrupt void USICIAB0TX_ISR(void){ //如果USI_B TX寄存器为空或RX寄存器已满
__BIC_SR_REGISTER_ON_EXIT (LPM0_bits); //清除位以唤醒CPU
} //返回主环路 

I2C状态ISR:

#pragma vector=USCIAB0RX_vector //由于USI_B处于I2C模式,因此这是I2C状态ISR
__interrupt void USICIAB0RX_ISR(void){ //当I2C状态改变时
__BIC_SR_REGISTER_ON_EXIT (LPM0_bits); //清除位以唤醒CPU
} //返回主环路 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我的第一个建议是,您查看TI提供的I2C示例并通过在线社区获取,所示的代码摘录与典型的中断实现有很大的不同。

    此致,
    Ryan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我已经阅读了MSP430G2xxS系列的官方TI I2C示例。 我已经阅读了全部13个I2C示例,TimerA示例和P1示例。 我没有能力测试任何I2C示例,因为我没有任何其他MSP430G2553,任何TMP100传感器,PCF8574s或DAC8751s。

    我的实施是不同的,而且更加复杂,因为我无法让ISR运行! 因此,不能在ISR中放置任何有用的代码。 目前,我只是让I2C数据和I2C状态ISR尝试唤醒CPU,以测试是否可以运行它们。 您可能已经注意到,__bis_sr_register(LPM0_bits + GIE);被注释掉,因为ISR不会唤醒CPU。

    我的I2C实现完成了任务,但由于CPU总是轮询中断标志,因此效率不高。 我只是想弄清楚我的TimerA ISR为什么运行,端口1和2 ISR运行,但I2C ISR拒绝运行。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    抱歉,我忘记了包含逻辑分析器屏幕截图,这里是:以100KHz运行,I2C总线完全按预期工作,MCP2.3018万已初始化为正确状态,但ISR没有帮助。 我不得不在一段时间内循环,不仅要初始化MCP,还要从MCP发送和接收数据。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请获取msp430g2xxS 3_uscib0_i2c_06.c (或08.c),针对I2C时钟频率和从属地址进行修改,并确认从属设备响应其地址,但从未输入UCSCIAB0TX_ISR。

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

    这是以下代码的结果:

    /*--版权--,BSD_EX
    *版权所有(c) 2012,Texas Instruments Incorporated
    *保留所有权利。
    *
    *以源代码和二进制形式重新分发和使用,无论是否使用
    *允许进行修改,前提是满足以下条件
    满足*:
    *
    **重新分发源代码必须保留上述版权
    *注意,此条件列表和以下免责声明。
    *
    **以二进制形式重新分发必须复制上述版权
    *注意,此条件列表和中的以下免责声明
    *随分发提供的文档和/或其他材料。
    *
    **既不是德州仪器(TI)公司的名称,也不是的名称
    *其贡献者可用于支持或推广衍生产品
    *未经事先书面许可。
    *
    *本软件由版权所有者和贡献者"按原样"提供
    *和任何明示或暗示的担保,包括但不限于
    *对适销性和特定适用性的暗示担保
    *不承担目的。 在任何情况下,版权所有者或
    *贡献者对任何直接,间接,附带,特殊,
    *惩戒性或后果性损害(包括但不限于
    采购替代货物或服务;使用,数据或利润损失;
    (*或营业中断),但基于任何责任理论,
    *无论是合同,严格责任还是侵权行为(包括疏忽或
    *否则)因使用本软件而产生,
    *即使已被告知可能发生此类损害。
    *
    *****************
    *
    * MSP430代码示例免责声明
    *
    * MSP430代码示例是通常包含的低级程序
    *在高度中演示单个外设功能或器件功能
    *简明扼要。 为此,代码可能依赖于设备的默认开机设置
    *注册值和设置,如时钟配置和必须注意
    *在合并多个示例中的代码时使用,以避免潜在的问题
    效果。 另请参阅www.ti.com/grace以获取GUI和www.ti.com/msp430ware
    *用于API函数库方法的外围设备配置。
    *
    *--/copyright--*/
    //************************************************************************************************
    // MSP430G2xx3演示- USI_B0 I2C主TX单字节,用于MSP430从属设备
    //
    //说明:此演示通过I2C总线连接两个MSP430。 主控
    //传输至从属设备。 这是主代码。 不断地
    //传输00h,01h,...,0ffh,并演示如何实现I2C
    //主发送器使用USI_B0 TX中断发送一个字节。
    // ACLK = N/A,MCLK = SMCLK = BRCLK =默认DCO =~1.2MHz
    //
    //***与"msp430g2xxS 3_uscib0_i2c_07.c"***一起使用
    //
    ///|\/|\
    // MSP430G2xx3 10k MSP430G2xx3
    //从|||主
    //----------- ||--------------------
    //||Xin 1.7 –UCB0SDA|<-|---+->|WFP–1.7 –UCB0SDA|-
    //||||||
    //-|XOUT ||| XOUT|-
    //| WFP 1.6 / UCB.S.|<-++--- >|WFP 1.6 / UCB.S.|
    //|||||
    //
    // D. Dang
    //德州仪器(TI)
    // 2011年2月
    //使用CCS版本4.2 0和IAR嵌入式工作台版本:5.10 构建
    //************************************************************************************************
    #include <MSP4S.h>

    未签名的char TXData;
    未签名的char TXByteCtr;

    内部主(无效)

    WDTCTL = WDTPW + WDTHOLD;//停止WDT
    P1SEL || BIT6 + BIT7;//将I2C引脚分配给USI_B0
    P1SEL2|= BIT6 + BIT7;//将I2C引脚分配给USI_B0
    UCB0CTL1 || UCSWRST;//启用软件重置
    UCB0CTL0 = UCMST + UCMODE_3 + UCSNC;// I2C主控,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSWRST;//使用SMCLK,保持SW重置
    UCB0BR0 = 40;// fSCL = SMCLK/12 =~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = 32;//从属地址为32
    UCB0CTL1 &=~UCSWRST;//清除软件重置,恢复操作
    IE2 |= UCB0TXIE;//启用TX中断

    TXData = 0x00;//保存TX数据

    同时(1)

    TXByteCtr = 1;//加载TX字节计数器
    while (UCB0CTL1和UCTXSTP);//确保已发送停止条件
    UCB0CTL1 || UCTR + UCTXSTT;// I2C TX,启动条件
    __bis_sr_register(CPUOFF + GIE);//输入带中断的LPM0
    //保留在LPM0中,直到所有数据
    //已发送
    TXData++;//增量数据字节
    }
    }

    //------------------
    // USCIAB0TX_ISR的结构可用于传输任何
    //预加载具有字节计数的TXByteCtr的字节数。
    //------------------
    #if defined(__TI_Compiler_version__)|| defined(__IAR_SYSTEMS _ICC__)
    #pragma vector = USCIAB0TX_vector
    __interrupt void USCIAB0TX_ISR(void)
    #Elif已定义(__GMNU__)
    void __attribute__((interrupt (USICAB0TX_vector))) USICAB0TX_ISR (void)
    #否则
    错误编译器不受支持!
    #endif

    IF (TXByteCtr)//检查TX字节计数器

    UCB0TXBUF = TXData;//加载TX缓冲区
    TXByteCtr -;// Decrement TX字节计数器
    }
    否则

    UCB0CTL1 || UCTXSTP;// I2C停止条件
    IFG2 &=~UCB0TXIFG;//清除USI_B0 TX int标志
    __BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出LPM0
    }
    }

    从逻辑分析器上看,MSP好像睡了一觉,从未醒来。 这是否是SLAZ440H中USCI29描述的行为?

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

    解决了我自己的问题,在调试时,我看到PC被完全像在错误表中指定的那样捕获到TRAPINT_ISR中。 解决方法#1是猜测什么...轮询受影响的中断... 那时只能忍受低效率。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我很高兴看到您找到了问题的根源,尽管很遗憾,它是从勘误表中找到的。 感谢您为E2E社区提供解决方案。 希望您仍然能够通过减少通过I2C通信所花费的时间来最大限度地减少应用的功耗。

    此致,
    Ryan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我也很高兴Ryan,可能USCI的中断问题实际上是一种伪装的祝福。 在模块激活的情况下,MSP430可以进入的最低功耗状态是LPM0。 在LPM0中,MSP仍使用比我预期的LPM3状态高的整数数量级电流。

    USCI模块的问题毕竟不是那么糟糕。