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/EK-TM4C129EXL:写入数据丢失

Guru**** 2455560 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/631713/ccs-ek-tm4c129exl-write-data-goes-missing

器件型号:EK-TM4C129EXL

工具/软件:Code Composer Studio

我正在处理一个项目、与 Max30101传感器通信以读取 SP02数据。 但使用示波器。 我意识到,在 I2CSEL 结束期间,写入数据中的1个字节丢失。 代码如下所示。

klib1.h 是 https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/blob/master/src/MAX30105.cpp 的修改版本。 例如 ,当我尝试“I2CSend (I2CDEVICE_ADDR,2,MAX30105_LED1_PULSEAMP,0x01);”时 ,我能够按预期打开红色 LED。 但情况并非总是如此。 大多数情况下、"MAX30105_LED1_PULSEAMP"将消失、因此红色 LED 不会亮起。

#include 
#include 
#include 
#include 
#include 
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/sysbt.h"
#driverlib/intrl.idu.ide"









#include "driverlib/u32ns/intrl.id_unt #include "driverlib.idr32";"drivers/u.idr32ns/intru.idrs/inu.rt.idr.idr.idr./u.idr./u.idr.idr.idr.idr.idr./u.idr.idr.idr./u.idr.idr.idr.idr./u.idr./u.idr.idr.idr./u.idr.idr./ 除以3个 cz 3个 clk 周期。

静态无符号长整型 WaitI2CDone (unsigned int long ulBase){
//等待直到传输完成
while (I2CMasterBusy (I2C0_BASE));
//返回 I2C 错误代码
返回 I2CMasterErr (I2C0_BASE);
}

//I2C 发送函数
//向指定的从设备发送 I2C 命令
//例如:I2CEND (LCD_SLAVE_ADDR、3、LCD_CMD、0x50、对比度);
void I2CSend (uint8_t slave_addr、uint8_t num_for_args、...)
{
uint8_t i = 0;
//告诉主模块何时将在总线上放置什么地址
//与从设备通信。
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);

//存储变量数量的参数列表
va_list vargs;

//将 va_list 指定为"open"和最后一个固定参数
//so vargs 知道从何处开始查找
va_start (vargs、num_of _args);

//将要发送的数据放入 FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));

//如果只有一个参数,我们只需要使用
//单发送 I2C 函数
if (num_of _args == 1)
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);

//等待 MCU 完成传输。
while (I2CMasterBusy (I2C0_BASE));

//"close"变量参数列表
va_end (vargs);
}

//否则,我们开始在上传输多个字节
//I2C 总线
其他
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);

//等待 MCU 完成传输。
while (I2CMasterBusy (I2C0_BASE));

//send num_of _args-2数据片段、使用
///burse_send_contt 命令的 I2C 模块
for (i = 1;i <(num_of _args - 1);i++)
{
//将下一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);

//等待 MCU 完成传输。
while (I2CMasterBusy (I2C0_BASE));
}

//将最后一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
//等待 MCU 完成传输。
while (I2CMasterBusy (I2C0_BASE));

//"Close"变量 args 列表
va_end (vargs);
}
}

//I2C 接收功能
//读取从器件
上的指定寄存器 uint32_t I2CReceive(Uint32_t SLAVE_addr、uint8_t reg)
{
uint8_t data = 0;
int16_t i2c_err = I2C_MASTER_ERR_NONE;
//指定我们要向写入(寄存器地址)
//从器件
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);

//指定要读取的寄存器
I2CMasterDataPut (I2C0_BASE、reg);

//将控制字节和寄存器地址字节发送到从器件
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C0_BASE));

//指定我们将从从从器件读取
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);

//发送控制字节并从我们的寄存器中读取
//specified
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);

if (i2c_err!= WaitI2CDone (I2C0_BASE)){
数据= I2CMasterDataGet (I2C0_BASE);
UARTprintf ("数据中的读取错误:%x\n"、数据);
}

//等待 MCU 完成事务
while (I2CMasterBusy (I2C0_BASE));

//返回从指定寄存器提取的数据
返回 I2CMasterDataGet (I2C0_BASE);
}

void 位掩码(uint8_t reg、uint8_t mask、uint8_t sing)
{
//抓取当前寄存器上下文
uint8_t originalContents = I2Coriginive (I2CDEVICE_ADDR、reg);

//将部分


内容全部删除;更改 I2CDe2
和 I2ADDR | originale2 | origined 内容= originive.


void setFIFOAimage (uint8_t NumberOfSamples){
bitmask (MAX30105_FIFOCONFIG、MAX30105_SAMPLEAVG_MASK、NumberOfSamples);
}

void enableFIFORlover (void){
bitmask (MAX30105_FIFOCONFIG、MAX30105_MASK、NumberOfSamples);}void enableFIFORollover (void enover){void translover (void){void translover (void)}/ void translover (void translover){void translover (void)}){bit maged



(void)}
//请参阅数据表、第19页
的位掩码(MAX30105_MODECONFIG、MAX30105_MODE_MASK、MODE);
}

void setADCRange (uint8_t adcRange){
// adcRange:MAX30105_ADCRANGE_2048、_4096、_8192、_16105
bitCLA_MASK (MAX30105_ADCRANGE_2048)中的一个 adcRange);
}

void setSampleRate (uint8_t sampleRate){
// sampleRate:MAX30105_SAMPLERATE_50、_100、_200、_400、_800、 _1000、_1600、_3200
位掩码(MAX30105_PARTICLECONFIG、MAX30105_SAMPLEREATE_MASK、sampleRate);
}

void setPulseWidth (uint8_t pulsewidth){
// pulsewidth:MAX30105_pulsewidth_69的其中一个、_188、_215、_411
位掩码(MAX30105_PARTICLECONFIG、MAX30105_pulsewidth_MASK、 pulsewidth);
}

//注意:振幅值:0x00 = 0mA、0x7F = 25.4mA、0xFF = 50mA (典型值)
//请参阅数据表、第21页
void setPulseAmp 振







幅红色(uint8_t 振幅){I2CSend (I2CDEVICE_ADDR、2、MAx105_LED1_LEADDR 振幅)、void (uint2UCD3_demp)、void P30t_magpend_magmagse_se_magmagmagmagme_se_se_se_se_se_se_se_se_sei20uelt
);}


void setPulseAmplitudeProximity (uint8_t samplity){
i2CSend (I2CDEVICE_ADDR、2、MAX30105_LED_PROx_AMP、sampling);
}

void setProximityThreshold (uint8_t THRESB){
//设置将触发颗粒感应模式开始的 IR ADC 计数。
// THRESHMSB 只表示 ADC 计数的8个最高有效位。
//请参阅数据表第24页。
I2CSend (I2CDEVICE_ADDR、2、MAX30105_PROXINTTHRESH、THRESB);
}

//给定插槽编号为其分配一个东西
//设备为 SLOT_RED_LED 或 SLOT_RED_PULSE (接近)
//分配 SLOT_RED_LED 将脉冲 LED//A
RELEARD_PLETDIN?
void enableSlot (uint8_t slotNumber、uint8_t device){
switch (slotNumber){
情况(1):
位掩码(MAX30105_MULTILEDCONFIG1、MAX30105_SLOT1_MASK、器件);
中断;
情况(2):
位掩码(MAX30105_MULTILEDCONFIG1、MAX30105_SLOT2_MASK、器件<< 4);
中断;
情况(3):
位掩码(MAX30105_MULTILEDCONFIG2、MAX30105_SLOT3_MASK、器件);
中断;
情况(4):
位掩码(MAX30105_MULTILEDCONFIG2、MAX30105_SLOT4_MASK、器件<< 4);
中断;
默认值:
//不应该在这里!
break;
}
}

void clearFIFO (void){
I2CSend (I2CDEVICE_ADDR、2、MAX30105_FIFOWRITEPTR、0);
I2CSend (I2CDEVICE_ADDR、 2、MAX30105_FIFOOVERFLOW、0);
I2CSEND (I2CDEVICE_ADDR、2、 MAX30105_FIFOREADPTR、0);
}

void softReset (void){
bitmask (MAX30105_MODECONFIG、MAX30105_RESET_MASK、MAX30105_RESET);
while (1)
{
uint8_t 响应= I2CReceive (I2CDEVICE_ADDR、MAX30105_MODECONFIG);
如果((RESPONSE & MAX30105_RESET)= 0)中断;//我们完成!
SysCtlDelay (延迟);//let 不会使 I2C 总线过载
}
//在此放置一些延迟
}

void Sensorsetup (uint8_t powerLevel、uint8_t sampleAsyage、uint8_t ledMode、int sampleRate、int pulsewidth、 int adcRange){
softReset ();//将所有配置、阈值和数据寄存器重置为 POR 值

//FIFO 配置
/../../====================================================================================================================================================================================================================================================================

每片 FIFO 平均值(如果您希望)多个采样值为0或0、则为1个采样
值)
否则、如果(sampleAime== 4)设置 FIFOAime(MAX30105_SAMPLEAVG_4);
否则、如果(sampleAime=8)设置 FIFOAull (MAX30105_SAMPLEAVG_8);
否则、如果(sampleAime=16)设置 FIFOA105 (MAX30105_SAMPLEG_8



);如果(samples/sameAM30_SAAVAime32);设置为"/sameAVEAPeEXOLAY=16);
//Allow FIFO to wrap/roll over
//================================/Mode

Configuration /============================================================================================================================================================================================================================================================================

RedleMode=(仅限三个)/TIRELED-MODE=EMEND30105;ENDULLE=(仅限三个)/RELED-MODE=EMENDULLE/EMEND23)


//用于控制从 FIFO 缓冲区中读取的字节数
//====================================================================================

Parsensing Configuration /============================================================================================================================ Range




S= ADC30384Sb RAC18248Sb (Sb) Range = XADC18245;= END= R18245S= END=(Sb) SENS=S=30245S=S=ENDA-=(S= RAC18245S=) SENS=S=(S=)


如果(sampleRate < 100) setSampleRate (MAX30105_SAMPLERATE_50);//如果
(sampleRate < 200) setSampleRate (MAX30105_SAMPLERATE_100);
否则(sampleRate < 400) sampleR100 (sampleR100
);如果(sampleR100
) sampleR100 (sampleR100

) sampleR100 (sampleR100);如果(sampleR100_SAMP30105_SAMPR100) sampleR100) sample_sample_sample_100 (sample_100);如果(sampleR100 (sampleR100) sampleR100 (sampleR100) sampleR100 (sampleR100) sampleR100 (sampleR100);如果(sampleR100) sample_sample_sample_sample_sample_sampleR100 (sampleR100) sample_s
否则、如果(sampleRate == 3200) setSampleRate (MAX30105_SAMPLERATE_3200);
否则、setSampleRate (MAX30105_SAMPLERATE_50);

//脉宽越长、检测距离越长、
在69us 和0.4mA 时、检测距离就大约为2英寸
//16英寸
(如果为0.4mA)、则为1 x 6英寸/0 x 6英寸(1 x 6英寸)。 //第26页,如果
(pulsewidth < 215)设置 PulseWidth (MAX30105_pulsewidth_118),则获得15位分辨率;//如果
(pulsewidth <)设置 PulseWidth (MAX30105_pulsewidth_215),则获得16位分辨率
;//如果(pulsewidth = 105)设置 PulseWidth (MAX301051_1011_set14),则获得17位分辨率;/PulseWidth_10411_setMAX30411_resolution
;//设置 Pulse411_10411_PulseWidth_resolution;//
//--========================================/LED

脉冲振幅配置
/=================================================================================================================================================== 0x42mA-0X46mA-0X4mA/powerel=0x4mA/enitude

~
~
~……………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………
50.0mA -~12英寸

setPulseAmplitudeRed (powerLevel)的存在检测;
setPulseAmplitudeIR (powerLevel);
setPulseAmplitudeGreen (powerLevel);
setPulseAmplitudeLED (powerLevel);
/--=-=/enableSlot





1);/=/=enable_enableMode (enableSlot 1);/=/=-=/=/enableSlot =/=/enableLED (enable_enable_enableMode);/=/=/=/=/enableSlot (enable=/=/=/enable= 1)/=/=/enable/=/enableSlot (enableMode)/=/=/=/enable/=/=/=/enableSlot (enable3)/=/enable/=/=/enableMode)/=/enable/enable/=/=/=/enableSlot (enable3)/enableLED (enable/=/=/=/enableSlot_enable

SLOT_IR_Pilot);
//enableSlot (3、SLOT_GREEN_PIRER);
//--============================================================================================================================================================================-----

--------------clearFIFO ();//在我们开始检查一


个二进制或六进制数之前重置传感器。 读出帧的最后一位数字。
void binary (n){
while (n){
如果(n 和1)
UARTprintf ("1");
其他
UARTprintf ("0");

n >=1;
}
UARTprintf ("\n");
}

//initialize I2C module 0
// TI 示例代码
void InitI2C0 (void)
{的细微修改版本
//启用 I2C 模块0
SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);

//复位模块
//SysCtlPeripheralReset (SYSCTL_Periph_I2C0);

//启用包含 I2C 0的 GPIO 外设
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);

//added 等待外设为编程做好准备
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOB));

//为端口 B2和 B3上的 I2C0功能配置引脚复用。
GPIOPinConfigure (GPIO_PB2_I2C0SCL);
GPIOPinConfigure (GPIO_PB3_I2C0SDA);

//为这些引脚选择 I2C 功能。
GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);//I2C0 SCL
GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);//I2C0 SCL

//启用和初始化 I2C0主机模块。 使用的系统时钟
// I2C0模块。 最后一个参数设置 I2C 数据传输速率。
//如果为 false,则数据速率设置为100kbps,如果为 true,则数据速率将设置为
//设置为400kbps。
#if defined (target_IS_TM4C129_RA0)|| \
已定义(TARGET_IS_TM4C129_RA1)|| \
已定义(TARGET_IS_TM4C129_RA2)
I2CMasterInitExpClk (I2C0_BASE、ui32SysClock、false);
#else
I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、false);
#endif

//清除 I2C FIFO
//HWREG (I2C0_BASE + I2C_O_FIFOCTL)= 80008000;
}

空 InitConsole (void){
//启用用于 UART0引脚的 GPIO 端口 A。
// TODO:将其更改为您正在使用的 GPIO 端口。
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
//为端口 A0和 A1上的 UART0功能配置引脚复用。
//如果您的器件不支持引脚复用、则无需执行此步骤。
// TODO:更改此选项以选择您正在使用的端口/引脚。
GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);
//启用 UART0以便我们可以配置时钟。
SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
//使用内部16MHz 振荡器作为 UART 时钟源。
UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);
//为这些引脚选择替代(UART)功能。
// TODO:更改此选项以选择您正在使用的端口/引脚。
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);
//初始化控制台 I/O 的 UART
UARTStdioConfig (0、115200、16000000);
}

void main (){
ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480)、120000000);
InitConsole ();
InitI2C0 ();

//Sensorsetup (0xFF、4、2、100、411、4096);
softReset();
I2CSOEND (I2CDEVICE_ADDR,2,MAX30105_MODECONFIG,0x02); //心率
SysCtlDelay (延迟);
I2CSend (I2CDEVICE_ADDR,2,MAX30105_LED1_PULSEAMP,0x01);//用118us 打开红色 LED。


while (1){
RxData = I2CReceive (I2CDEVICE_ADDR、MAX30105_PARTID);
UARTprintf ("部件 ID 为:%x\n"、RxData);
SysCtlDelay (5*Delay);
}

附加的是 I2CEnd 的范围视图(I2CDEVICE_ADDR、2、MAX30105_LED1_PULSEAMP、0x01)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    您没有告诉过 I2CDEVICE_ADDR 等于什么、我必须假设从器件地址+写入位等于0xAE 或您的从器件地址为0x53、对吧? 观察您的示波器、看起来从器件试图为第9位断言 NACK。 但是、即使是全时钟脉冲、也不是 ACK / NACK。 如果从机真的想回复 NACK、则表示地址可能不正确。 您能否先在从器件上对此进行研究? 您说在调用 I2CSend (I2CDEVICE_ADDR,2,MAX30105_LED1_PULSEAMP,0x01)时它不起作用。 当您调用 I2CSend (I2CDEVICE_ADDR、2、MAX30105_MODECONFIG、0x02)时,它是否起作用?

    您的程序看起来很复杂。 您能否从 TivaWare i2c 示例等简单程序开始发送和接收一些数据?

    此外、您在 SCL 和 SCA 总线上使用了什么上拉电阻器?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Charles Tsaaa"]您的程序看起来很复杂

    您好、Charles、

    所以、"正确"-海报的代码非常复杂、而且很长。

    然而-这不是"复杂性"的"结果"-而不是"真正/真正的原因"?

    原因可能源于海报的"开始使用高度复杂的设备"-而不是简单得多的设备-"工作要容易得多、一个?"   (例如、某种程度上、一个小容量 EEPROM "会让您想起!")

    这种"渐进、简化、无限成功"的方法确实有一个名称!   (此处禁用-我们必须假设)

    请注意、海报承认来自外部来源的"借用代码"、因此、"他的"学习过程"中的"如此之多"受到"不智地急于完成?"   (最常"用(最小)思维"剪切/粘贴"来替代"缓慢、具体、渐进式学习!    (即高度强化的学习!)    又名"kiss..."

    此外、海报从未/从未被提示报告其"特定经验水平"、因此所有诊断(也)都过于复杂...   当然,必须考虑到"困难程度",但(显然)所有项目都是"欢迎"(在各级)。   我们注意到、您建议使用"简单项目"、但此处未显示任何项目、它们是吗?   ("回路"-强制一个 I2C 端口用作从端口-并不"简单!"   过去-(正确)呈现了一个小容量 EEPROM。。。)

    海报的"标题/主题"报告、"写数据丢失"-更准确地说、"拒绝简化(H已)、"理解/项目成功缺失!"

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

    您好、Charles、

    我非常确信我的从器件地址和相应寄存器的地址是正确的。 您可以自行查看 Max30101的数据表以及指向 i hv 提供的头文件的链接。  

    对于您的问题:“当您调用 I2CSOEND (I2CDEVICE_ADDR,2,MAX30105_MODECONFIG,0x02)时,它是否起作用?” 请参阅:“例如, 当我在帖子中尝试“I2CSOEND (I2CDEVICE_ADDR等”时。  

    SDA 和 SCL 由4.7K 欧姆电阻器上拉、电压为5V。 我还使用了3.3V 电源。

    嗯、如果您已经研究过数据表和 YUP、这一点并不复杂、我已经尝试过您很久以前建议的那些简单程序。

    P.S:如果您坚持使用我的 fren 主题(写数据丢失)、我将不胜感激。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你(们)好 感谢道义上的支持。 真搞笑。 但我也希望你能为这一职位作出贡献。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    供应商/朋友 Amit Ashara 过去曾制作过详细的应用手册-面向供应商的"MCU、I2C 实施"。 (它是"粘滞"的-我不知道它当前的位置。)

    您的复杂从站可能需要您完全精确地掌握您所使用的所有"API 函数。 例如-我的公司列出了关键/关键外设功能-提供了详细的叙述性说明-以及带有直接相应"示波器电容器"的"支持"-(两者)针对每个 API 功能说明和阐明了 MCU 的信号输出!

    与往常一样-如果您对"更简单的 I2C 程序"有"很好的理解"(找到的最佳公司/我仍然找到的)教学-正在进行具有小容量(最大256字节) EEPROM 的转换)-那么您的交易过程中每个步骤的"系统测试-验证"-(所有这些都通过适当的示波器 CAP 记录) 然后用"多种(受过学校教育)的眼睛"来看待-最常说的是、"成功之路"。

    正如"kiss"所说的-永远不会以高于最小值(100kbps)的速度"开始"-您的目标是让您的交易"一切机会"取得成功。 从器件和主器件之间的隔离应该是最小的-并且您必须确保从器件完全/正确供电-并且从器件和主器件的接地确实是常见的!

    如果连接了"复杂从器件"、则需要缓慢、仔细(且适当)地监控单个事务。 公司/我不"相信"快捷方式-您对交易顺序的每个/每个阶段提出明确的范围上限(在您进行全面审查/研究之后)、这似乎是"吸引/吸引他人-加入您的寻找..."的最佳方式。 (可能)

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

    您好、您提到过"永远不会启动"且高于最小值(100kbps)"。 这是正确的、但在我的代码中、我相信我的 hv 也使用了100kbps。 我错过了什么吗?
    关于"你必须确保受控器件完全/正确供电-并且受控器件和主器件的接地确实很常见!"、有很好的建议、我将对此进行仔细检查。
    但是、根据我的代码、I2CRead 工作得非常好。 我可以读取 PARTID (MAX30105_PARTID)和其他寄存器、而不会出现任何问题。 这就是 I2CSend 的 hv 问题、它间歇性工作(但只有10%的时间)。

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

    您好!

    1.您说“附件是 I2CEND (I2CDEVICE_ADDR、2、MAX30105_LED1_PULSEAMP、0x01)的范围视图”。 这就是为什么我问"当你调用 I2CSOEND (I2CDEVICE_ADDR、2、MAX30105_MODECONFIG、0x02)时它是否正常工作"。我认为提出这样的问题没有任何问题。

    2、我说示波器的第9位看起来好像有一个 NACK 被从器件应答。 您是否有机会对此进行调查? NACK 可能会导致主器件停止。 当您说 I2CRead 正常时、第9位在示波器上看起来是什么样的?

    3.我建议您尝试用两条线替换下面的一行,如图所示。 对于实验、您也可以尝试 SysCtlDelay(10)而不是  while(!I2CMasterBusy(I2C0_BASE));

    while(I2CMasterBusy(I2C0_BASE));

    使用  

    while(!I2CMasterBusy(I2C0_BASE));

    while(I2CMasterBusy(I2C0_BASE));

    4.我不清楚你的代码。 在 I2CSend (I2CDEVICE_ADDR,2,MAX30105_LED1_PULSEAMP,0x01)中,您将2作为参数数传递给函数。 但在您拥有的函数内  for(i = 1; i < (num_of_args - 1); i++). What is inside the loop is not executed, isn't? Doesn't it just finish with the one transmit data after you call I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH).

    5.当你说 I2CSend()的工作时间是10%时,这意味着什么? 您是否继续运行相同的程序, 并且 I2CSend (I2CDEVICE_ADDR,2,MAX30105_LED1_PULSEAMP,0x01)的10%时间将正常工作,而另外90%的时间将不工作? 这让我觉得你应该调查 NACK。 检查 I2C 状态寄存器并查看主器件是否检测到 NACK。

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

    请允许我"再次敦促"介绍"范围上限"和产生它们的确切用户代码-涵盖所有"发送"功能。

    经常出现的情况-一套眼睛错过-"新鲜的眼睛"快速/轻松检测到它!   (尤其是那些"新鲜眼睛"(适当)激发了积极性的情况!)

    的确-正如供应商 Charles (反复)所说的-"任何"NAK 干扰-并使您的代码、时序、互连-都可疑!

    在此处执行这些操作-您需要正确确认:从设备的正确电源(在交易期间保持);" MCU 与从设备的紧密性"(已请求-但未说明);以及最近的示波器电容-消除了您的"帮助者"的动机、以便(不单独地)进一步提供帮助...

    这里没有"导致您的问题"-我们(非常)正在尝试引导和帮助...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 CB1、
    NACK 看起来很窄。 只要在 SCL 为高电平时它不发生变化、就不应对它进行采样。 但是、它看起来确实是可疑的。 这就是我想在 I2CRead 上看到第9位波形的原因、因为它根据海报工作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Charles、

    虽然我理解您(有点奇异)的 NAK 问题-这是一种效果(不是原因)-这是不是吗?

    因此-我们的时间/努力受到"有限关注"的严重影响-这解释了我对"示波器盖"(直接与他们的启动代码关联)的请求、即海报的"完整"(可疑/缺失)从属写!

    请注意、我(经常)努力寻求"通用解决方案"、这种解决方案将带来远远超过单个帖子或海报的好处!
    示波器盖、展示海报的代码- MCU 的输出-和从器件的响应-到目前为止-最好证明是"解决!" (他们当然是“吻”。)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    经过进一步调查后、I2CREAD 也无法正常工作。 与 I2CWrite 类似、它间歇性工作。 但是我发现、通过删除" while (I2CMasterBusy (I2C0_BASE))"并将其替换为100ms 延迟、我能够毫无问题地读取寄存器。 但是、通过查看 I2C 读取的示波器电容器、"重复启动"条件似乎很长。

    已附加屏幕截图并已修改 I2CRead。

    P.S:这种方法不能解决 I2CWrite 的问题。

    "重复启动"条件:

    修改的 I2CRead 条件:

    静态无符号长整型 WaitI2CDone (unsigned int long ulBase){
    //等待直到传输完成
    //while (I2CMasterBusy (I2C0_BASE));
    SysCtlDelay (my_delay);
    
    //返回 I2C 错误代码
    返回 I2CMasterErr (I2C0_BASE);
    }
    
    //读取从器件
    上的指定寄存器 uint32_t I2Creceive (uint32_t slave_addr、uint8_t reg)
    {
    UARTprintf ("输入的接收\n");
    uint8_t data = 0;
    int16_t iERR_master_none;
    //指定我们要向写入(寄存器地址)
    //从器件
    I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);
    
    //指定要读取的寄存器
    I2CMasterDataPut (I2C0_BASE、reg);
    
    //将控制字节和寄存器地址字节发送到从器件
    I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
    
    //等待 MCU 完成事务
    SysCtlDelay (my_delay);
    
    //指定我们将从从从器件读取
    I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);
    
    //发送控制字节并从我们的寄存器中读取
    //specified
    I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);
    
    if (i2c_err!= WaitI2CDone (I2C0_BASE)){
    数据= I2CMasterDataGet (I2C0_BASE);
    UARTprintf ("数据中的读取错误:%x\n"、数据);
    }
    
    //等待 MCU 完成事务
    SysCtlDelay (my_delay);
    
    UARTprintf ("读取寄存器:%d \n"、reg);
    //返回从指定寄存器提取的数据
    返回 I2CMasterDataGet (I2C0_BASE);
    }