ADC MCP3561 不返回转换值
ADC MCP3561 not returning conversion values
我是不得已才来这里的。
我正在使用没有外部时钟 (MCLK) 且未使用中断 (irq)(均浮动)的 MCP3561。
DATASHEET
我最初尝试 运行 快速命令来获取 adcdata 但它全部返回 0。
然后我尝试相应地设置所有配置位,并且仍然在读取 adcdata 时它 returns 数据全为 0。但是在增量读取所有地址时,我可以看到来自配置的数据很好。
t_buf[0] = 0b01110110; //slaveaddr + lockregister + wr
t_buf[1] = 0b10100101; // wr 0xa5 to unlock writing to registers
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0);
HAL_SPI_Transmit(&hspi1, t_buf, 2, 1000); //unlock resgisters
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1);
t_buf[0] = 0b01000110; //slave address - reg address - write
t_buf[1] = 0b01100011; //config 0
t_buf[2] = 0b00011100; //config 1
t_buf[3] = 0b10101011; //config 2
t_buf[4] = 0b11000000; //config 3 - bit 4-5 is data_format[1:0]
t_buf[5] = 0b00100000; //irq register
t_buf[6] = 0b00000001; //mux
t_buf[7] = 0b00000000; //7-8-9 scan register
t_buf[8] = 0b00000000;
t_buf[9] = 0b00000000;
t_buf[10] = 0b00000000; //10-11-12 timer delay value
t_buf[11] = 0b00000000;
t_buf[12] = 0b00000000;
t_buf[13] = 0b00000000; //13-14-15 offset calibration
t_buf[14] = 0b00000000;
t_buf[15] = 0b00000000;
t_buf[16] = 0b10000000; //16-17-18 gain calibration //0x80 is default 1x gain
t_buf[17] = 0b00000000;
t_buf[18] = 0b00000000;
t_buf[19] = 0b10010000; //19-20-21 reserved should be set at 0x90
t_buf[20] = 0b00000000;
t_buf[21] = 0b00000000;
t_buf[22] = 0b01010000; // reserved set at 0x50
t_buf[23] = 0b00000000; // lock register 0xa5 unlock anything else lock
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0);
HAL_SPI_Transmit(&hspi1, t_buf, 23, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1);
我的阅读功能:
float Get_ADC(void){
float val;
float sensor_val;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0); //pull down cs line on adc to enable spi on chip
t_buf[0] = 0b01000011;
t_buf[1] = 0b00010000;
//HAL_SPI_TransmitReceive(&hspi1, t_buf, r_buf, 3, 1000);
HAL_SPI_Transmit(&hspi1, t_buf, 1, 1000);
HAL_SPI_Receive(&hspi1, r_buf, 28, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1); //return cs line to high to disable spi on chip
return(sensor_val);
以及我读到的数据:
r_buf[0] uint8_t 0 '[=12=]'
r_buf[1] uint8_t 0 '[=12=]'
r_buf[2] uint8_t 0 '[=12=]'
r_buf[3] uint8_t 99 'c'
r_buf[4] uint8_t 28 '4'
r_buf[5] uint8_t 171 '«'
r_buf[6] uint8_t 192 'À'
r_buf[7] uint8_t 48 '0'
r_buf[8] uint8_t 1 '[=12=]1'
r_buf[9] uint8_t 0 '[=12=]'
r_buf[10] uint8_t 0 '[=12=]'
r_buf[11] uint8_t 0 '[=12=]'
r_buf[12] uint8_t 0 '[=12=]'
r_buf[13] uint8_t 0 '[=12=]'
r_buf[14] uint8_t 0 '[=12=]'
r_buf[15] uint8_t 0 '[=12=]'
r_buf[16] uint8_t 0 '[=12=]'
r_buf[17] uint8_t 0 '[=12=]'
r_buf[18] uint8_t 128 '0'
r_buf[19] uint8_t 0 '[=12=]'
r_buf[20] uint8_t 0 '[=12=]'
r_buf[21] uint8_t 144 '0'
r_buf[22] uint8_t 0 '[=12=]'
r_buf[23] uint8_t 0 '[=12=]'
r_buf[24] uint8_t 80 'P'
r_buf[25] uint8_t 165 '¥'
r_buf[26] uint8_t 0 '[=12=]'
r_buf[27] uint8_t 12 '\f'
r_buf[28] uint8_t 0 '[=12=]'
r_buf[3] returns 写入的 config0 和 .... 以 r_buf[28] 锁定寄存器结束。
r_buf[0],1,[2] 应该 returning 我的 24 位数据,无论配置设置的什么组合,它总是 return 0。我目前有一个光度二极管分别连接到 ch0-ch1。它位于连接到带有 spi_mode(1,1).
的 stm32l412 芯片的印刷电路板上
我目前的假设是 adc 永远不会离开 shutdown/sleep 模式并且不会进行任何转换。
-罗斯
看来你用的是STM32 HAL。
我发现在HAL_SPI_Transmit()
之后,我必须在下一次SPI操作之前调用HAL_SPIEx_FlushRxFifo(&hspi1);
。这是 STM32 HAL 的一个怪癖。或者,HAL_SPI_TransmitReceive()
在没有 flush 调用的情况下工作。
此外,您的调用 HAL_SPI_Transmit(&hspi1, t_buf, 1, 1000);
使用缓冲区大小 1,但您之前初始化了 t_buf
的两个字节,所以我猜您想发送两个字节。
区分是ADC还是SPI的问题,可以尝试读取ADC的内部温度;通过在通道 MCP3564_REGISTER_MUX_VIN_PLUS_TEMP_P
和 MCP3564_REGISTER_MUX_VIN_MINUS_TEMP_M
之间读取(然后根据数据表第 5.1.2 节和图 2-32 或 2-33 进行转换)。
我遇到了同样的问题,STM32 和 HAL。
事实证明,您必须将 IRQ 线上拉至 DVDD 或通过将 IRQ[2] 寄存器位设置为 1 来打开内部上拉。这在数据表第 3.4 节中简要提及为
When the IRQ pin is in High-Z mode, an external
pull-up resistor must be connected between DVDD and
the IRQ pin.
我是不得已才来这里的。
我正在使用没有外部时钟 (MCLK) 且未使用中断 (irq)(均浮动)的 MCP3561。
DATASHEET
我最初尝试 运行 快速命令来获取 adcdata 但它全部返回 0。
然后我尝试相应地设置所有配置位,并且仍然在读取 adcdata 时它 returns 数据全为 0。但是在增量读取所有地址时,我可以看到来自配置的数据很好。
t_buf[0] = 0b01110110; //slaveaddr + lockregister + wr
t_buf[1] = 0b10100101; // wr 0xa5 to unlock writing to registers
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0);
HAL_SPI_Transmit(&hspi1, t_buf, 2, 1000); //unlock resgisters
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1);
t_buf[0] = 0b01000110; //slave address - reg address - write
t_buf[1] = 0b01100011; //config 0
t_buf[2] = 0b00011100; //config 1
t_buf[3] = 0b10101011; //config 2
t_buf[4] = 0b11000000; //config 3 - bit 4-5 is data_format[1:0]
t_buf[5] = 0b00100000; //irq register
t_buf[6] = 0b00000001; //mux
t_buf[7] = 0b00000000; //7-8-9 scan register
t_buf[8] = 0b00000000;
t_buf[9] = 0b00000000;
t_buf[10] = 0b00000000; //10-11-12 timer delay value
t_buf[11] = 0b00000000;
t_buf[12] = 0b00000000;
t_buf[13] = 0b00000000; //13-14-15 offset calibration
t_buf[14] = 0b00000000;
t_buf[15] = 0b00000000;
t_buf[16] = 0b10000000; //16-17-18 gain calibration //0x80 is default 1x gain
t_buf[17] = 0b00000000;
t_buf[18] = 0b00000000;
t_buf[19] = 0b10010000; //19-20-21 reserved should be set at 0x90
t_buf[20] = 0b00000000;
t_buf[21] = 0b00000000;
t_buf[22] = 0b01010000; // reserved set at 0x50
t_buf[23] = 0b00000000; // lock register 0xa5 unlock anything else lock
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0);
HAL_SPI_Transmit(&hspi1, t_buf, 23, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1);
我的阅读功能:
float Get_ADC(void){
float val;
float sensor_val;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0); //pull down cs line on adc to enable spi on chip
t_buf[0] = 0b01000011;
t_buf[1] = 0b00010000;
//HAL_SPI_TransmitReceive(&hspi1, t_buf, r_buf, 3, 1000);
HAL_SPI_Transmit(&hspi1, t_buf, 1, 1000);
HAL_SPI_Receive(&hspi1, r_buf, 28, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1); //return cs line to high to disable spi on chip
return(sensor_val);
以及我读到的数据:
r_buf[0] uint8_t 0 '[=12=]'
r_buf[1] uint8_t 0 '[=12=]'
r_buf[2] uint8_t 0 '[=12=]'
r_buf[3] uint8_t 99 'c'
r_buf[4] uint8_t 28 '4'
r_buf[5] uint8_t 171 '«'
r_buf[6] uint8_t 192 'À'
r_buf[7] uint8_t 48 '0'
r_buf[8] uint8_t 1 '[=12=]1'
r_buf[9] uint8_t 0 '[=12=]'
r_buf[10] uint8_t 0 '[=12=]'
r_buf[11] uint8_t 0 '[=12=]'
r_buf[12] uint8_t 0 '[=12=]'
r_buf[13] uint8_t 0 '[=12=]'
r_buf[14] uint8_t 0 '[=12=]'
r_buf[15] uint8_t 0 '[=12=]'
r_buf[16] uint8_t 0 '[=12=]'
r_buf[17] uint8_t 0 '[=12=]'
r_buf[18] uint8_t 128 '0'
r_buf[19] uint8_t 0 '[=12=]'
r_buf[20] uint8_t 0 '[=12=]'
r_buf[21] uint8_t 144 '0'
r_buf[22] uint8_t 0 '[=12=]'
r_buf[23] uint8_t 0 '[=12=]'
r_buf[24] uint8_t 80 'P'
r_buf[25] uint8_t 165 '¥'
r_buf[26] uint8_t 0 '[=12=]'
r_buf[27] uint8_t 12 '\f'
r_buf[28] uint8_t 0 '[=12=]'
r_buf[3] returns 写入的 config0 和 .... 以 r_buf[28] 锁定寄存器结束。
r_buf[0],1,[2] 应该 returning 我的 24 位数据,无论配置设置的什么组合,它总是 return 0。我目前有一个光度二极管分别连接到 ch0-ch1。它位于连接到带有 spi_mode(1,1).
的 stm32l412 芯片的印刷电路板上
我目前的假设是 adc 永远不会离开 shutdown/sleep 模式并且不会进行任何转换。
-罗斯
看来你用的是STM32 HAL。
我发现在HAL_SPI_Transmit()
之后,我必须在下一次SPI操作之前调用HAL_SPIEx_FlushRxFifo(&hspi1);
。这是 STM32 HAL 的一个怪癖。或者,HAL_SPI_TransmitReceive()
在没有 flush 调用的情况下工作。
此外,您的调用 HAL_SPI_Transmit(&hspi1, t_buf, 1, 1000);
使用缓冲区大小 1,但您之前初始化了 t_buf
的两个字节,所以我猜您想发送两个字节。
区分是ADC还是SPI的问题,可以尝试读取ADC的内部温度;通过在通道 MCP3564_REGISTER_MUX_VIN_PLUS_TEMP_P
和 MCP3564_REGISTER_MUX_VIN_MINUS_TEMP_M
之间读取(然后根据数据表第 5.1.2 节和图 2-32 或 2-33 进行转换)。
我遇到了同样的问题,STM32 和 HAL。
事实证明,您必须将 IRQ 线上拉至 DVDD 或通过将 IRQ[2] 寄存器位设置为 1 来打开内部上拉。这在数据表第 3.4 节中简要提及为
When the IRQ pin is in High-Z mode, an external
pull-up resistor must be connected between DVDD and
the IRQ pin.