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.

[参考译文] CC2650EM-7ID-RD:I2C 通信问题 CC2560

Guru**** 1144270 points
Other Parts Discussed in Thread: CC2650, CC2560, MSP430G2553
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/926265/cc2650em-7id-rd-i2c-communication-issue-cc2560

器件型号:CC2650EM-7ID-RD
Thread 中讨论的其他器件:CC2650SYSBIOSCC2560MSP430G2553

您好!  

我正在使用 CC2650和 MAX30100传感器、在我的代码中、我设法初始化 i2c 通信、但我无法从 FIFO 缓冲区读取传感器数据。

我甚至尝试使用 Semaphore_post 来确保任务仍在运行、但我最终得到了相同的结果

注意:我无法看到任务的状态、因为任务是静态的、而不是动态的(由构造函数创建)

在我的代码下面

/*
* I2C 引脚:RF1.18 (MOSI) SCL
* RF1.20 (MISO) SDA
***/
/* I2C */
//#define Board_I2C0_SDA0 IOID_8 //RF1.20
//#define Board_I2C0_SCL0 IOID_9 //RF1.18
/* XDCtools 头文件*/
#include
#include
#include
#include
#include
#include

/* BIOS 头文件*/
#include
#include
#include
#include

/* TI-RTOS 头文件*/
#include
#include
#include
#include

/*板头文件*/
#include "Board.h"

/* MAX30100头文件*/
#include "MAX30100_Registers.h"
#include "MAX30100_Filters.h"
#include "MAX30100_SpO2Calculator.h"
#include "ringbuffer.h"

/* MAX30100定义*/
#define MAX_BUFFER_SIZE 64

#define SLAVE_ADDR 0x57 // MAX30100地址

#define DEFAULT_MODE MAX30100_MODE_HRONLY
#define DEFAULT_SAMPLING_RATE MAX30100_SAMPRATE_100Hz
#define MAX30100_SPC_PW_16位 MAX30100_SPC_PW_1600US_16位
#define MAX30100_SPC_PW_13BITS MAX30100_SPC_PW_200US_13BITS
#define DEFAULT_RED_LED_CURRENT MAX30100_LED_CURR_50mA
#define DEFAULT_IR_LED_CURRENT MAX30100_LED_CURR_50mA
#define RED_LED_CURRENT_START MAX30100_LED_CURR_27_1mA
#define Expected;PART_ID 0x11

/*堆栈大小*/
#define I2CTASKSTACKSIZE 2048
#define UARTASKSTACKSIZE 1024


/* PIN_Config 表的全局存储器*/
静态 PIN_STATE ledPinState;
pin_handle ledPinHandle;
/*
*应用 LED 引脚配置表:
*-所有 LED 板 LED 均熄灭。
*
PIN_Config ledPinTable[]={
BOARD_LED1 | PIN_GPIO_OUTP_EN | PIN_GPIO_LOW | PIN_PushPull | PIN_DRVSTR_MAX、
BOARD_LED2 | PIN_GPIO_OUTP_EN | PIN_GPIO_LOW | PIN_PushPull | PIN_DRVSTR_MAX、
PIN_TERMINATE
};
/* MAX30100变量*/
ringBuffer_typedef (uint16_t、FIFO 缓冲区);
FIFO 缓冲区 redbuffer、irBuffer;
FIFO 缓冲区* redBuffer_ptr;
FIFO 缓冲区* irBuffer_PTR;
静态 uint8_t Tempo [6]={0};

/*信标变量*/
静态 Semaphore_handle i2cSem;
/* I2C 配置*/

静态 uint8_t txBuffer[2];
静态 uint8_t rxBuffer[MAX_buffer_size];
静态 bool transferDone = false;
静态 I2C_Handle i2c;
静态 I2C_Params i2cParams;
静态 I2C_Transaction i2cTransaction;

Task_Structi2cTaskStruct;
char i2cTaskStack[I2CTASKSTACKSIZE];

Task_StructuartTaskStruct;
字符 uartTaskStack[UARTTASKSTACKSIZE];
/*I2C 状态机功能*/
uint8_t readRegister (uint8_t SLV_reg);
void writeRegister (uint8_t SLV_reg、uint8_t data);
void CopyArray (uint8_t *源、uint8_t * dest、uint8_t count);
bool begine();
uint8_t getPartId();
void setMode (模式);
void setLedsPulseWidth (LEDPulseWidth ledPulseWidth);
void setSamplingRate (SamplingRate SamplingRate);
void setLedsCurrent (LEDCurrent irLedCurrent、LEDCurrent redLedCurrent);
void setHighresModeEnabled (启用 bool);
void readFifoData();
void burstRead (uint8_t baseAddress、uint8_t *缓冲区、uint8_t length);
bool getRawValues (uint16_t *或 uint16_t *红色);

静态空 taskFxn (UARg arg0、UARg arg1);

/******** 读取寄存器******** /
uint8_t readRegister (uint8_t SLV_reg)

txBuffer[0]= SLV_reg;
i2cTransaction.slaveAddress = slave_ADDR;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.ReadCount = 1;
if (I2C_transfer (i2c、&i2cTransaction))

返回 rxBuffer[0];

其他

System_printf ("I2C Error Reading \n");
system_flush();
返回0;

void burstRead (uint8_t baseAddress、uint8_t *缓冲区、uint8_t 长度)

txBuffer[0]= baseAddress;
i2cTransaction.slaveAddress = slave_ADDR;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.ReadCount =长度;
if (I2C_transfer (i2c、&i2cTransaction))

CopyArray (rxBuffer、buffer、length);

其他

System_printf ("I2C 错误突发读取\n");
system_flush();

/******* 写 Rgister (注册)******* /
空写入寄存器(uint8_t SLV_reg、uint8_t 数据)

txBuffer[0]= SLV_reg;
txBuffer[1]=数据;

i2cTransaction.slaveAddress = slave_ADDR;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount =2;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.ReadCount = 0;
I2C_transfer (i2c、&i2cTransaction);

void CopyArray (uint8_t *源、uint8_t *目标、uint8_t 计数)

uint8_t copyIndex = 0;
for (copyIndex = 0;copyIndex < count;copyIndex++)

dest[copyIndex]= source[copyIndex];

bool begine()

if (getPartId ()!= Expected_part_ID)
返回 false;

setMode (default_mode);
setLedsPulseWidth (MAX30100_SPC_PW_13BITS);//请记住每次更改采样率时都要进行更改
setSamplingRate (MAX30100_SAMPREATE_1000Hz);
setLeds 电流(DEFAULT_IR_LED_CURRENT、DEFAULT_RED_LED_CURRENT);
setHighresModeEnabled (真);

bufferInit (redBuffer、16、uint16_t);
bufferInit (irBuffer、16、uint16_t);
redBuffer_ptr = redBuffer (&R);
irBuffer_ptr =&irBuffer;

返回 true;

uint8_t getPartId()

返回读寄存器(MAX30100_REG_PART_ID);

void setMode (模式)

writeRegister (MAX30100_REG_MODE_CONFIGURATION、MODE);

void setLedsPulseWidth (LEDPulseWidth ledPulseWidth)

uint8_t Previous =读取寄存器(MAX30100_REG_SPO2_CONFIGURATION);
writeRegister (MAX30100_REG_SPO2_configuration、(上一个和0xFC)| ledPulseWidth);

void setSamplingRate (SamplingRate SamplingRate)

uint8_t Previous =读取寄存器(MAX30100_REG_SPO2_CONFIGURATION);
writeRegister (MAX30100_REG_SPO2_configuration、(Previous 和0xe3)|(samplingRate << 2));

空 setLedsCurrent (LEDCurrent irLedCurrent、LEDCurrent redLedCurrent)

writeRegister (MAX30100_REG_LED_CONFIGURATION、redLedCurrent << 4 | irLedCurrent);

空 setHighresModeEnabled (启用 bool)

uint8_t Previous =读取寄存器(MAX30100_REG_SPO2_CONFIGURATION);
如果(已启用){
writeRegister (MAX30100_REG_SPO2_configuration、Previous | MAX30100_SPC_SPO2_HI_RES_EN);
}否则{
writeRegister (MAX30100_REG_SPO2_configuration、Previous &~MAX30100_SPC_SPO2_HI_RES_EN);


空 readFifoData()

uint8_t buffer[MAX30100_FIFO_DEPTY*4];
uint8_t toRead、i;
uint16_t redWrite、irWrite;

toRead =(readRegister (MAX30100_REG_FIFO_WRITE_POINTER)- readRegister (MAX30100_REG_FIFO_READ_POINTER)和(MAX30100_FIFO_DEPTY-1);

if (toRead)

BurstRead (MAX30100_REG_FIFO_DATA、缓冲器、4 * toRead);

对于(i=0;i < toRead;++I)

irWrite =(uint16_t)((buffer[i*4]<<8)| buffer[i*4 + 1]);
redWrite =((buffer[i*4+2]<<8)| buffer[i*4+3]);
bufferWrite (irBuffer_PTR、irWrite);
bufferWrite (redBuffer_ptr、redWrite);

bool getRawValues (uint16_t *或 uint16_t *红色)

if (!isBufferEmpty (irBuffer_PTR)&&!isBufferEmpty (redcBuffer_PTR))

bufferRead (irBuffer_ptr、*ir);
bufferRead (redBuffer_ptr、*红色);
返回 true;

其他
返回 false;

/*
*==== 回声 Fxn =====
*此函数的任务是静态创建的。 请参阅工程的.cfg 文件。
*
静态空 taskFxn (UARg arg0、UARg arg1)
{/*为异步创建一个信号量*/
Semaphore_Params semParams;
ERROR_Block EB;

/* Init 参数*/
Semaphore_Params_init (semParams);
ERROR_INIT (&EB);

/*创建信标实例*/
i2cSem = Semaphore_create (0、SemParams、&EB);
/*创建 I2C 以供使用*/
I2C_Params_init (&i2cParams);
i2cParams.bitrate = I2C_400kHz;
i2cParams.transferMode = I2C_MODE_BLOCKING;
i2cParams.transferCallbackFxn =空;

I2C = I2C_open (0、&i2cParams);
//i2c = I2C_open (Board_I2C0、&i2cParams);
i2cTransaction.slaveAddress = slave_ADDR;
if (i2c == NULL){
System_abort ("初始化 I2C\n 时出错");


否则{
system_printf ("I2C 已初始化!\n"\});
system_flush();

/*配置 MAX30100 */
bool READY = Beging();

如果(!ready)

System_printf ("无法初始化 MAX30100\n");
system_flush();
while (1);

Task_sleep (50);
PIN_setOutputValue (ledPinHandle、Board_LED2、!PIN_getOutputValue (Board_LED2));
设置模式(MAX30100_MODE_SPO2_HR);
setLeds 电流(DEFAULT_IR_LED_CURRENT、RED_LED_CURRENT_START);

setHighresModeEnabled (真);
writeRegister (MAX30100_REG_INTERRUPT_ENABLE、MAX30100_IE_ENB_SPO2_RDY);//启用 SpO2中断
uint16_t rawIRValue、rawRedValue;
Tempo [0]= 0xFF;
Tempo [1]= 0xFF;
while (1){
System_printf ("**** 1**\n");
system_flush();
while (!(readRegister (MAX30100_REG_INTERRUPT_STATUS)& 0x10));//等待中断发生//如果是 HR IE、则更改为0x20
/*{
Semaphore_pend (i2cSem、BIOS_wait_forever);
}*/

System_printf ("**** 2**\n");

readFifoData();
System_printf ("**** 3**\n");

while (getRawValues (&rawIRValue、&rawRedValue))

System_printf ("**** 4**\n");

Tempo [2]= rawIRValue;
Tempo [3]=(rawIRValue >> 8);
Tempo [4]= rawRedValue;
Tempo [5]=(rawRedValue >> 8);
对于(i = 0;i<6;i++){
System_printf ("%u:\n",Tempo [i]);
system_flush();

// Semaphore_post (i2cSem);

/* else{
System_printf ("I2C 总线故障\n");
}*/


//System_flush();
// Task_sleep (1000000 / Clock_tickPeriod);

/*已取消初始化 I2C */
I2C_Close (i2c);
System_printf ("I2C 已关闭!\n"\});

system_flush();

/*
*==== main ====
*
int main (空)

Task_Params taskParams;

/*呼叫板初始化函数*/
Board_initGeneral();
Board_initI2C();

/*构造 I2C 任务线程*/
Task_Params_init (&taskParams);
taskParams.STACKSIZE = I2CTASKSTACKSIZE;
taskParams.stack =&i2cTaskStack;
taskParams.priority = 2;
Task_construct(&i2cTaskStruct,(Task_Functr)taskFxn,&taskParams,NULL );

/*打开 LED 引脚*/
ledPinHandle = PIN_OPEN (&ledPinState、ledPinTable);
if (!ledPinHandle){
System_abort ("初始化板 LED 引脚时出错");

PIN_setOutputValue (ledPinHandle、Board_LED1、1);

system_printf ("启动 I2C 示例\n 系统提供程序设置为 SysMin。"
"停止目标以查看 ROV 中的任何 SysMin 内容。\n");
/* SysMin 仅在您调用 flush 或 exit 时才会打印到控制台*/
system_flush();

/*启动 BIOS */
BIOS_start();

返回(0);

当我对程序进行调试时、我发现 函数"getRawValues (&rawIRRedValue、&rawRedValue)"始终返回 false

控制台

SCL (黄色)和 SDA (蓝色)信号的输出下方

如果能帮助解决我的问题、我将不胜感激

此致

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

    I2C 信号看起来不好。 您应首先检查 I2C 连接。

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

    您好!  

    在使用 MAX30100之前、我使用基本程序检查了 I2C 连接(我刚刚从 MSP430G2553向 CC2560发送了一条命令并打印出该命令)

    我还检查了很多次接线、都可以

    此致

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

    基本上,对 I2C 使用如此长的导线以及是否向 I2C 端口添加上拉电阻并不是一个好的做法?

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

    试验电路板会增加大量寄生电容。 可能是连接正确、但使用较短的导线直接连接到传感器。 您似乎有一个脉冲没有时间达到指示过大负载的逻辑"1"电平。  

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

    不、我没有。 那么、我应该在引脚表中启用上拉 I2C 吗? 如下所示

    PIN_Config I2CPinTable[]={
    Board_I2C0_SCL0 | PIN_GPIO_OUTP_EN | PIN_GPIO_HIGH | PIN_PULLUP、
    Board_I2C0_SDA0 | PIN_INPUT_EN | PIN_PULLUP、
    PIN_TERMINATE
    };

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

    我是说您应该向 I2C SCL/SDA 线缆添加物理上拉电阻器。

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

    谢谢、我将添加它、然后查看我的信号

    BTW、我是否需要 HWI 例程来传输 I2C 数据或 I2C 驱动程序已在使用 HWI?

    此致

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

    您无需 HWI 例程即可传输 I2C 数据。

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

    您好!

    我添加了两个4.9k 的上拉电阻器、并将咬接速率更改为100kHz。 我有相同的信号、但我可以在 控制台中看到前两个数据样本。

    [Cortex_M3_0]开始 I2C 示例
    系统提供商设置为 SysMin。 停止目标以查看 ROV 中的任何 SysMin 内容。
    I2C 已初始化!
    240:
    1:
    176:
    1:
    8:
    2:
    200:
    1:

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

    I2C 信号现在看起来要好得多。 那么、您现在的问题是什么?

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

    您好!  

    在我的 while 环路中、我应该会看到来自 I2C 缓冲区的所有传入数据、但是。 我只能看到前两个样本、没有其他东西

    此致。

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

    您好!

    在我的 while 中、我打印来自 I2C 缓冲区的所有传入数据、但是。 我只能看到前两个样本、没有其他东西。

    此致

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

    如果在 I2C 读取函数上设置断点并对其进行调试、它能否每次读取正确的结果?

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

    我通过打印从 I2C 缓冲器通过 UART 接收到的数据来解决问题。 但是、我仍然不理解 CCS 控制台的问题是什么!

    此致。