在对 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);
}



