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.

[参考译文] ADS1299:写入和读取寄存器时出现意外结果

Guru**** 2563000 points
Other Parts Discussed in Thread: ADS1299

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1019880/ads1299-unexpected-result-when-writing-and-reading-registers

器件型号:ADS1299

在对 ADS1299上的寄存器进行写入和读取时、我会得到不一致和意外的结果。

我通过发送命令 reset (0x06)复位来启动 ADS。 然后、我使用命令 SDATAC (0x11)。
使用 RREG (0x20)并从寄存器 CONFIG1 (0x01)读取 CONFIG4 (0x17)、我将获得数据表中规定的预期结果。

TX 注释 复位 SDATAC RREG + 0x01 16 (+1)个寄存器
TX 06 11. 21. 16. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 等等
RX 00 3c E0 00 00 96 C0 60 00 61. 61. 61. 61. 61. 61. 61. 61. 00 等等
RTX 注释 配置1 CONFIG2 接口3. 通道1SET CH2SET CH3SET CH4SET CH5SET CH6SET CH7SET CH8SET BIAS_SENSP

当写入寄存 器(WREG) CH1SET 并将其设置为例如0xF6 (该值应有效)、然后再次读取(RREG)寄存器时、我得到  

TX 注释 复位 SDATAC WREG + CH1SET_addr 0 (+1)个要写入的寄存器 写入值 SDATAC RREG + CONFIG1_addr 16 (+1)个寄存器进行读取
TX 06 11. 45. 00 B6. 11. 21. 16. 00 00 00 00 00 00 00 00 00 00 等等
RX 00 00 E0 00 00 7F 47. FF 96 C0 60 00 7F 61. 61. 61. 0061. 等等
RX 注释 配置1 CONFIG2 接口3. LOFF 通道1SET CH2SET CH3SET CH4SET CH5SET

请注意、CH1SET 获得的值错误。 但是、如果我尝试将 CH1SET 设置为0x20 (由于保留了几个位、该设置不应有效?)、则 RREG 显示正确的结果。
此外、ADS 通常会提供更多错误值、这些值不是很正确。 以下命令与上述命令相同、但结果完全不同。

TX 注释 复位 SDATAC WREG + CH1SET_addr 0 (+1)个要写入的寄存器 写入值 SDATAC RREG + CONFIG1_addr 16 (+1)个寄存器进行读取
TX 06 11. 45. 00 B6. 11. 21. 16. 00 00 00 00 00 00 00 00 00 00 等等
RX 00 00 E0 00 00 7F FF 00 00 00 0f 00 00 00 00 00 等等
RX 注释 配置1 CONFIG2 接口3. LOFF 通道1SET CH2SET CH3SET CH4SET CH5SET

我的最佳猜测是、这会是与计时相关的一些错误。 我在某个地方读出、时序问题可能会在读取寄存器时导致错误。


尝试写入 CH1SET 和 CH2SET 会得到更多奇数值。 例如、如果我设置 CH1SET = 0x20且 CH2SET = 0x30、我将得到该结果。

TX
RX 20. 61. 30 61.
RX 注释 通道1SET CH2SET CH3SET CH4SET

CH2SET 和 CH3SET 似乎已切换。 我已经对发送的值进行了双倍和三倍检查。

数据表中介绍的时序有多重要? 在多字节命令中、我不是在 TX 之间等待1.46µs μ s、而是等待1ms、这会导致问题吗?


如果您对 我可能会做什么或 我可以做些什么来缩小问题来源的搜索范围有任何想法、我很感谢您的帮助。

提前感谢您!

一些相关代码

ADS_Transmit(&(uint8_t) {ADS_CMD_RESET}, 1);

	HAL_Delay(500);	// Wait for power up (min 180 ms)

	//	ADS is waken up in RDATAC mode
	ADS_Transmit(&(uint8_t){ADS_CMD_SDATAC},1);

    // ADS_CH1SET_ADDR = 0x05
	ADS_WriteReg(ADS_CH1SET_ADDR, 0x20);

    // ADS_CH2SET_ADDR = 0x06
	ADS_WriteReg(ADS_CH2SET_ADDR, 0x15);

	ADS_ReadReg(ADS_CONFIG1_ADDR, 17);

	uint8_t tmp;

	 while (1)
	  {
	      ADS_DRDY_Wait();
		  HAL_Delay(1);
		  HAL_SPI_Receive(&hspi3, &tmp, 1, 100);
		  HAL_Delay(500);
		  
	  }

 

/*
 *	\brief Transmits data over SPI to ADS1299. 
 *	@param data Array of data to be transmitted. If only one byte,
 *	please dereference (&data) parameter when calling function.
 *	@param size Number of bytes in the data
 */
void ADS_Transmit(uint8_t* data, uint16_t size)
{
	ADS_DRDY_Wait();		//TODO: Visst ska´re va så?
//	HAL_GPIO_WritePin(ADS_CS_BUS, ADS_CS_PIN, RESET);
	HAL_SPI_Transmit(&hspi3, (uint8_t *) data, size, 100);
//	HAL_GPIO_WritePin(ADS_CS_BUS, ADS_CS_PIN, SET);
	HAL_Delay(1);
}


/*
 * 	\brief Is used to wait for DRDY to go low before sending data
 */
void ADS_DRDY_Wait(){
	while(HAL_GPIO_ReadPin(ADS_DRDY_BUS, ADS_DRDY_PIN) == GPIO_PIN_SET);
}
/*
 * 	\brief Read values of ADS1299 register(s).
 * 	@param baseAddr Address of first register to be read.
 * 	@param numOfReg Number of registers to be read following baseAddr, to only read one register, set numOfReg=1
 *
 */
void ADS_ReadReg(uint8_t baseAddr, uint8_t numOfReg)
{
	uint8_t opcode = ADS_CMD_RREG | baseAddr;

	//	Stop Read Data Continuously
	ADS_Transmit(&(uint8_t){ADS_CMD_SDATAC}, 1);

	ADS_Transmit(&opcode, 1);

	ADS_Transmit(&(uint8_t){numOfReg-1}, 1);

    for(int i = 0; i < numOfReg; i++){
        ADS_DRDY_Wait();
        ADS_Transmit(0, numOfReg);
        HAL_Delay(5);
    }
	
}

/*
 * 	\brief Writes to ADS1299 register. CS need to be active (LOW/RESET) during
 * 	the entire transmission!
 * 	@param address Address to register, use @ADS_REGISTERS
 * 	@param val Set value to register
 *
 */
void ADS_WriteReg(uint8_t address, uint8_t val)
{
	uint8_t opcode = ADS_CMD_WREG | address; 
	//	Stop Read Data Continuously
	ADS_Transmit(&(uint8_t){ADS_CMD_SDATAC}, 1);

	ADS_Transmit(&opcode, 1);

	//	Write to 1 register 
	ADS_Transmit(&(uint8_t){0x00}, 1);

	//	Set register to value
	ADS_Transmit(&val, 1);
}

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

    您好 Kristoffer、

    欢迎访问 E2E 论坛、感谢您的发帖!!!

    对于发送多字节命令、tSDECODE 时序对于确保器件有足够的时间对命令进行解码至关重要。 如果超过 tSDECODE 所需的最短时间、则不会出现问题。 我建议探测所有 SPI 信号并确保所有 TX 和 RX 信号都正确、以调试您的问题。 首先向器件发送单字节命令、然后读回该值以查看操作是否正确(请参阅以下链接中的调试步骤)。 一旦可以读取和写入所有寄存器、就可以继续执行多字节命令的操作。

    我无法通过 SPI 与 ADS129x 器件通信。 我应该尝试哪些调试步骤?

    谢谢

    -TC

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

    感谢您的回复!
    包含上述帖子中字节的表格可通过逻辑分析仪看到。 由于我在多个命令中的每个字节之间等待1ms、这大于  tSDECODE、因此这不是问题。
    我有一些奇数误差。 我在一组不同的设置中尝试了 SCLK、从164kHz 一直到4MHz。 一些 SCLK 似乎比其他 SCLK 更好。  
    在我最基本的测试中、我读取了14个寄存器、并将结果与默认值进行比较。 我的最佳结果是328 kHz、这给了我39/40正确的回答-这似乎仍然很低。

    但是、尝试向寄存器 CONFIG1写入值是奇数的。 如数据表中的示例所示、将0x96写入 CONFIG1会在读取寄存器时始终为我提供错误的结果。 在大约一半的结果中、芯片以响应的形式发出0xE0、而在其余的尝试中、DRDY 永远不会变为低电平、因此不会发送任何数据。

    尝试向 CONFIG1写入另一个数字时、例如0x60。 这方面的效果还可以。 我在40次尝试中得到了39次正确的响应。

    我已经卡住了一段时间、我正在尝试找到任何可能导致此问题的小问题。 我已经检查了数字输入电压、没关系。  
    DVDD-DGND = 2.89V、没关系
    AVDD-DVDD = 1.82、没关系
    AVDD-AVSS = 4.72V、略低于4.75V 的最小值。这样的关闭似乎可行吗? 我觉得有一点奇怪、我的结果会因时间而异、并且可以将一些值写入 config1、但永远不可能写入其默认值。   发送复位后、我已超过 tPOR、但仍然存在相同的问题。

    由于试验卡是为 Arduino Nano 设计的、而且我使用的是 STM32F407、因此有大量长而有损的电缆。 这可能是某些奇怪结果的原因。

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

    您好 Kristoffer、

    如果您无法从寄存器读取和写入操作中获得一致的结果、那么您的 SPI 通信似乎存在一些时序问题。 请确保在数据表规格内运行 ADS1299。 正如建议的那样、我将首先检查下面列出的常见问题解答、以供您进行调试。 我建议观察发送的内容、并使用示波器返回 SPI 总线。

    [常见问题解答] ADS129x:如何验证 ADS129x 器件是否仍然正常工作?

    [常见问题解答] ADS129x:通过 SPI 与 ADS129x 器件通信时遇到问题。 我应该尝试哪些调试步骤?

    谢谢

    -TC

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

    您好、再说一次、

    我认为不一致问题已经解决。 我现在使用更稳定的电压源为其供电。 从寄存器读取值时、我会得到一致的结果。

    但是、我在写入寄存器方面仍然有问题。 写入寄存器不再会使任何东西混乱、但它们接收到错误的值(但是、它们始终收到我尝试写入的每个值的相同错误数字)。
    例如、将0xE0写入 CONFIG3不会导致任何变化、即 CONFIG3读取为0x60。
    将0x96写入 CONFIG1会导致 CONFIG1 = 0x16上的读取。

    对于后者、发送的数据(使用示波器检查值)为0x41 (WREG+CONFIG1)、 0x00 (写入1寄存器)、 0x96。  

    我当前使用的是 SCLK 328 kHz (也尝试了1.3 MHz)。 我已经尝试进一步延迟每个字节之间的等待时间、并完全删除它。 我将 CS 保持在低电平。 CPOL=0、CPHA=1。 我已经根据您发送的链接测量了内部电压引脚。

    感谢你的帮助!

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

    您好 Kristoffer、

    您的 SPI 接口的 MSB 位似乎存在一些问题。 您能否从示波器捕获中验证 MSB 位的时序? 请注意、在写入这些寄存器时、需要遵守寄存器中的某些保留位。 例如、CONFIG1[4:3]是需要0b00的保留位。

    谢谢

    -TC

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

    感谢你的答复。 你是对的。 我发送的每个字节中都缺少 MSB。 查看我的设置、我注意到与我相比、我使用的 IDE 对 CPHA 0和1的定义有不同的看法。 我应该早点注意到,这是我方面的一个令人烦恼的错误。
    比较这两种设置之间的差异。 在这两个示例中、发送0x96。 向左、CPOL=0、CPHA=0。 在右侧、CPOL=0、CPHA=1

    CPOL0 CPHA0, 0x96CPOL0, CPHA1, 0x96

    这可能是最高有效位被扔掉的原因。 将其更改为正确的 SPI 模式(如右图所示)会导致新问题。 发送与之前相同的数据、观察示波器上的值、不会返回任何数据。

    0x00 ​

    TX 0x06 0x11 0x21 0x0D 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 等等
    RX 0x00 0xC0 0x00 0xE0 0xE0 0xE0 0xE0 0xE0 0xE0 0xE0 0xE0 0xE0 0xE0 0xE0 等等
    注释 复位 SDATAC RREG 配置1 14个寄存器

    Example from table above, a seen using a scope

    我假设0xE0来自 1100 + LOFF_STATP[7:4]。 就像它不能识别 SDATAC 命令、也不能识别任何其他命令。 非常感谢您迄今提供的帮助!

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

    您好、Kris、

    很高兴知道您发现了一些 SPI 问题。

    用于数据检索的24个状态位将始终以0b1100而不是0xE0开头。 请查看您是否能够根据以下常见问题解答中的步骤从器件读取正确的寄存器。

    [常见问题解答] ADS129x:通过 SPI 与 ADS129x 器件通信时遇到问题。 我应该尝试哪些调试步骤?

    谢谢

    -TC

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

    您好!

    啊哈、好的。
    我发送的内容与您链接的图片相同。 没有。 它会不断地以似乎随机的方式从0xE0、0xC0和0x00进行吐出。 但是、更改为 CPOL=1和 CPHA=0似乎是个诀窍。 当 CPOL=1、CPHA=0时、我能够在读取/写入寄存器时读取和写入所有寄存器、而不会发生任何奇怪的情况。

    我已经对通道1进行了一些测试、在连接到电源并更改输入时获得了合理的结果。 但是、当我缩短 IN1P 和 IN1N 时、我希望通道1上的输出为0或接近0。 但它大约为0xFFFFFF00。 可能不像我所设想的那样工作。  

    现在、我将把它保留在错误的 CPOL 和 CPHA 中、因为它目前似乎可以正常工作。 非常感谢您的帮助!

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

    您好、Kris、

    感谢您的更新。 我将关闭此主题。 如果您有进一步的问题、请打开另一个主题。  

    谢谢

    -TC