STM32H7并行读取AD7606数据以及片内AD值不准解决办法

Posted 花开花落的个人博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32H7并行读取AD7606数据以及片内AD值不准解决办法相关的知识,希望对你有一定的参考价值。

一、硬件

先了解一下AD7606,16位,单电源,200k采样率,8路,除了贵没有其他缺点,数据相当的稳,一个5V供电,不用运放的情况下采集电压精度可以达到1mv,非常Nice

与单片机相连

单片机

二、嵌入式软件

#include "ad7606.h"
#include "stdio.h"
#include "cmsis_os.h"

void delay_us(uint32_t delay)

	uint32_t i=0;
	for(i=0;i<delay;i++)
	
		__NOP();
	


void delay_ms(uint32_t delay)

	osDelay(delay);



AD7606CHDataREG ADCHData = 


;

short adc_read_data()

	short temp=0,j;      	  
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_15))temp++;   
	temp=temp<<1;  
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_14))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_13))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_11))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_10))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_9))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_8))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_7))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_6))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_5))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_4))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_3))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_2))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_1))temp++;   
	temp=temp<<1; 
	if( HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_0))temp++;   
	return temp;


void AD7606Initialization(unsigned char OverSampleRate)

	delay_ms(1);
	ADC_RESET_L; //初始复位管脚低电平
	switch(OverSampleRate)//采样率选择
  
		case 200:OS_NO;break;
		case 100:OS_2;break;
		case 50: OS_4;break;
		case 25: OS_8;break;
		default: OS_NO;break;
	
	ADC_CS_H;
	ADC_CONV_H;
	ADC_RD_H;
	delay_ms(1);


void AD7606Reset(void)

		//脉冲50nS复位有效 
		BYTE_SEL_L;//并行
		ADC_STBY_H;//开始工作
		ADC_RESET_H;
		delay_us(1);
		ADC_RESET_L;
		delay_us(1);


void AD7606ReadSample(void)

	uint8_t i = 0;
	short Ary16[8];
//开启转换
	ADC_CONV_L;
  delay_us(1);	
	ADC_CONV_H;
  delay_us(1);
	//当前数据状态 低电平可读取新数据 高电平可读取上次结果
	while(ADC_Busy_State)
	
 
	
	delay_us(1);
	ADC_CS_L;
	ADC_RD_L;
	delay_us(35);//35个ns
	Ary16[0]=adc_read_data();
	ADC_RD_H;//高电平宽度为15个ns最少
	delay_us(35);//35个ns
	ADC_RD_L;
	delay_us(35);//35个ns
	Ary16[1]=adc_read_data();
	ADC_RD_H;//高电平宽度为15个ns最少
	delay_us(35);//35个ns
	ADC_RD_L;
	delay_us(35);//35个ns
	Ary16[2]=adc_read_data();
	ADC_RD_H;//高电平宽度为15个ns最少
	delay_us(35);//35个ns	
	ADC_RD_L;
	delay_us(35);//35个ns		
	Ary16[3]=adc_read_data();
	ADC_RD_H;//高电平宽度为15个ns最少
	delay_us(35);//35个ns	
	ADC_RD_L;
	delay_us(35);//35个ns
	Ary16[4]=adc_read_data();
	ADC_RD_H;//高电平宽度为15个ns最少
	delay_us(35);//35个ns
	ADC_RD_L;
	delay_us(35);//35个ns
	Ary16[5]=adc_read_data();
	ADC_RD_H;//高电平宽度为15个ns最少
	delay_us(35);//35个ns
	ADC_RD_L;
	delay_us(35);//35个ns
	Ary16[6]=adc_read_data();
	ADC_RD_H;//高电平宽度为15个ns最少
	delay_us(35);//35个ns	
	ADC_RD_L;
	delay_us(35);//35个ns	
	Ary16[7]=adc_read_data();
	ADC_RD_H;ADC_CS_H;//高电平宽度为15个ns最少
	for(i=0;i<8;i++)
	
		if(Ary16[i]<0)
		
			Ary16[i] = 0;
		
	
	ADCHData.REG.AD7606_1 = ((float)Ary16[0]/32768) * 5;
	ADCHData.REG.AD7606_2 = ((float)Ary16[1]/32768) * 5;
	ADCHData.REG.AD7606_3 = ((float)Ary16[2]/32768) * 5;
	ADCHData.REG.AD7606_4 = ((float)Ary16[3]/32768) * 5;
	ADCHData.REG.AD7606_5 = ((float)Ary16[4]/32768) * 5;
	ADCHData.REG.AD7606_6 = ((float)Ary16[5]/32768) * 5;
	ADCHData.REG.AD7606_7 = ((float)Ary16[6]/32768) * 5;
	ADCHData.REG.AD7606_8 = ((float)Ary16[7]/32768) * 5;
#ifndef __AD7606_H__
#define __AD7606_H__

#include "gpio.h"

//ADC7606——AD采集相关参数管脚定义//
//推挽输出模式
#define    ADC_CONV_H            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);//通道转换开始
#define    ADC_CONV_L            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
#define    ADC_RESET_H           HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);//复位管脚使能
#define    ADC_RESET_L           HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);  
#define    ADC_RD_H              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET);//
#define    ADC_RD_L           	 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET);
#define    ADC_CS_H            	 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_SET);
#define    ADC_CS_L           	 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_RESET);

//工作模式选择H正常工作L休眠
#define 	ADC_STBY_H  					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
#define 	ADC_STBY_L  					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
//数据传输模式选择,
#define 	BYTE_SEL_H  					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
#define 	BYTE_SEL_L  					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);

//工作模式选择H正常工作L休眠
#define 	ADC_10V  							HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
#define 	ADC_5V  							HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
//RD下降沿后读取,高电平可提供V1结果,下一个下降延
#define    ADC_FSTDATA           HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15)
//当前数据状态 低电平可读取新数据 高电平可读取上次结果
#define    ADC_Busy_State        HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_10)
//并行数据采集
#define	ADC_PDate	GPIOD->IDR&0xFFFF
 //000  200K 调节采样模式---推挽输出
#define    ADC_OS0_H          HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
#define    ADC_OS0_L          HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
#define    ADC_OS1_H          HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_SET);
#define    ADC_OS1_L          HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_RESET);
#define    ADC_OS2_H          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
#define    ADC_OS2_L          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
//采样率设置
#define   OS_NO  ADC_OS0_L;ADC_OS1_L;ADC_OS2_L;
#define   OS_2   ADC_OS0_H;ADC_OS1_L;ADC_OS2_L;
#define   OS_4   ADC_OS0_L;ADC_OS1_H;ADC_OS2_L;
#define   OS_8   ADC_OS0_H;ADC_OS1_H;ADC_OS2_L;
typedef struct

	struct
	
		float    AD7606_1;      //
		float    AD7606_2;      
		float    AD7606_3;    	
		float    AD7606_4;     
		float    AD7606_5;   
		float    AD7606_6; 
		float    AD7606_7;
		float    AD7606_8;  
		float    AD_9;  
		float    AD_10;  
		float    AD_11;  
		float    AD_12;  
		float    AD_13;  
	REG;
	struct
	
		float    C1;      //
		float    C2;      
		float    C3;    	
		float    C4;     
		float    C5;   
		float    C6; 
		float    C7;
		float    C8;  
		float    C9;  
		float    C10;  
		float    C11;  
		float    C12;  
		float    C13;  
	VALUE;
AD7606CHDataREG; 
extern AD7606CHDataREG ADCHData;
void AD7606Initialization(unsigned char OverSampleRate);//初始采样率定义
void AD7606ReadSample(void);//周期采样
void AD7606ReadOnceSample(void);//单次数据采集
void AD7606Reset(void);

#endif

调用代码

void sample_task(void const * argument)

	AD7606Reset();
	AD7606Initialization(200);
	for(;;)
  
		vTaskSuspendAll();
		AD7606ReadSample();
		get_adc_value();
		printf("[adc]:c1:%.4fv,c2:%.4fv,c3:%.4fv,c4:%.4fv,c5:%.4fv,c6:%.4fv,c7:%.4fv,c8:%.4fv,c9:%.4fv,c10:%.4fv,c11:%.4fv,c12:%.4fv\\r\\n",ADCHData.REG.AD7606_1,ADCHData.REG.AD7606_2,ADCHData.REG.AD7606_3,ADCHData.REG.AD7606_4,ADCHData.REG.AD7606_5,ADCHData.REG.AD7606_6,ADCHData.REG.AD7606_7,ADCHData.REG.AD7606_8,ADCHData.REG.AD_9,ADCHData.REG.AD_10,ADCHData.REG.AD_11,ADCHData.REG.AD_12);
		printf("[adc]:c1:%.4f,c2:%.4f,c3:%.4f,c4:%.4f,c5:%.4f,c6:%.4fv,c7:%.4f,c8:%.4f,c9:%.4f,c10:%.4f℃,c11:%.4f℃,c12:%.4f℃\\r\\n",ADCHData.VALUE.C1,ADCHData.VALUE.C2,ADCHData.VALUE.C3,ADCHData.VALUE.C4,ADCHData.VALUE.C5,ADCHData.VALUE.C6,ADCHData.VALUE.C7,ADCHData.VALUE.C8,ADCHData.VALUE.C9,ADCHData.VALUE.C10,ADCHData.VALUE.C11,ADCHData.VALUE.C12);
		xTaskResumeAll();
		osDelay(1000);
	

三、STM32H7的AD采集

测试发现AD采集到的电压要远小于实际电压,H7的AD还是16位的,不能这么拉跨吧,在网上搜索了一圈,找了的解决办法,延长AD的采样时间比校正AD管用的多,Config.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    adc.c
  * @brief   This file provides code for the configuration
  *          of the ADC instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "adc.h"

/* USER CODE BEGIN 0 */

#include "ad7606.h"
#include "stdio.h"
#include "cmsis_os.h"

#define ADC_CONVERTED_DATA_BUFFER_SIZE   ((uint32_t)  32)   /* Size of array aADCxConvertedData[] */
ALIGN_32BYTES (static uint16_t   aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]);
/* USER CODE END 0 */

ADC_HandleTypeDef hadc1;

/* ADC1 init function */
void MX_ADC1_Init(void)


  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_MultiModeTypeDef multimode = 0;
  ADC_ChannelConfTypeDef sConfig = 0;

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_16B;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  
    Error_Handler();
  

  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  
    Error_Handler();
  

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_7;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  
    Error_Handler();
  
  /* USER CODE BEGIN ADC1_Init 2 */
	//HAL_ADCEx_Calibration_Start(&hadc1,ADC_CALIB_OFFSET_LINEARITY,ADC_DIFFERENTIAL_ENDED);
  /* USER CODE END ADC1_Init 2 */



void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)


  GPIO_InitTypeDef GPIO_InitStruct = 0;
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = 0;
  if(adcHandle->Instance==ADC1)
  
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */

  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
    PeriphClkInitStruct.PLL2.PLL2M = 4;
    PeriphClkInitStruct.PLL2.PLL2N = 8;
    PeriphClkInitStruct.PLL2.PLL2P = 1;
    PeriphClkInitStruct.PLL2.PLL2Q = 2;
    PeriphClkInitStruct.PLL2.PLL2R = 2;
    PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
    PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
    PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
    PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    
      Error_Handler();
    

    /* ADC1 clock enable */
    __HAL_RCC_ADC12_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PA7     ------> ADC1_INP7
    PC4     ------> ADC1_INP4
    PC5     ------> ADC1_INP8
    PB0     ------> ADC1_INP9
    */
    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  


void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)


  if(adcHandle->Instance==ADC1)
  
  /* USER CODE BEGIN ADC1_MspDeInit 0 */

  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC12_CLK_DISABLE();

    /**ADC1 GPIO Configuration
    PA7     ------> ADC1_INP7
    PC4     ------> ADC1_INP4
    PC5     ------> ADC1_INP8
    PB0     ------> ADC1_INP9
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_7);

    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_4|GPIO_PIN_5);

    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0);

  /* USER CODE BEGIN ADC1_MspDeInit 1 */

  /* USER CODE END ADC1_MspDeInit 1 */
  


/* USER CODE BEGIN 1 */
volatile uint32_t uhADCxConvertedValue = 0;

//共33条记录
const float NCP18XH103F03RB_10k_table[]=
	195.652,
	148.171,
	113.347,
	87.559,
	68.237,
	53.650,
	42.506,
	33.892,
	27.219,
	22.021,
	14.674,
	12.081,
	10.000,
	8.315,
	6.948,
	5.834,
	4.917,
	4.161,
	3.535,
	3.014,
	2.586,
	2.228,
	1.925,
	1.669,
	1.452,
	1.268,
	1.110,
	0.974,
	0.858,
	0.758,
	0.672,
	0.596,
	0.531
;

float NCP18XH103F03RB_10k_lookup(float res)

	float value = -40;
	int16_t index = 0;
	int32_t decimals = 0;
	for(index = 0;index < 33;index++)
	
		if(NCP18XH103F03RB_10k_table[index]<res)
		
			break;
		
	
	/** temperature overflow **/
	if(index >= 32) return 1200;
	if(index == 0) return -350;
	value = value + (index*5) - ((res - NCP18XH103F03RB_10k_table[index])/(NCP18XH103F03RB_10k_table[index-1]-NCP18XH103F03RB_10k_table[index]))*5;
	return value;


float get_ntc_temp(float voltage) //input : AD voltage (raw data). 10k/(10k+res)=ad_temp*1800/4096/1800
  float res;
	/** temperature sensor no connect **/
	if(voltage < 0) return -500;
	
	//10k电阻
  res = (10*3.26 - voltage * 10)/voltage;
	return NCP18XH103F03RB_10k_lookup(res);


uint16_t GetAdValue(uint32_t channel)

	uint16_t i;
	ADC_ChannelConfTypeDef sConfig;
	uhADCxConvertedValue = 0;

  /* Parameter discarded because offset correction is disabled */

	sConfig.Channel = channel;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
	
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  
    return 0;
  

  
  /*##-3- Start the conversion process #######################################*/
  if (HAL_ADC_Start(&hadc1) != HAL_OK)
  
    /* Start Conversation Error */
    return 0;
  

  /*##-4- Wait for the end of conversion #####################################*/
  /*  For simplicity reasons, this example is just waiting till the end of the
      conversion, but application may perform other tasks while conversion
      operation is ongoing. */
  if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
  
    /* End Of Conversion flag not set on time */
		HAL_ADC_Stop(&hadc1);
    return 0;
  
  else
  
    /* ADC conversion completed */
		for(i=0;i<10;i++)
		
			HAL_ADC_GetValue(&hadc1);
		
    /*##-5- Get the converted value of regular channel  ########################*/
		for(i=0;i<10;i++)
		
			uhADCxConvertedValue += HAL_ADC_GetValue(&hadc1);
		
		uhADCxConvertedValue = uhADCxConvertedValue/10;
  
	HAL_ADC_Stop(&hadc1);
	return 1;


void get_adc_value(void)

		int16_t ret = 0;
	  float value = 0,value1 = 0;
		HAL_ADC_MspDeInit(&hadc1);
	  HAL_ADC_MspInit(&hadc1);
	  HAL_Delay(1000);
		ret = GetAdValue(ADC_CHANNEL_8);
		if(ret==0)
		
			printf("adc9电压转换失败\\r\\n");
		
		else
		
			value = (3.26/65535)*uhADCxConvertedValue;
		
		ADCHData.REG.AD_9 = value;
		HAL_Delay(100);
		ret = GetAdValue(ADC_CHANNEL_7);
		if(ret==0)
		
			printf("adc10电压转换失败\\r\\n");
		
		else
		
			value = (3.26/65535)*uhADCxConvertedValue;
			ADCHData.VALUE.C10 =	get_ntc_temp(value);
			ADCHData.REG.AD_10 = value;
		
		ret = GetAdValue(ADC_CHANNEL_4);
		if(ret==0)
		
			printf("adc11电压转换失败\\r\\n");
		
		else
		
			value = (3.26/65535)*uhADCxConvertedValue;
			ADCHData.VALUE.C11 =	get_ntc_temp(value);
			ADCHData.REG.AD_11 = value;
		
		
		ret = GetAdValue(ADC_CHANNEL_9);
		if(ret==0)
		
			printf("adc12电压转换失败\\r\\n");
		
		else
		
			value = (3.26/65535)*uhADCxConvertedValue;
			ADCHData.VALUE.C12 =	get_ntc_temp(value);
			ADCHData.REG.AD_12 = value;
		

/* USER CODE END 1 */

AD值非常准

c10:1.7133v,c11:1.7064v,c12:1.6983v
c10:22.8853℃,c11:22.6582℃,c12:22.3859℃

以上是关于STM32H7并行读取AD7606数据以及片内AD值不准解决办法的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式新闻早班车-第13期

嵌入式STM32+STM32CubeMX调试AD7606记录

来自不同 AD7606 通道的混合电压读数

FMC 比 STM32H7 上的 QSPI 慢?

STM32H7教程第41章 STM32H7的BDMA应用之控制任意IO做PWM和脉冲数控制

STM32H7教程第43章 STM32H7的DMA应用之双缓冲控制任意IO和脉冲数控制