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.

[参考译文] MSP430FR2433:来自Walter Schurr的I2C代码不起作用。

Guru**** 2609195 points
Other Parts Discussed in Thread: MSP430F5329, MSP-EXP430FR2433

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/655362/msp430fr2433-i2c-code-from-walter-schurr-does-not-work

部件号:MSP430FR2433
主题中讨论的其他部件:MSP-EXP430FR2433MSP430F5329
//=============================================================================================================

#include "MSP4S.h"
#include "driverlib.h"

#define DCOFREQ 800万

#define I2C_0_BBASE (EUSI_B0_Bbase)
#define I2C_RECEIVE_BUFFER_SIZE (32)

uint8_t I2C_0_rxBuffer[I2C_RECEIVE_BUFFER_SIZE];
INT8_T_0_rxBytesaining_0 = I2C_0




EUSCI_B_I2C_initMasterParam I2C_0;

// SMCLK = MCLK = DCO = 4MHz
// ACL = 32kHz
Cs_initClockSignal (CS_FLLREF,CS_REFOLCLK_SELECT,CS_CLock_diver_1);
cs_initClockSignal (CS_ACLK,CS_REFOLCLK_SELECT,CS_CLock_diver_1);
cs_initClockSignal (CS_MCLK,CS_DCOCLKDIV_SELECT,CS_CLock_DICROLATER_1);
cs_initClockSignal (CS_SMCLK,CS_DCOCLKDIV_SELECT,CS_CLock_diver_1);
cs_initFLL(DCOFREQ/1000),DCOFREQ/3.2768万);
cs_clearAllOscar FlagsWithTimeout (1000);

// I2C端口多路复选
P1OUT = 0;
P1DIR || BIT0 | BIT1 | BIT4 | BIT5 | BIT6;
P1SEL0 || BIT2 | BIT3;
PM5CTL0 &=~LOCKLPM2;

// I2C设置
I2C_0.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
I2C_0.i2cClk = DCOFREQ;
I2C_0.datarate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
I2C_0.byteCounterThreshold = 0;
I2C_0.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;

EUSCI_B_I2C_DISABLE (I2C_0_BASE);
EUSCI_B_I2C_initMaster (I2C_0_BASE,&I2C_0);
EUSCI_B_I2C_ENABLE (I2C_0_BASE);

__delay_cycles(800万);
}

uint8_t I2C_0_readCmd (uint8_t slaver, uint8_t cmd)
{
P1OUT || BIT0 | BIT4 | BIT5 | BIT6;

//设置从属地址并等待总线
EUSCI_B_I2C_setSlaveAddress (I2C_0_BASE,从机);
EUSCI_B_I2C_clearInterrupt (I2C_0_BASE,
EUSCI_B_I2C_receive _INTERRUPT0 |\
EUSCI_B_I2C_Transmit_INTERRUPT0 |\
EUSCI_B_I2C_STOP_INTERRUPT);
EUSCI_B_I2C_enableInterrupt (I2C_0_BASE,
EUSCI_B_I2C_receive _INTERRUPT0 |\
EUSCI_B_I2C_STOP_INTERRUPT);
I2C_0_rxBytesRemaining = 0;

//写入命令到从属设备
EUSCI_B_I2C_setMode (I2C_0_BASE,EUSCI_B_I2C_Transmit_mode);
EUSCI_B_I2C_masterSendMultiByteStart(I2C_0_Base,cmd);
while (!(EUSCI_B_I2C_getInterruptStatus (I2C_0_BASE,EUSCI_B_I2C_Transmit_INTERRUPT0)))
{
IF (EUSCI_B_I2C_getInterruptStatus (I2C_0_BASE,EUSCI_B_I2C_NAK_INTERRUPT))
{

返回0;}

}

//从从属设备读取响应
EUSCI_B_I2C_masterReceiveStart (I2C_0_BASE);
同时(EUSCI_B_I2C_isBusy (I2C_0_BASE));
EUSCI_B_I2C_DisableInterrupt (I2C_0_BASE,
EUSCI_B_I2C_receive _INTERRUPT0 |\
EUSCI_B_I2C_STOP_INTERRUPT);

P1OUT &=~BIT0;
返回I2C_0_rxCnt;
}

void run (void)
{
I2C_0_readCmd (0x0B,0x02);
__no_operation();
__delay_cycles(100万);
}

void main(void)
{
WDTCTL = WDTPW | WDTHOLD;
__enable_interrupit();
Setup();
同时(1)
{
run();
}
}

#pragma vector=USI_B0_vector
__interrupt void I2C_0_ISR(void)
{
UINT8_t数据;

P1OUT || BIT1;
Switch(__偶 数_in_range(UCB0IV,0x1E))
{
0x00:中断; //向量0:无中断中断;
案例0x02:中断; //矢量2:ALIFG中断;
0x04:中断; //矢量4:NACKIFG中断;
判例0x06:中断; //矢量6:STT IFG中断;
案例0x08:
P1OUT &=~BIT5;
中断; //矢量8:STPIFG中断;
0x0a:中断; //矢量10:RXIFG3中断;
0x0c:中断; //矢量14:TXIFG3中断;
0x0E:中断; //矢量16:RXIFG2中断;
0x10:中断; //矢量18:TXIFG2中断;
0x12:中断; //矢量20:RXIFG1中断;
0x14:中断; //矢量22:TXIFG1中断;
案例0x16: //矢量24:RXIFG0中断;
//接收字节
数据= EUSCI_B_I2C_masterReceiveMultiByteNext(I2C_0_BASE;

//如果这是第一个字节(RX长度无效),则保存要读取的长度
//并将接收计数器重置为0
IF (I2C_0_rxBytesRemaining == 0x00)
{
I2C_0_rxBytesRemaining =数据;
IF (I2C_0_rxBytesRemaining > I2C_Receive_buffer_size)
{
I2C_0_rxBytesRemaining = I2C_Receive_buffer_size
;}
I2C_0_rxCnt = 0;
}

//如果这不是第一个字节,则将响应附加到RX
//缓冲区
否则
{
I2C_0_rxBuffer[I2C_0_rxCnt++]=数据;
I2C_0_rxBytesRemaining--;
}

//在最后一个字节进入时发送nack和stop
IF (I2C_0_rxBytesRemaining == 1)
{
P1OUT &=~BIT4;
EUSCI_B_I2C_masterReceiveMultiByteStop(I2C_0_BASE);
}
中断;
0x18:中断; //矢量26:TXIFG0中断;
0x1a:中断; //矢量28:BCNTIFG中断;
0x1c:中断; //矢量30:时钟低超时中断;
案例0x1E:中断; //矢量32:第9位中断;
默认值:break;
}

P1OUT &=~BIT1;
} 


我从Walter那里得到了这个代码,它位于“MSP430F5329: How do you send a NAK in I2C SMBus Protocol”(MSP430F5329:如何在I2C SMBus协议中发送NAK)  

帖子。  

我以为我理解了它并用它来编写我的代码。 我的代码中没有得到任何SDA或SCL引脚移动。 所以我决定从Walter的"工作代码"开始,慢慢迁移到我的应用程序。  

在主要程序中

void main (void)
{
WDTCTL = WDTPW | WDTHOLD;
__enable_interrupit();
Setup();
同时(1)
{
run();
}
} 

我不编译任何警告或错误。  

当我单步进入setup();时,它似乎在__enable_Interrupt()之后失控。  

拆卸看起来像是对#setup的有效调用

但它跳至00C400 __program_start



为什么要这样做?

这是看门狗计时器吗? 或者其他中断未处理?  

我很困惑。 我正在将MSP-EXP430FR2433与IAR编译器配合使用。  

谢谢!

基普

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在MSP-EXP430FR2433的演示代码中,他们使用此代码来停止监视计时器。

    /*停止监视计时器*/
    WDT_A_HOLD (WDT_A_BASE);

    我把它放在__enable_interrupt ()之前,并注释掉//WDTCTL = WDTPW | WDTHOLD;

    而进入setup()的一个步骤:从未返回。 我看不出来它去了哪里。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    void main (void)
    {
    //WDTCTL = WDTPW | WDTHOLD;
    /*停止监视计时器*/
    WDT_A_HOLD (WDT_A_BASE);
    Setup();
    __enable_interrupit();
    
    同时(1)
    {
    run();
    }
    } 

    我修改了main,在setup()之后放置enable中断;

    我能够完成设置,但它从未从单步返回到run();

    我猜有一些中断正在触发,但没有得到处理。 默认情况下打开哪些中断?

    基普

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

    您好,Kip:

    我将通过IAR来尝试。  我当时在自己的一边使用CCS进行构建。  CCS有一个中断请求陷阱,但没有定义处理程序;我不确定IAR是否有。  在这两种情况下,我都应该在自己的身边看到它,因为我最终会陷入CPU陷阱。

    沃尔特

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

    我能够在IAR中成功地运行,并使用代码按“现在”到达第86行,没有任何奇怪的问题。  从您的解释来看,我假设您的硬件 不能做到这一点?  您是否有任何其他设备连接到LaunchPad?  在设置中,我将GPIO引脚配置为输出;这可能与其他一些布线冲突,并造成其他一些问题。

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

    我唯一挂接到电路板上的是SDA,SCL和MSP430F5329接地板。 因此,我断开了电缆连接,现在只有USB电缆连接到MSP-EXP430FR2433。

    同一问题。

    我当时查看的IDE和“强制单步进”,“启用/禁用GIE位”,“强制RTS/NMI”和“时钟控制”的图标在停止响应时都闪烁。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

     我在我的项目中欺骗了,但仍然有其他文件,并且在main.c中的所有其他代码中使用了#if 0和#endif,而不是您的代码。

    所以我从项目中删除了所有其他文件,从main.c中删除了所有其他行,但仍然存在相同的问题。

    所以我做了和你看起来完全一样的事。 我在run() 和run子例程的第一行设置了断点。

    当我说Go时,拆卸在__program_start停止:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    只是想把我所有的基础都覆盖了。 我有两个调试程序连接到我的计算机。 (Windows 10)工作区知道这一个在COM4,另一个在COM7。

    已断开另一个连接,并在项目的"选项"中按出厂设置。
    没有区别。 同样的问题。

    我现在对下一步要做什么感到很不了解。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我尝试了最后一件事。

    我从计算机上的USB端口拔下MSP-EXP430FR2433,然后重新插入。

    现在它开始工作了。

    因此,从调试器中进行重置的方式与关闭电源后重启时的方式不同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    最新更新。

    我通过I2C将e MSP-EXP430FR2433连接到使用MSP430F5329的主板。

    我将速度设置为100 kbps,从地址设置为0x16,并设置了命令0x20 (这是我的第一个SMBus块读取命令),它就工作了!

    现在,对代码进行更彻底的测试。 感谢你的所有帮助。

    基普