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/MSP430FR2311:Software I²C 会导致 ISR 陷阱

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/685387/ccs-msp430fr2311-software-i2c-is-leading-to-isr-trap

器件型号:MSP430FR2311
主题中讨论的其他器件: MSP430FR2111

工具/软件:Code Composer Studio

大家好、

本指南 www.ti.com/.../slaa703.pdf 中的“Software I²C (软件)”出现问题 。  当我在 MSP430FR2311上执行时、它会在调用 timer_iteration()后进入 ISR 陷阱(有时它会循环并在进入陷阱之前多次调用此函数)。

我已将计时器更改为使用计时器 B (因为 MSP430FR2311没有计时器 A)、并保持引脚不变(软件 I²C 使用我所需的引脚)。

我的 main.c 如下所示:

#include 
#include 
#include 
#include "msp430_swi2c_master.h"

void main (void)
{
WDTCTL = WDTPW | WDTHOLD; //停止看门狗计时器

PM5CTL0 &=~LOCKLPM5; //禁用 GPIO 上电默认高阻抗模式
//激活先前配置的端口设置

//根据 MCLK 的器件数据表的要求配置一个 FRAM 等待状态
//在配置时钟系统之前在8MHz 以上运行。
FRCTL0 = FRCTLPW | NWAITS_1;

_bis_SR_register (SCG0); //禁用 FLL
CSCTL3 |= SELREF_REFOCLK; //将 REFO 设置为 FLL 基准源
CSCTL0 = 0; //清除 DCO 和 MOD 寄存器
CSCTL1 &=~(DCORSEL_7); //首先清除 DCO 频率选择位
CSCTL1 |= DCORSEL_5; //设置 DCO = 16MHz
CSCTL2 = FLLD_0 + 487; // DCOCLKDIV = 16MHz
_DELAY_CYCLES (3);
_BIC_SR_register (SCG0); //启用 FLL
while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1)); // FLL 锁定

CSCTL4 = SELMS_DCOCLKDIV | SELA_REFOCLK; //将默认 REFO (~32768Hz)设置为 ACLK 源,ACLK = 32768Hz
//默认 DCOCLKDIV 为 MCLK 和 SMCLK 源

SWI2C_I2CTransaction myTransaction;
uint8_t myBuffer[1]={0xFF};

/*初始化主设备*/
SWI2C_initI2C();

/*设置事务*/
myTransaction.address = 0x38;
myTransaction.writeBuffer = myBuffer;
myTransaction.numWriteBytes = 1;

if (!SWI2C_performI2CTransaction (&myTransaction))
{
/*此处处理错误代码*/
}

while (1);
}

代码挂起的部分位于 MSP430_swi2c_master.c 中

/*循环读取、直至所有位均已读取*/
操作
{
/*为临时变量添加初始值并发送时钟脉冲*/
temp =(temp << 1);
SWI2C_SCL_HIGH;
timer_iteration();

/*如果数据线为高电平,则记录该*/
IF (SWI2C_PxIN 和 SWI2C_SDA)
{
temp += 1;
}

/*发送另一个时钟周期并递减计数器*/
位=(位- 1);
SWI2C_SCL_LOW;
timer_iteration();
} 

我已经尝试将堆栈大小增加到1000kB (几乎整个 RAM)、但没有成功。 此外、我已经尝试修改 MSP430FR2111的源代码(可在本指南 http://www.ti.com/lit/an/slaa714/slaa714.pdfd 上找到)、结果是一样的。 是否缺少其他配置?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于我在任何地方都看不到任何中断被启用、我的第一个猜测是 NMI。 SYSSNIV 和 SYSUNIV 说什么?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    不确定对这些寄存器有什么期待、以前从未处理过...

    更新了:根据我的读数、有一个振荡器故障 IFG 和一个空的存储器访问 IFG。 因此、我更改了两次时钟、一次根本没有配置(因此默认值将生效)、另一次使用软件调整示例。 他们都不起作用。 至于 VMAIFG、我不知道我可以做什么。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我不太确定 VMAIFG 是如何出现在 SYSSNIV 中的、因为(根据惯例、至少) XXIV 寄存器只包含已启用的 IFG、并且我看不到 VMAIE 在任何位置被置位。

    话虽如此:我发现更令人不安的是,SWI2C 库正在查看的未初始化字段的数量--即使在使用 SLAA703示例 main()程序时也是如此。 发生故障的代码片段位于 SWI2C_ReadData 中、但您没有要求它读取任何内容、表明 numReadBytes (意外)不为0。 该函数使用尚未初始化的 readBuffer 指针存储字节(hmm、听起来像是 VMAIFG 的配方)。

    如果您将 myTransaction 设为全局变量、会有什么变化吗? 只是截取、对于原本未使用的字段、看起来像0是可以的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Bruce McKenney47378]\n 如果您将 myTransaction 设为全局变量、会有什么变化吗? 只是截取、对于原本未使用的字段、看起来像0是可以的。

    出于某种原因、代码以这种方式工作-在 numReadBytes 中输入0或将 myTransaction 设置为全局-(谢谢 btw)!

    编辑:发现全局变量初始化为0。 遗憾的是 、如果 没有这些修改、slaa703.pdf 中提供的示例代码将无法正常工作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、simple_example.c 不正确(我想这就是您得到它的位置)。 我想如果你把它从加电状态中运行、在堆栈任何脏东西之前、它"有效"、但它似乎可以使用更多的练习。