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:Problemwith i2c、将函数从 eusci_b0导入到 eusci_B1

Guru**** 2597975 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/648108/ccs-msp432p401r-problemwith-i2c-importing-function-from-eusci_b0-to-eusci_b1

器件型号:MSP432P401R

工具/软件:Code Composer Studio

大家好、我之前使用了一些用于 i2c 的函数、在我的实际硬件中、我必须更改用于通信的引脚、因此我使用了与用于 eusci_B0相同的函数、并更改了 eusci_B1的值、它们不起作用、 SCL 始终为0V、我无法理解原因。

//
#include 
#include 
//#include "msp432.h"
#include "i2c_driver.h"
/* DriverLib 定义了*/
#include 

//
////
定义
//
//*********

typedef 枚举{
eUSCI_IDLE = 0、
eUSCI_SUCCESS = 0、
eUSCI_BUSY = 1、
eUSCI_NACK = 2、
eUSCI_STOP、
eUSCI_START
}eUSCI_STATUS;

//*********
//
//全局数据
//
//*********
易失性 eUSCI_STATUS ui8Status;

uint8_t * pData;
uint8_t ui8DummyRead;
uint32_t g_ui32ByteCount;
bool BurstMode = false;
eUSCI_I2C_MasterConfig* configPtr;

/* I2C 主配置参数*/
volatile eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
0、
EUSCI_B_I2C_SET_DATA_RAM_100KBPS、 //所需的100kHz I2C 时钟
0、 //无字节计数器阈值
EUSCI_B_I2C_SEND_STOP_INALOCK_BYTECOUNT_T_THRESHOLD //自动停止
};


//
//导入的数据
//


//////常量
//


////函数原型
//

//////函数:

void initI2C (void)
{
// I2C 时钟同步速度*/
i2cConfig.i2cClk = map_CS_getSMCLK ();
//setI2cClk (map_CS_getSMCLK ());

/*为 I2C_SCL (P6.5)和 I2C_SDA (P6.4)选择 I2C 功能-修改了*/
GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_P6、GPIO_PIN5 | GPIO_PIN4、
GPIO_PRIMARY_MODULE_FUNCTION);

//getI2cConfig (&configPtr);

/*使用自动停止将 I2C 主设备初始化为 SMCLK,速度为400kbs */
MAP_I2C_initMaster (EUSCI_B1_base、&i2cConfig);
//map_I2C_initMaster (EUSCI_B1_base、configPtr);
}

/*********
函数:
*/
bool writeI2C (uint8_t ui8Addr、uint8_t ui8Reg、uint8_t *数据、uint8_t ui8ByteCount)
{
//等待写入准备就绪
while (MAP_I2C_isBusBusy (EUSCI_B1_base));

//将数据分配给本地指针
pData =数据;

//禁用 I2C 模块进行更改
MAP_I2C_DisableModule (EUSCI_B1_base);

//设置要发送的字节数+ 1以考虑寄存器字节
i2cConfig.byteCounterThreshold = ui8ByteCount + 1;
MAP_I2C_initMaster (eUSCI_B1_base、(const eUSCI_I2C_MasterConfig *)&i2cConfig);

//加载器件从器件地址
MAP_I2C_setSlaveAddress (eUSCI_B1_base、ui8Addr);

//启用 I2C 模块以启动操作
MAP_I2C_enableModule (EUSCI_B1_BASE);

//启用主器件停止、TX 和 NACK 中断
MAP_I2C_enableInterrupt (EUSCI_B1_base、EUSCI_B_I2C_STOP_INTERRUPT +
EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_Transmit INTERRUPT0);

//将我们的本地状态设置为忙
ui8Status = eUSCI_BUSY;

//为剩余数据启用主中断
map_Interrupt_enableInterrupt (INT_EUSCIB1);

//发送开始位和寄存器
MAP_I2C_masterSendMultiByteStart (EUSCI_B1_base、ui8Reg);

//为剩余数据启用主中断
//MAP_Interrupt_enableInterrupt (INT_EUSCIB1);

//现在等待数据字节发送
(ui8Status = eUSCI_BUSY);
//
#ifdef USE_LPM
MAP_PCM_gotoLPM0 ();
#else
__NO_OPERATION ();
#endif
}*

/#ifdeUSCI_interrupt
+ EUSCI_I2C_MOBIT_B
(eUSCI_INTERRUC_B1)+ EUSCI_INIT_INTERRUC_B1 + EUSCI_INTERRUC_B1
MAP_Interrupt_disableInterrupt (INT_EUSCIB1);

IF (ui8Status == eUSCI_NACK)
{
return (false);
}
else
{
return (true);
}


}/*********
函数:
*/
bool readI2C (uint8_t ui8Addr、uint8_t ui8Reg、uint8_t *数据、uint8_t ui8ByteCount)
{
/*待办事项:推迟*/
*等待就绪*/
while (MAP_I2C_isBusBusy (EUSCI_B1_base));

//将数据分配给本地指针*/
pData =数据;

/*禁用 I2C 模块进行更改*/
MAP_I2C_DisableModule (EUSCI_B1_base);

//设置要接收的字节数*
i2cConfig.byteCounterThreshold = ui8ByteCount;
//setI2cByteCntThrshld (ui8ByteCount);
i2cConfig.autoSTOPGeneration = EUSCI_B_I2C_SEND_STOP_Automatically _ON_BYTECOUNT_T_THRESHOLD;
//setI2cAutoStopGen (EUSCI_B_I2C_SEND_STOP_AUTOMODE_ON_BYTECOUNT_THRESHOLD);
MAP_I2C_initMaster (eUSCI_B1_base、(const eUSCI_I2C_MasterConfig *)&i2cConfig);
//getI2cConfig (configPtr);
//map_I2C_initMaster (eUSCI_B1_base、(const eUSCI_I2C_MasterConfig *) configPtr);

//加载器件从器件地址*/
map_I2C_setSlaveAddress (eUSCI_B1_base、ui8Addr);

/*启用 I2C 模块以启动操作*/
MAP_I2C_enableModule (EUSCI_B1_BASE);

/*启用主器件停止和 NACK 中断*/
MAP_I2C_enableInterrupt (EUSCI_B1_base、EUSCI_B_I2C_STOP_INTERRUPT +
EUSCI_B_I2C_NAK_INTERRUPT);

/*将我们的本地状态设置为 BUSY */
ui8Status = eUSCI_BUSY;

//发送开始位和寄存器*/
MAP_I2C_MASTERSendMultiByteStart (EUSCI_B1_BASE、ui8Reg);

//为剩余的数据启用主中断*
MAP_Interrupt_enableInterrupt (INT_EUSCIB1);

/*注意:如果要接收的字节数= 1、则
在写入阶段*移出目标寄存器时、UCBxTBCNT 将被计数并过早触发停止位
*如果 count > 1、请等待下一个 TXBUF 空中断 (就在寄存器值
已*移出
之后*/
while (ui8Status == eUSCI_BUSY)
{
if (map_I2C_getInterruptStatus (eUSCI_B1_base、eUSCI_B2_I2C_Transmit _INTERRUPT0))
}{
ui8Status = eUSCI_B1_IDLE;
}


ui8Status = eUSCI_B1_START */ECCI2C_RX_BUSY*

/ RE_START


*/ ETOOTB1 */ E* BUSY*/ RE_START * BUSY/ RE_START */ RE_START / ETOOTN *
MAP_I2C_enableInterrupt (eUSCI_B1_base、eUSCI_B_I2C_RECEIVE_INTERRUPT0);

//等待接收所有数据
* while (ui8Status = eUSCI_B1_BUSY)
{

#ifdef USE_LPM
MAP_PCM_GEotoLPM0 ();
#else
__NO_OPERATION (ui2C_INTERRUC_BUSCI_INTERB_INTERRUB*





)+#if_INTERUSCI_INTERRUI2C_INTERRU中断*+#if_NOT_IN_INTERRUC_B1 +#if_INTERRUI2C_INTERRU中断*;*#IP_NO_INTERRUI2C_NO_INTERB_INTERRU中断***
MAP_Interrupt_disableInterrupt (INT_EUSCIB1);

IF (ui8Status == eUSCI_NACK)
{
return (false);
}
else
{
return (true);
}


}/*********
函数:
*/
*bool readBurstI2C (uint8_t ui8Addr、uint8_t ui8Reg、uint8_t *数据、uint32_t ui32ByteCount)
{
待办事项:等待延迟
直至准备就绪
while (MAP_I2C_isBusBusy (EUSCI_B1_base));

将数据分配给本地指针
pData =数据;

禁用 I2C 模块进行更改
MAP_I2C_DisableModule (EUSCI_B1_MODULE);

设置要接收的字节数
i2cConfig.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
G_ui32ByteCount = ui32ByteCount;
BurstMode = true;
MAP_I2C_initMaster (EUSCI_B1_MODULE、(CONST eUSCI_I2C_MasterConfig *)&i2cConfig);

加载器件从器件地址
MAP_I2C_setSlaveAddress (EUSCI_B1_MODULE、ui8Addr);

启用 I2C 模块以启动操作
MAP_I2C_enableModule (EUSCI_B1_MODULE);

启用主器件停止和 NACK 中断
MAP_I2C_enableInterrupt (EUSCI_B1_MODULE、EUSCI_B_I2C_STOP_INTERRUPT +
EUSCI_B_I2C_NAK_INTERRUPT);

将我们的本地状态设置为 BUSY
ui8Status = eUSCI_BUSY;

发送开始位和寄存器
MAP_I2C_MASTERSendMultiByteStart (EUSCI_B1_MODULE、ui8Reg);

为其余数据启用主中断
MAP_Interrupt_enableInterrupt ();

注意:如果要接收的字节数= 1、那么
当目标寄存器在写入阶段*移出时、UCBxTBCNT 将被计数并过早触发停止位
*如果 count > 1、请等待下一个 TXBUF 空中断 (就在寄存器值
被*移出

while (ui8Status = eUSCI_BUSY)
{
if (map_I2C_getInterruptStatus (eUSCI_B1_MODULE、EUSCI_B2_I2C_Transmit Receive_INTERRUPT0))
}{
ui8Status = eUSCI_IDLE;
}


ui8Status = eUSCI_B1_MODULE


;启用 eUSCI_RX_START 中断;关闭 eUSCI_START 和 ECCI2C_RX_START

中断
MAP_I2C_enableInterrupt (EUSCI_B1_MODULE、EUSCI_B2_I2C_Receive_INTERRUPT0);

等待接收所有数据
(ui8Status = eUSCI_B繁忙)
{

#ifdef USE_LPM
MAP_PCM_gotoLPM0 ();
#else
_ no_operation ();#endi2C_interrupt




+ EUSCI_B1_INTERUSCI_interrupt + EUSCI_interrupt + EUSCI_中断 EUSCI_中断 UCI_B + EUSCI_中断

MAP_Interrupt_disableInterrupt ();

if (ui8Status == eUSCI_NACK)
{
return (false);
}
else
{
return (true);
}
}*/

/*********
函数:euscib0IntHandler
*/
void EUSSCIB1_IRQHandler (void)
{
uint_fast16_t status;

STATUS = MAP_I2C_getEnabledInterruptStatus (EUSCI_B1_BASE);
MAP_I2C_clearInterruptFlag (EUSCI_B1_BASE、STATUS);
//map_I2C_clearInterruptFlag (EUSCI_B1_base、0x02);

IF (STATUS & EUSCI_B_I2C_NAK_INTERRUPT)
{
/*在从器件发生 Nacks 时生成 STOP */
MAP_I2C_masterSendMultiByteStop (EUSCI_B1_BASE);

/*清除所有挂起的 TX 中断*/
MAP_I2C_clearInterruptFlag (EUSCI_B1_BASE、EUSCI_B_I2C_Transmit、INTERRUPT0);

/*将我们的本地状态设置为 NACK Received */
ui8Status = eUSCI_NACK
;}

IF (STATUS & EUSCI_B_I2C_START_INTERRUPT)
{
/*更改我们的本地状态*/
ui8Status = eUSCI_START;
}

IF (STATUS & EUSCI_B_I2C_STOP_INTERRUPT)
{
/*更改我们的本地状态*/
ui8Status = eUSCI_STOP;
}

IF (STATUS & EUSCI_B_I2C_Receive_INTERRUPT0)
{
/* RX 数据*/
*pData++= MAP_I2C_masterReceiveMultiByteNext (EUSCI_B1_BASE);
ui8DummyRead= MAP_I2C_masterReceiveMultiByteNext (EUSCI_B1_BASE);

IF (BurstMode)
{
g_ui32字节计数--;
if (g_ui32ByteCount = 1)
{
BurstMode = false;

/*生成停止*/
MAP_I2C_masterSendMultiByteStop (EUSCI_B1_BASE);
}
}


IF (STATUS & EUSCI_B_I2C_Transmit _INTERRUPT0)
{
/*发送下一个数据*/
MAP_I2C_masterSendMultiByteNext (EUSCI_B1_base、* pData++);
}

#ifdef USE_LPM
MAP_Interrupt_disableSlepOnIsrExit();
#endif
}

我现在将 P6.4用作 SDA、将 P6.5用作 SCL。

谢谢

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

    安德烈

    您能否告知我 P6.4和 P6.5上是否有上拉电阻器、它们的值是多少?

    本应用手册的第5节: http://www.ti.com/lit/an/slaa734/slaa734.pdf 对于在 MSP 器件上调试 I2C 应用非常有用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    2.2k 电阻器时、时钟始终为低电平、同时我尝试进行运输
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    安德烈

    我可以更深入地了解这一点。 您能告诉我更多信息吗?
    1) 1)您是否尝试过更大的上拉电阻器? 2.2k 位于电压过低的边缘。 如果您尝试了10k、该怎么办?
    2) 2)您使用的是什么板? 如果是 LaunchPad、它们是什么颜色(红色或黑色)。
    3) 3)您的从端是什么? 它运行的代码是什么?
    4) 4)您是否已尝试使用 SDK 中的一个示例执行此相同的端口? 例如 :dev.ti.com/.../

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

    安德烈

    我刚刚针对 B1测试了这些示例、它们工作正常。 我的上拉电阻器为10k。

    /cfs-file/__key/communityserver-discussions-components-files/166/i2c_5F00_master_5F00_w_5F00_multibyte_5F00_multislave_2D00_master_5F00_code.c

    /cfs-file/__key/communityserver-discussions-components-files/166/i2c_5F00_master_5F00_w_5F00_multibyte_5F00_multislave_2D00_slave_5F00_code.c

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

    安德烈

    这种易于使用的 I2C API 可能对您有用。 请参阅随附的文件。

    e2e.ti.com/.../1067.i2c_5F00_driver.c

    e2e.ti.com/.../6237.i2c_5F00_driver.h

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

    @Evan Wakefield,
    我现在使用的是10k 的上拉电阻器、但仍然无法正常工作、电路板为红色(MSP432P401R SimpleLink)、从器件为 NFC 模块、使用与上述相同的代码、但使用模块 eUSCIB0时、从速率上讲、上述代码与您链接的示例相同。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    void system_init (void)
    {
    SCB->CPACR |=(3UL <<10 * 2)| //设置 CP10完全访问
    (3UL << 11 * 2)); //设置 CP11完全访问
    
    WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; //停止 WDT
    
    SYSCTl->SRAM_BANKEN = SYSCTL_SRAM_BANKEN_BNK7_EN; //启用所有 SRAM 组
    
    while (((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
    PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1;
    while (((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
    
    //将 LDO VCORE1切换到 DCDC VCORE1
    
    while (((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
    PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5;
    while (((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
    
    
    // 1个闪存等待状态(BANK0 VCORE1最大值为16MHz、组1 VCORE1最大值为32MHz)
    FLCTL->BANK0_RDCTL =(FLCTL->BANK0_RDCTL 和~FLCTL_BANK0_RDCTL_WAIT_MASK)| FLCTL_BANK0_RDCTL_WAIT_1;
    FLCTL->BANK1_RDCTL =(FLCTL->BANK1_RDCTL &~FLCTL_BANK1_RDCTL_WAITL_MASK)| FLCTL_BANK1_RDCTL_WAIT_1;
    
    // DCO = 48MHz;MCLK =源
    CS->KEY = CS_KEY_VAL; //解锁 CS 模块以进行寄存器访问
    CS->CTL0 = CS_CTL0_DCORSEL_5; //将 DCO 设置为48MHz
    CS->CTL1 =(CS->CTL1和 μ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)| CS_CTL1_SELM_DCOCLK;
    //选择 MCLK 作为 DCO 源
    CS->KEY = 0;
    
    //设置闪存组读取缓冲
    FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL |(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
    FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL |(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFFI);
    
    MAP_Interrupt_enableMaster();
    } 

    大家好、在另一个项目上使用相同的代码时、我没有任何错误、即使使用 eUSCIB1也是如此、但是在我需要的主项目上、我仍然有一个故障中断、这很奇怪。

    这是我用于 UC 的初始化:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这是 startup_file 的问题、忘记了我使用的项目是否有它。 很抱歉耽误你的时间。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    安德烈

    没问题! 这就是我们在这里的目标! 很高兴您的问题得到解决!