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.

[参考译文] MSP430F5438A:I2C 通信问题

Guru**** 2587345 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1125641/msp430f5438a-i2c-communication-problem

器件型号:MSP430F5438A

大家好。

我的项目是通过 I2C 通信发送和接收1个字节与一个 MSP430通信。

我已配置 UCB0 I2C (P3.1、P3.2、主器件)、UCB1 I2C (P3.7、P5.4)、传输速度为400Kbps、SMCLK 为1MHz。  

我已经使用 CCS 的 driverlib 进行编码。

它在工作。 但也有 问题。  

蓝色为 I2C_SDA、黄色为 I2C_SCL。

1) 1) SCL 的频率为203.2KHz。 我认为 I2C_SCL 应该接近400KHZ。 因为我设置 了400Kbps。

USCI_B_I2C_initMasterParam I2cParam0 = {0,};
I2cParam0.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK;
I2cParam0.i2cClk = UCS_getSMCLK();
I2cParam0.dataRate = USCI_B_I2C_SET_DATA_RATE_400KBPS;

USCI_B_I2C_initMaster(USCI_B0_BASE, &I2cParam0);

2) 2) 1位在数据地址和 NACK 之间是什么意思?

3) 3)  NACK 数据信号通常是短路吗? 无法为1个时钟保持 NACK 值。

这是我的代码。

#include <MSP430.h>
#include <MSP430F5xx_6xx/driverlib.h>

uint8_t transmitData = 0x52;
uint8_t receiveData;
/**
 * main.c
 */
void main(void)
{
	WDT_A_hold(WDT_A_BASE);// stop watchdog timer

	initGPIO();
	initClock();
	initI2C();

	__bis_SR_register(GIE);
	while(1)
	{
		USCI_B_I2C_masterSendSingleByte(USCI_B0_BASE, transmitData);

		while(USCI_B_I2C_isBusBusy(USCI_B0_BASE));

		//__delay_cycles(50);

		transmitData++;
	}
}



#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
	switch(__even_in_range(UCB1IV, 0x0A)){
		case 0x0A:
			receiveData = USCI_B_I2C_slaveGetData(USCI_B1_BASE);
			break;
	default: //__never_executed();
	break;
	}
}
#include <MSP430F5xx_6xx/driverlib.h>

// Clock
#define XT1CLK_HZ 32768
#define XT2CLK_HZ 32768
#define DESIREDMCLK_KHZ 1000
#define MCLKXT1CLKRATIO	DESIREDMCLK_KHZ/(XT1CLK_HZ/1024)

// I2C Slave
#define SLAVEADDRESS 0x51

uint32_t myACLK, mySMCLK, myMCLK;


void initGPIO(void)
{
	//Configurate oscillator 
	GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P7, GPIO_PIN0 + GPIO_PIN1);

	//Configurate I2C
	GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN1 + GPIO_PIN2 + GPIO_PIN7);
	GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);

	//Configurate SMCLK
	//GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P11, GPIO_PIN2);
}

	

void initClock(void)
{
	PMM_setVCore(PMM_CORE_LEVEL_3);

	UCS_setExternalClockSource(XT1CLK_HZ, XT2CLK_HZ);
	UCS_turnOnLFXT1(XT1DRIVE_0, XCAP_3);

	UCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);

	//Configurate FLL

	UCS_initClockSignal(UCS_FLLREF, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);
	UCS_initFLL(DESIREDMCLK_KHZ, MCLKXT1CLKRATIO);

	myACLK = UCS_getACLK();
	mySMCLK = UCS_getSMCLK();
	myMCLK = UCS_getMCLK();
}

void initI2C(void)
{
	USCI_B_I2C_initMasterParam I2cParam0 = {0,};
	I2cParam0.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK;
	I2cParam0.i2cClk = UCS_getSMCLK();
	I2cParam0.dataRate = USCI_B_I2C_SET_DATA_RATE_400KBPS;

	USCI_B_I2C_initMaster(USCI_B0_BASE, &I2cParam0);
	USCI_B_I2C_initSlave(USCI_B1_BASE, SLAVEADDRESS);

	USCI_B_I2C_setSlaveAddress(USCI_B0_BASE, SLAVEADDRESS);

	USCI_B_I2C_setMode(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_MODE);
	USCI_B_I2C_setMode(USCI_B1_BASE, USCI_B_I2C_RECEIVE_MODE);

	USCI_B_I2C_enable(USCI_B0_BASE);
	USCI_B_I2C_enable(USCI_B1_BASE);

	USCI_B_I2C_clearInterrupt(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT);
	USCI_B_I2C_clearInterrupt(USCI_B1_BASE, USCI_B_I2C_RECEIVE_INTERRUPT);

	USCI_B_I2C_enableInterrupt(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT);
	USCI_B_I2C_enableInterrupt(USCI_B1_BASE, USCI_B_I2C_RECEIVE_INTERRUPT);
}

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

    2) 2)我在 地址和 ACK 之间看到一个0位(写入)。 上升沿(SCL)是重要时刻、而不是下降沿。

    3)右侧 SDA 上的"跳跃"实际上是一个 ACK (再次为:上升沿)。 主器件释放了数据线、该数据线在从器件将其置为有效之前被短暂上拉。

    1) 1)[E] USCI 只有一个简单的整数时钟分频器(br0/1)、因此您无法实现某些总线速度。 借助1MHz SMCLK、您可以获得250/333/500kHz (br0=4/3/2)。 Driverlib 的算术会截断、因此它始终生成大于或等于请求的时钟(我个人对此不同意)。 SET_DATA_RATE 400KHZ 定义只是400000UL、因此、如果您用300000UL 等替代、您将得到333kHz。 或者、如果您可以以8MHz 的频率运行 CPU (真正的 SMCLK)、则可以得到恰好为400kHz (br0=20)的频率。

    也就是说、这里还有另外一件更微妙的事情(可能)。 我在一段时间后使用 EUSCI (与您的 USCI 很常见)进行了一些实验、并观察到当我提高 I2C 时钟速度时、我达到了(实际)时钟减慢的程度。 我的假设是、当 检测到 I2C 单元的内部时钟监控器的运行速度超过允许的 I2C 规范时、它将后退(以 br0为单位)。 我很确定我在论坛中报告了这一点、但我现在没有找到它。 这不是错的、但这对我来说有点惊喜。

    [编辑:少量澄清。]

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

    我很抱歉回复得太晚了。

    我想在我的写作中做一些更正。

    它从数据地址更改为数据。  

    我在看到您的回答后有几个问题。 (2、3个问题)

    1) //这不是问题。

    我将 SMCLK 设置为1MHz、 将 I2C 设置为400KBps (实际上 SMCLK 为1.013~1.02MHz)。 在调试模式下、UCBRW 为0x0002。

    我的频率为 250kHz 、但我得到203kHz。  

    那么、在这个感测中

    [引用 userid="47378" URL"~μ C/support/microcontrollers/msp-low-power-microcontrollers-group/msp430-low-power-microcontroller-forum/1125641/msp430f5438a-i2c-communication-problem /4175142#4175142"] Driverlib 的算术截断函数、因此它不同意或不同意此引用(本人)。

    我也同意你的意见。

    2)问题


    我的代码是 发送和接收1个字节、以便通过 I2C 通信与一个 MSP430进行通信。

    在上图中、数据部分中没有 R /\W。  

    您在我所做的更正中的回答是否正确?

    3)  问题

    这种 ACK 或 NACK 位于 SDA 上的"跳跃"位置是否在右侧? (介于?? 和 SP)