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.

[参考译文] MSP432P401R:在默认3MHz以外的其他时钟速度下使用i2c时出现问题。

Guru**** 2539500 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/575811/msp432p401r-problems-using-i2c-at-other-clock-speeds-other-than-default-3mhz

部件号:MSP432P401R
主题中讨论的其他部件:BQ2.7441万-G1

大家好,

我目前正在尝试使用BQ2.7441万-G1燃油表进行通信,并使用技术参考手册第11页中的步骤编辑设计容量(以下链接)。

http://www.ti.com/lit/ug/sluuac9/sluuac9.pdf  

现在,根据我目前所写的内容(如下所示),我已经能够 成功地将新的设计容量写入BQ2.7441万-G1。


//驱动程序库 #include "driverlib.h"
//标准库包括 #include <stdbool.h> #include <string.h>
// BQ2.7441万燃油表工具包
#include "BQ2.7441万_Definitions.h" #include "FuelGauge.h" // I2C主配置参数 const eUSI_I2C_MasterConfig i2cConfig = { EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK时钟源 300万, // SMCLK = 3MHz EUSCI_B_I2C_SET_DATA_RATE_100KBPS, //所需的I2C时钟为100kHz 0, //无字节计数器阈值 EUSCI_B_I2C_NO_AUTO_STOP //无自动停止 }; int main(void){ //禁用监视程序 MAP_WDT_A_HoldTimer(); MAP_GPIO_setAsPeripheralModuleFunctionInputPin (I2Cport,SDApin + SCLPin,GPIO主要模块功能); //为I2C选择端口6 -设置引脚4,5 MAP_I2C_INITMaster (EUSCI_MODULE,&i2cConfig); //在100kbs的速度下将I2C主设备初始化到SMCLK,不带自动停止功能 MAP_I2C_setSlaveAddress (EUSCI_MODULE,BQ2.7441万_I2C_ADDRESS); //指定从属地址 MAP_I2C_setMode (EUSCI_MODULE,EUSCI_B_I2C_Transmit_MODE); //将主中继器设置为传输模式 MAP_I2C_enableModule (EUSCI_MODULE); //启用I2C模块以启动操作 MAP_I2C_clearInterruptFlag (EUSCI_MODULE,EUSCI_B_I2C_Transmit_INTERRUPT0 + ESCI_B_I2C_receive _INTERRUPT0); //启用和清除中断标志 MAP_Interrupt_enableInterrupt (EUSCI_moduleINT); //启用主接收中断 UINT16_t BatCapacity = 1200;// mAh FuelGauge SetBatteryCap (BatCapacity); Int batteryCap = FuelGauch_GetBatteryCap(); Int stateOfCharge = FuelGauch_GetStateOfCharge (); Int voltage = FuelGauch_GetVoltage(); 同时(1);}

其中FuelGauch_SetBatteryCap()是我写的一个函数,基本上遵循第11页上的步骤。 其他职能部门也会发送相应的推荐,以了解其名称的含义。

当我尝试通过添加driverlib命令将DCO时钟频率设置为非默认值时,会出现问题...

MAP_CS_setDCOFrequency(800万); //将DCO (时钟)设置为指定的时钟速度
MAP_CS_INITICClockSignal (CS_SMCLK,CS_DCOCLK_SELECT,CS_CLock_DICROLOR_1);	//将SMCLK连接到DCO 

以及更改I2C配置中的频率...

// I2C主配置参数
const eUSI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK时钟源
	800万, // SMCLK = 8MHz
EUSCI_B_I2C_SET_DATA_RATE_100KBPS, //所需的I2C时钟为100kHz
0, //无字节计数器阈值
EUSCI_B_I2C_NO_AUTO_STOP //无自动停止
}; 

我的函数FuelGauch_SetBatteryCap()将尝试从BQ2.7441万-G1 (步骤7)检索旧校验和值,并得到0x00,这是意外的。 然后在计算新校验和时
根据此值并发送到BQ2.7441万-G1 (步骤11),它不会确认。

我更改导致I2C故障的DCO频率的方式是否有问题? 在设计容量设置过程中出现故障的时刻是否与此相关?

提前感谢!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很抱歉出现格式错误。 我对发布有一点点新的感觉。 最后一个代码块上的文本是...

    " My Function FuelGauch_SetBatteryCap()将尝试从BQ2.7441万-G1 (步骤7)检索旧校验和值,并得到0x00,这是意外的。 然后,当根据此值计算新校验和并发送到BQ2.7441万-G1 (步骤11)时,它不会确认。 我更改导致I2C故障的DCO频率的方式是否有问题? 在设计容量设置过程中出现故障的时刻是否与此相关?

    提前感谢!"
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    奥斯汀,
    您是否看过此设置DCO的示例? dev.ti.com/.../

    我很好奇您是否使用以下行:

    /*为DCO频率计算启用FPU */
    MAP_FPU_enableModule();

    /*将DCO频率设置为非标准8MHz */
    MAP_CS_setDCOFrequency(800万);

    中心频率为48,24,12,6,3, 和1.5。 8MHz需要计算。 也可以通过输出到引脚(引脚4.4 上的HSMCLK)来验证SMCLK的频率。

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

    您好,Chris:

    因此,我使用您建议的添加行运行下面的代码,而与燃油表的I2C通信仍在同一点失败。  

    //驱动程序库
    #include <driverlib.h>//
    标准库包括
    #include <stdbool.h>
    #include <string.h>//
    BQ2.7441万燃料计的工具包
    #include "FuelGauge.h"
    #include "atlers.h"
    
    // I2C主配置参数
    const eUSI_I2C_MasterConfig i2cConfig ={
    
    EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK时钟源
    		800万, // SMCLK = 8MHz
    EUSCI_B_I2C_SET_DATA_RATE_100KBPS, //所需的I2C时钟为100kHz
    0, //无字节计数器阈值
    EUSCI_B_I2C_NO_AUTO_STOP //无自动停止
    };
    
    int main(void){
    
    
    //禁用监视程序
    MAP_WDT_A_HoldTimer();
    
    MAP_FPU_enableModule();
    
    MAP_CS_setDCOFrequency(800万);//将DCO (时钟)设置为指定的时钟速度
    MAP_CS_initClockSignal (CS_SMCLK,CS_DCOCLK_SELECT,CS_CLock_diver_1);	//将SMCLK连接到DCO
    
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin (I2Cport,SDApin + SCLpin,GPIO_primary_module_function);		//为I2C选择端口6 -设置引脚4,5
    MAP_I2C_INITMaster (EUSCI_MODULE,&i2cConfig); 		//在100kbs的速度下将I2C主设备初始化到SMCLK,不带自动停止功能
    MAP_I2C_setSlaveAddress (EUSCI_MODULE,BQ2.7441万_I2C_ADDRESS);	//指定从属地址
    MAP_I2C_setMode (EUSCI_MODULE,EUSCI_B_I2C_Transmit_MODE);		//将主中继器设置为传输模式
    MAP_I2C_enableModule (EUSCI_MODULE);			//启用I2C模块以启动操作
    MAP_I2C_clearInterruptFlag (EUSCI_MODULE,EUSCI_B_I2C_Transmit_INTERRUPT0 + ESCI_B_I2C_receive _INTERRUPT0);	//启用和清除中断标志
    MAP_Interrupt_enableInterrupt(EUSI_moduleINT);		//启用主接收中断
    
    MAP_Interrupt_enableMaster();
    
    UINT16_t BatCapacity = 1000;// mAh
    
    FuelGauge SetBatteryCap (BatCapacity);
    Int batteryCap = FuelGauch_GetBatteryCap();
    Int stateOfCharge = FuelGauch_GetStateOfCharge ();
    Int voltage = FuelGauch_GetVoltage();
    
    同时(1);}
    

    我还运行了您推荐的DCO设置示例,以确保SMCLK频率正确,当设置为8 MHz时,我以大约805.8017万 Hz的频率进行测量,这似乎足够接近。  

    当我不小心将i2cConfig中的时钟频率设置为 800万,并将DCO频率设置为3MHz时,我设法使上述代码正常工作,但我无法解释。 我第二次核实了这些条件,结果似乎一致。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    奥斯汀,
    我尝试了几个示例,但通过更改频率未发现问题。 我在您的评论中看到您正在尝试启用接收中断,尽管我没有看到API调用MAP_I2C_enableInterrupt (EUSSCI_B0_BBASE,EUSCI_B_I2C_Receive_INTERRUPT0);。 另外,我确实看到您选择EUSCI以传输模式,而不是接收模式:MAP_I2C_setMode(EUSSCI_B0_BBASE,EUSCI_B_I2C_Receive_mode);。

    传输和接收功能是否在3MHz下都正常工作,然后当您将DCO移动到8MHz时,只有传输功能才工作?

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

    在FuelGauge SetBatteryCap()函数内,我执行多字节传输,然后将模块设置为接收模式,并使用中断仅接收(以下代码片段)。 很抱歉未包含这一点。

    void FuelGauge SetBatteryCap (uint16_t batCap)
    {//-----------
    
    	传输-----------
    	EUSCI_TXBuffer &= 0x00; //清除传输缓冲
    	区MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE,BQ2.7441万_COMMAND_CONTROL);
    	MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE,BQ2.7441万_CONTAC_DEVICE_TYPE);
    	MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE, 0x00);
    	MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE);
    
    	EUSCI_TXBuffer &= 0x00; //清除传输缓冲
    	区map_I2C_masterSendSingleByte(EUSSCI_MODULE,0x00);
    
    	//---- 接收----------- //**************** 注意*************************
    	num_of_rec_bytes = 2; // NUM_OF_REC_Bytes仅接受2或更大的值
    	MAP_I2C_setMode (EUSCI_MODULE,EUSCI_B_I2C_RECEIVE_MODE); //设置为接收模式
    	MAP_I2C_masterReceiveStart(EUSSCI_MODULE); //开始接收
    	MAP_I2C_enableInterrupt (EUSCI_MODULE,EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断
    	xferIndex =0; //
    	将RXData索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志
    	rxFlag =0; 

    但是,为了回答您的问题,接收和传输功能在3 MHz下都能正常工作(不调用setDCOFrequency()),我可以通过整个序列(电量监测程序)完成,但是如果我包括设置DCO频率的调用,就可以正常工作 (无论是3 MHz还是8 MHz),I2C通信工作,但在编辑电量监测计的存储器时会在非常特定的点停止。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很抱歉回复延迟。 请参阅以下主题中的讨论和示例: e2e.ti.com/.../211.7452万

    此致,
    Chris