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/MSP432P401R:可以#39;t 使 I2C 以更高的时钟速率工作

Guru**** 2608555 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/650848/ccs-msp432p401r-can-t-get-i2c-working-at-higher-clock-rate

器件型号:MSP432P401R

工具/软件:Code Composer Studio

我在使用外部时钟时所做的任何操作、我似乎都无法使它正常工作。

我会得到非常奇怪的波形:

这里是我要使用的代码:

#include 
#include 

#include 

静态易失性 bool sendStopCondition;
静态无符号 char * TXData;
静态 long int ByteCtr = 0;
静态易失性 uint32_t xferIndex;

void i2c_init (void);
uint8_t i2c_send (uint8_t iConfig_num、unsigned char i2c_addr、unsigned char * i2c_dataset

);静态 I2C i2c_eConfig_unsigned char =
静态易失性 I2C
EUSCI_B_I2C_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
48000000、 // SMCLK = 3MHz
EUSCI_B_I2C_SET_DATA_RATE 100KBPS、//所需的 I2C 时钟
0、 //无字节计数器阈值
EUSCI_B_I2C_NO_AUTO_STOP //无自动停止
};

int main (void)
{
volatile uint32_t ii;

MAP_WDT_A_HOLDTimer();

MAP_CS_setExternalClockSourceFrequency (32768、48000000);
GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_PJ、GPIO_PIN0|GPIO_PIN1、GPIO_PRIMARY_MODULE_FUNCTION);//将 PJ.0设置为 LF 晶振的特殊输入
GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_PJ、GPIO_PIN2|GPIO_PIN3、GPIO_PRIMARY_MODULE_Function);//将 PJ.3设置为 HF 晶体的特殊输入
MAP_PCM_setCoreVoltageLevel (PCM_VCORE1);
MAP_FlashCtl_setWaitState (FLASH_BANK0、2);
MAP_FlashCtl_setWaitState (FLASH_BANK1、2);
MAP_CS_startHFXT (false);
CS_startLFXT (CS_LFXT_DRIVE3);//设置外部 LF 示波器,无旁路
//CS_initClockSignal (CS_ACLK、CS_LFXTCLK_SELECT、CS_clock_divider);//低频晶振上的 ACLK
CS_initClockSignal (CS_MCLK、CS_HFXTCLK_select、CS_clock_divider);高频晶体上的//MCLK
//CS_initClockSignal (CS_BCLK、CS_LFXTCLK_select、CS_clock_divider);//BCLK on LF 晶振
CS_initClockSignal (CS_SMCLK、CS_HFXTCLK_select、CS_clock_divider);高频晶体上的//SMCLK
//CS_initClockSignal (CS_HSMCLK、CS_HFXTCLK_select、CS_clock_divider);//Hf 晶振上的 HSMCLK


uint32_t clk1 = CS_getSMCLK ();
uint32_t clk2 = CS_getMCLK ();
uint32_t clk3 = CS_getACLK ();
uint32_t clk4 = CS_getBCLK ();
uint32_t clk5 = CS_getDCOFrequency ();
uint32_t clk6 = CS_getHSMCLK ();

I2C_init();

unsigned char channel_buf[3]={0xFF};
while (1)
{
对于(ii = 0;ii < 4000;i++);
I2C_SEND (3、0x75、CHANNEL _Buf);
}
}

void i2c_init (void)
{

MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P6、
GPIO_PIN6 + GPIO_PIN7、GPIO_secondary 模块功能);
MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P10、
GPIO_PIN2 + GPIO_PIN3、0x00);

MAP_I2C_initMaster (EUSCI_B3_base、&i2cConfig);

return;
}

uint8_t i2c_send (uint8_t i2c_num、unsigned char i2c_addr、unsigned char * i2c_data)
{
MAP_I2C_setSlaveAddress (EUSCI_B3_base、i2c_addr);
MAP_I2C_setMode (EUSCI_B3_base、EUSCI_B_I2C_Transmit);
MAP_I2C_enableModule (EUSCI_B3_base);
MAP_Interrupt_enableInterrupt (INT_EUSCIB3);
while (MAP_I2C_masterIsStopSent (EUSCI_B3_base)= EUSCI_B_I2C_Sending _stop);
TXData = i2c_data;
MAP_I2C_masterSendSingleByteWithTimeout (EUSCI_B3_base、TXData[0]、30);
MAP_I2C_DisableModule (EUSCI_B3_base);

返回0;
}

使 EUSCIB3_IRQHandler (void)
{无效
UINT_fast16_t 状态;
STATE = MAP_I2C_getEnabledInterruptStatus (EUSCI_B3_base);
MAP_I2C_clearInterruptFlag (EUSCI_B3_base、state);

IF (状态和 EUSCI_B_I2C_NAK_INTERRUPT)
{
MAP_I2C_masterSendStart (EUSCI_B3_base);
}

IF (状态和 EUSCI_B_I2C_Transmit INTERRUPT0)
{
/*检查字节计数器*/
IF (ByteCtr)
{
/*发送下一个数据并递减字节计数器*/
MAP_I2C_masterSendMultiByteNext (EUSCI_B3_base、* TXData++);
ByteCtr --;
} 其他
{
MAP_I2C_masterSendMultiByteStop (EUSCI_B3_base);
sendStopCondition = true;
MAP_Interrupt_disableSlepOnIsrExit();
}
}

如果我将 i2cConfig 变量更改为:

静态易失性 eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
3000000、 // SMCLK = 3MHz
EUSCI_B_I2C_SET_DATA_RATE 100KBPS、//所需的 I2C 时钟
0、 //无字节计数器阈值
EUSCI_B_I2C_NO_AUTO_STOP //无自动停止
};

并将 initClockSingals 更改为:

CS_startLFXT (CS_LFXT_DRIVE3);//设置外部 LF 示波器,无旁路
//CS_initClockSignal (CS_ACLK、CS_LFXTCLK_SELECT、CS_clock_divider);//低频晶振上的 ACLK
CS_initClockSignal (CS_MCLK、CS_HFXTCLK_select、CS_clock_divider);高频晶体上的//MCLK
//CS_initClockSignal (CS_BCLK、CS_LFXTCLK_select、CS_clock_divider);//BCLK on LF 晶振
CS_initClockSignal (CS_SMCLK、CS_HFXTCLK_select、CS_clock_divider);高频晶体上的//SMCLK
//CS_initClockSignal (CS_HSMCLK、CS_HFXTCLK_select、CS_clock_divider);//Hf 晶振上的 HSMCLK 

然后、我得到以下波形:

如果我现在完全注释掉时钟内容:

int main (void)
{
volatile uint32_t ii;

MAP_WDT_A_HOLDTimer();

/*
MAP_CS_setExternalClockSourceFrequency (32768、48000000);
GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_PJ、GPIO_PIN0|GPIO_PIN1、GPIO_PRIMARY_MODULE_FUNCTION);//将 PJ.0设置为 LF 晶振的特殊输入
GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_PJ、GPIO_PIN2|GPIO_PIN3、GPIO_PRIMARY_MODULE_Function);//将 PJ.3设置为 HF 晶体的特殊输入
MAP_PCM_setCoreVoltageLevel (PCM_VCORE1);
MAP_FlashCtl_setWaitState (FLASH_BANK0、2);
MAP_FlashCtl_setWaitState (FLASH_BANK1、2);
MAP_CS_startHFXT (false);
CS_startLFXT (CS_LFXT_DRIVE3);//设置外部 LF 示波器,无旁路
//CS_initClockSignal (CS_ACLK、CS_LFXTCLK_SELECT、CS_clock_divider);//低频晶振上的 ACLK
CS_initClockSignal (CS_MCLK、CS_HFXTCLK_select、CS_clock_divider);高频晶体上的//MCLK
//CS_initClockSignal (CS_BCLK、CS_LFXTCLK_select、CS_clock_divider);//BCLK on LF 晶振
CS_initClockSignal (CS_SMCLK、CS_HFXTCLK_select、CS_clock_divider);高频晶体上的//SMCLK
//CS_initClockSignal (CS_HSMCLK、CS_HFXTCLK_select、CS_clock_divider);//Hf 晶振上的 HSMCLK
*

uint32_t clk1 = CS_getSMCLK ();
uint32_t clk2 = CS_getMCLK ();
uint32_t clk3 = CS_getACLK ();
uint32_t clk4 = CS_getBCLK ();
uint32_t clk5 = CS_getDCOFrequency ();
uint32_t clk6 = CS_getHSMCLK ();

I2C_init();

unsigned char channel_buf[3]={0xFF};
while (1)
{
对于(ii = 0;ii < 4000;i++);
I2C_SEND (3、0x75、CHANNEL _Buf);
}
} 

我发现我得到的波形与上面相同、但是如果我将 i2cConfig 更改为400KBPS、那么我得到我想要的:

理想情况下、我希望以50Kbps 的速率运行(对于一些较慢的 I2C 器件)并使用外部48MHz 时钟。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Seth、
    在我看一下这个-您是否能够获得任何以100和400kbps 工作的预设示例?
    此致、
    Bob
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我对您的硬件更好奇。  

    1.您使用什么测量来获得图像?

    2.您在哪里测量以获得两种不同版本的信号?

    我的第一个猜测是您的示波器探头未校准。 电容调整稍微偏小。  

    如果探头在示波器校准信号上看起来不错、我的下一个问题是 I2C 线/线迹有多长、以及连接到它们的是什么?

    什么是上拉电阻器?

    有多少个器件?

    I2C 线路上是否有额外的电容?  



    第4个低电平底部信号中的毛刺脉冲使我想知道您的接地有多好。 (两个示波器探针接地端都连接到电路板上的良好接地端。 对吧?)  和/或您的电源在 IC 上具有足够的电容或足够的旁路电容器。  

    基普



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

    Bob、

    所有预设示例似乎都可以正常工作。 当我将 MSP432切换为使用外部时钟时、会发生该问题。

    Kip、

    我使用 Saleae 进行测量。 我在 I2C 多路复用器芯片上进行探测(地址为0x75)。 我知道它不起作用(也不是探测问题)、因为除非我以400KBPS 的频率以3MHz 运行、否则不会设置多路复用器。

    我有10k 上拉电阻器、我在400KBPS 时使用3MHz 的频率已有很长一段时间、现在没有任何问题。

    但是、如果您对此不满意、我尝试将代码上传到 TI Launchpad、并将探针直接连接到引脚。 我遇到相同的问题。

    是的、干扰可能只是一个坏的接地、但这还不足以让我担心我会停止接收信号。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    "我有10K 上拉电阻器"。
    对于快速 I2C 速度、您可能需要重新考虑这一点。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我想您遇到硬件问题而不是软件问题。

    尝试使用一个较低值的上拉电阻器、如 Mike 建议的那样。 我希望信号中不会出现毛刺脉冲和较小的边沿。

    我可能会尝试1K、看看它是如何工作的。

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

    您是否能够解决此问题?

    我还想补充一点、虽然 eUSCI I2C 模块可以提供 SMCLK-HFXT、但最大模块时钟限制为24MHz。
    根据数据表第5-25-10节、第80页: www.ti.com/.../msp432p401r.pdf

    我在您的代码中看到您设置了一些分频器、不确定您是否在使用它们。

    在将 SMCLK 提供给 USCI 模块之前、您需要设置 SMCLK <=24MHz。

    -Priya
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    检查以查看是否可以解决此问题。

    此致、
    Chris