您好!
我对您的 ADC 有一些问题:ADS8691IPW。
主要问题是缺乏可靠的工作。
它通过跳线连接到 STM32F411E-DISCOS 开发板。
ADC 本身焊接在执行板上以用于调试。
它主要内置于具有四个菊花链单元的定制 PCB 中、但问题是类似的。 
STM 由 USB 供电、ADC 模拟端和数字端通过 Keithley SMU 提供5V 电压。
使用1uF 电解电容器进行去耦。
我已经通过具有类似效果的多个 ADC 进行了迭代。
问题是它仅在连接示波器时起作用。
但在重新设置 STM 或将接地端连接到逻辑分析仪或将数字引脚连接到逻辑分析仪后、或一段时间后、它会停止工作。
我可以通过以下方式使其正常工作:
为 ADC 重置跳线、
断开跳线与逻辑分析仪的连接、
断开逻辑分析仪的接地、
重新连接到逻辑分析仪、
和许多其他组合。 
定制 PCB ADC 原理图: 
在定制 PCB 上、由于寄生引起的过冲和下冲显著降低。
绕过是根据指南进行的。
请注意、还有一个接地引线电感、它看起来会更糟。
(在所有屏幕中、示波器在 SPI 总线上触发)
当它工作时、数据会清晰地显示 

有时在重置后、看起来是这样的: 
或者根本无法正常工作。
我还在 MCU 以及靠近 ADC 的硬件中尝试了上拉和下拉电阻。
此外、还测试了不同的 CLK 速度。
代码:
来自 main 的零件:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == ADC_ALARM_Pin)
{
//This block will be triggered after pin activated.
if(BUTTON_Pin == 1)
{
for(int i = 0; i < 4; i++)
{
read_hword_data();
char *msg = "ADC Alarm working\r\n";
HAL_UART_Transmit(&huart2, msg, sizeof(msg), 100);
}
}
}
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)
{
HAL_SPI_Receive_DMA(&hspi1, RX_Buffer, sizeof(RX_Buffer));
if(sample < 50000)
{
read_adc_data(&adc_handle, RX_Buffer, sample);
sample++;
}
else if(sample == 50000)
{
char *msg = "50 000 samples gathered\r\n";
HAL_UART_Transmit(&huart2, msg, sizeof(msg), 100);
}
}
自定义库:
struct adc_state adc_init() {
struct adc_state state;
/*
for(uint16_t i=0; i<12500; i++) state.data0[i] = '\0';
for(uint16_t i=0; i<12500; i++) state.data1[i] = '\0';
for(uint16_t i=0; i<12500; i++) state.data2[i] = '\0';
for(uint16_t i=0; i<12500; i++) state.data3[i] = '\0';
*/
return state;
}
/*
* 11000_xx_<9-bit address>_ <16-bit data>
* Command used to clear any (or a group of) bits of a register.
* Any bit marked 1 in the data field results in that particular bit of the specified register being reset to 0, leaving the other bits unchanged.
* Half-word command (that is, the command functions on 16 bits at a time).
* LSB of the 9-bit address is always ignored and considered as 0b.(2)
*/
void clear_hword(char *reg)
{
char command[16];
sprintf(command, "11000000%s", reg);
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 0);
}
/*
* 11001_xx_<9-bit address>_ 00000000_00000000
* Command used to perform a 16-bit read operation.
* Half-word command (that is, the device outputs 16 bits of register data at a time).
* LSB of the 9-bit address is always ignored and considered as 0b.
* Upon receiving this command, the device sends out 16 bits of the register in the next frame.
*/
void read_hword(char *reg)
{
char x[8] = "00000000";
char command[16];
sprintf(command, "11001000%s", reg);
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 0);
HAL_SPI_Transmit(&hspi1, x, sizeof(x), 0);
}
void read_hword_data()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
read_hword(DATAOUT_CTL_REG);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* 01001_xx_<9-bit address>_ 00000000_00000000
* Same as the READ_HWORD except that only eight bits of the register (byte read) are returned in the next frame.
*/
void read_word(char *reg)
{
char command[16];
sprintf(command, "01001000%s", reg);
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 0);
}
/*
* 11010_00_<9-bit address>_ <16-bit data>
* Half-word write command (two bytes of input data are written into the specified address).
* LSB of the 9-bit address is always ignored and considered as 0b.
*
* 11010_01_<9-bit address>_ <16-bit data>
* Half-word write command.
* LSB of the 9-bit address is always ignored and considered as 0b.
* With this command, only the MS byte of the 16-bit data word is written at the specified register address. The LS byte is ignored.
*
* 11010_10_<9-bit address>_ <16-bit data>
* Half-word write command.
* LSB of the 9-bit address is always ignored and considered as 0b.
* With this command, only the LS byte of the 16-bit data word is written at the specified register address. The MS byte is ignored.
*/
void write_word(char *reg)
{
char command[16];
sprintf(command, "11010000%s", reg);
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 0);
}
/*
* 11011_xx_<9-bit address>_ <16-bit data>
* Command used to set any (or a group of) bits of a register.
* Any bit marked 1 in the data field results in that particular bit of the specified register being set to 1, leaving the other bits unchanged.
* Half-word command (that is, the command functions on 16 bits at a time).
* LSB of the 9-bit address is always ignored and considered as 0b.
*/
void set_hword(char *reg)
{
char command[16];
sprintf(command, "11011000%s", reg);
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 0);
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void id_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(DEVICE_ID_REG);
char command[16];
sprintf(command,"0000000000000000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void reset_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(RST_PWRCTL_REG);
char command[16];
sprintf(command,"0100010100100000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void sdi_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(SDI_CTL_REG);
char command[16];
sprintf(command,"0000000000000000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void sdo_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(SDO_CTL_REG);
char command[16];
sprintf(command,"0000000100000000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void data_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(DATAOUT_CTL_REG);
char command[16];
sprintf(command,"0100110000000000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void ref_vol_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(RANGE_SEL_REG);
char command[16];
sprintf(command,"0000000000000000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void alarms_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(ALARM_REG);
char command[16];
sprintf(command,"0000110000000000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void alarmh_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(ALARM_H_TH_REG);
char command[16];
sprintf(command,"0000000000000000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
/*
* Configuration described in the documentation in chapter "7.6 Register Maps" (p.48)
* www.ti.com/.../ads8691.pdf
*/
void alarml_config()
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
for(int i = 0; i < 4; i++)
{
write_word(ALARM_L_TH_REG);
char command[16];
sprintf(command,"0000000000000000");
HAL_SPI_Transmit(&hspi1, command, sizeof(command), 10); }
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}
// Initialization of all ADC's registers
void adc_config()
{
id_config();
reset_config();
sdi_config();
sdo_config();
data_config();
ref_vol_config();
alarms_config();
alarmh_config();
alarml_config();
}
//
void read_adc_data(struct adc_state *state, uint8_t *val, uint16_t x)
{
x = x/4;
receiver_check(state, val, x);
read_hword_data();
}
//
void receiver_check(struct adc_state *state, uint8_t *val, uint16_t x)
{
int16_t data;
data = (val[3] << 8) | val[2];