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

这篇具有很好参考价值的文章主要介绍了STM32H7并行读取AD7606数据以及片内AD值不准解决办法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、硬件

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

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

与单片机相连

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

单片机

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

二、嵌入式软件

#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℃文章来源地址https://www.toymoban.com/news/detail-511899.html

到了这里,关于STM32H7并行读取AD7606数据以及片内AD值不准解决办法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 CubeMX 无法将 STM32H7 的最大 CPU 频率设置为 480 MHz

    使用stm32cubemx设置时钟树为480MHz时,提示 cpu clock frequency must be =200MHZ 对于STM32H7 需要CPU修订版 为 V 才能达到 480 MHz 的最大频率。 使用STM32Programmer查看芯片修订版,确认是V版本: 在STM32CubeMX PinConfiguration 界面修改RCC选项,将Product Version设置为V: 此时时钟树界面已可以设置48

    2024年02月16日
    浏览(46)
  • STM32H7 SDMMC+FATFS+USBMSC+FREERTOS 虚拟U盘

    通过cubemx配置 实现STM32H7 SDMMC+FATFS+USBMSC+FREERTOS 虚拟U盘 1.使用FAFTS文件操作系统,实现STM32虚拟U盘,读写外部SD卡,fatfs和usb mass storage class共存。 2.请先完成上一个帖子的步骤 -- 跳转https://blog.csdn.net/hjn0618/article/details/130383593 硬件平台:正点原子阿波罗 STM32H734IIT6 开发工具:

    2024年02月10日
    浏览(37)
  • STM32H7使用QSPI外扩flash(linux下使用openocd操作)

    根据安福莱的STM32H7教程,H7单片机的QSPI外设是直接连到芯片内核上的,地址是0X90000000;那么就可以通过QSPI外设,将外置flash内存映射,并由此执行代码。 相关操作在keil5上比较简单,配置点东西就行;可以参考安福莱教程。 这里要介绍的是在linux环境下没有keil5 IDE的情况下

    2024年01月16日
    浏览(51)
  • stm32 AD7606 芯片驱动 hal库 spi通讯

             这两天用来个ad7606 的芯片,结果硬件出来个问题,花了不少时间看这个芯片手册,干脆分享一下。         OS0 OS1 OS2         这个三个引脚用于配置芯片的采样频率,只要不设置为111即可正常采样; CONVSTA CONVSTB 这两个引脚用于启动芯片采集转换,默认高电平,

    2024年04月26日
    浏览(38)
  • AD7606与STM32F103ZET6的串行通信

      本文是AD7606与STM32的串行通信的学习心得,可帮助你快速入门AD7606。   图一   图二   图三   图四   根据图一,一些引脚在置高或置低时的上升或下降沿会受时间影响,因此在编写代码时,一些对引脚的操作需要放在一起,且延时函数不能随意使用。   图

    2024年02月08日
    浏览(65)
  • 【STM32H7 开发笔记】| 02 - 通过定时器级联方式同步启动多个定时器并输出 PWM 波形

    (STM32H723xE/G) 所有定时器包括 两个高级控制定时器、十二个通用定时器、两个基本定时器、五个低功耗定时器、两个看门狗定时器和一个SysTick定时器 。所有计时器计数器都可以在Debug模式下冻结。 本次实验主频配置的是500MHz 高级控制定时器(TIM1,TIM8)可以看作是在6通道

    2024年02月14日
    浏览(40)
  • cubmx基础操作,hal库基本配置流程之使用 stm32cubmx生成HAL库进行gpio点亮led(stm32h7xx)(超详细,小白教程)

    HAL库(硬件抽象层库)是一个提供对底层硬件操作的抽象的库,它使得开发者可以使用统一的接口进行硬件操作,而不必关心底层硬件的具体实现细节。HAL库通常由硬件厂商提供,用于支持其硬件设备,并为其提供标准化的接口。 HAL库的主要目的是简化底层硬件的操作,使得

    2024年02月20日
    浏览(54)
  • 【STM32L496】使用HAL库实现SPI写入/读取数据(AD5421)

    SPI协议详解(图文并茂+超详细) SPI超详细解析 【STM32笔记】HAL库中的SPI传输(可利用中断或DMA进行连续传输) AD5421是一款集成器件,设计用于环路供电型4-20mA智能发射器应用。AD5421在单芯片内提供如下特性和功能:16位DAC和电流放大器,用于对环路电流进行数字控制;用于

    2024年02月03日
    浏览(75)
  • STM32L431RCT6芯片型号标识信息以及片内Flash区和片内RAM区的大小、地址范围

    通过以ARM Cortex-M4为核心的STM32L4系列MCU,由该MCU的存储器映像、中断源与硬件最小系统构建出一种通用嵌入式计算机(AHL-STM32L431)。本博客主要介绍 STM32L4系列MCU的型号信息以及该芯片的Flash区和RAM区的存储器映像 STM32L4系列MCU是意法半导体(ST)公司于2016年开始陆续推出基于

    2024年04月26日
    浏览(35)
  • STM32G473VET6 FlashDB数据库移植(裸机、片内Flash)

    此文档也适用于STM32G070 此处使用FlashDB官方最新源码 FlashDB: 一款支持 KV 数据和时序数据的超轻量级数据库 (gitee.com) 克隆源码后目录如下 红框中几个为移植必要文件与参考 根据FlashDB官方文档可知,FlashDB底层依赖于RT-Thread的FAL组件,所以需要先移植FAL FlashDB源码中port目录下即

    2024年01月21日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包