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

2023-05-16

一、硬件

先了解一下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℃

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • jupyter_notebook_config.py的配置详解

    Configuration file for jupyter notebook Application SingletonConfigurable configuration This is an application The date
  • js Function 参数按值传递详解

    如果传入参数是基本数据类型 xff0c 那么按值传递是很容易理解的 xff1b 如果传入参数是引用数据类型 xff0c 那么会很容易陷入误区 xff0c 错误地认为是引用传递 xff1b 错误例子一 xff1a function setCo
  • 准确率、精准率、召回率和F1值详解

    专业术语的中英文对照表 英文名准确率Accuracy精准率Precise召回率RecallF1值F1 measure Precise和Recall是广泛应用在信息检索和统计学分类领域的两个度量值 xff0c 用来评价结果的质量 xff1b
  • snippet,让你编码效率翻倍

    为什么谈到Snippet 今天下午在用vscode做小程序的时候 xff0c 发现很不方便 xff0c 因为商店里提供的代码片段极为有限 xff0c 而且平时几乎每天都需要用到代码片段 xff0c 所以就在思考他们是怎么做到给别人提供代码的
  • 验证Promise是同步的

    前言 Promise是ES6提出的解决异步编程导致陷入回调的地狱问题 例子1 console log 1 var a 61 new Promise function resolve reject console log 2 resolve
  • Nextcloud下载文件出错、无法下载、网页卡死解决办法

    通常出现这种情况是因为用了一些Nextcloud不支持的下载工具 xff0c 通常需要去下载工具中设置 通过Nextcloud下载大文件的时候1G或更大时 xff0c Internet Download Manager会将系统卡住 xff0
  • 原生js实现JSONP

    介绍 JSONP是JSON with Padding 填充式JSON或参数式JSON 的简写 xff0c 是一种非常常用的跨域请求方式 主要原理是利用了script 标签可以跨域请求的特性 xff0c 由其 src属性发送请求到服务器 xf
  • ESP32设备驱动-SHT20温湿度传感器驱动

    SHT20温湿度传感器驱动 文章目录 SHT20温湿度传感器驱动 1 SHT20介绍 2 硬件准备 3 软件准备 4 驱动实现 1 SHT20介绍 Sensirion 的 SHT20 湿度和温度传感器已成为外形尺寸和智能方面的行业标准 嵌入
  • ESP32设备驱动-BME680环境传感器驱动

    BME680环境传感器驱动 文章目录 BME680环境传感器驱动 1 BME680介绍 2 硬件准备 3 软件准备 4 驱动实现 1 BME680介绍 BME680 是一款集成环境传感器 专为尺寸和低功耗是关键要求的移动应用和可穿戴设备而开
  • ESP32设备驱动-HDC2080温湿度传感器驱动

    HDC2080温湿度传感器驱动 文章目录 HDC2080温湿度传感器驱动 2 硬件准备 3 软件准备 4 驱动实现 HDC2080 器件是一款集成式湿度和温度传感器 可在小型 DFN 封装中以极低的功耗提供高精度测量 基于电容的传感器包括新
  • ESP32设备驱动-BMP388气压传感器驱动

    BMP388气压传感器驱动 文章目录 BMP388气压传感器驱动 1 BMP388介绍 2 硬件准备 3 软件准备 4 驱动实现 1 BMP388介绍 BMP388 是一款非常小巧 低功耗和低噪声的 24 位绝对气压传感器 它可以实现精确的
  • ESP32设备驱动-BMA400加速度传感器驱动

    BMA400加速度传感器驱动 文章目录 BMA400加速度传感器驱动 1 BMA400介绍 2 硬件准备 3 软件准备 4 驱动实现 1 BMA400介绍 BMA400 是第一款真正的超低功耗加速度传感器 不会影响性能 BMA400 具有
  • ESP32设备驱动-BH1745NUC 亮度和颜色传感器驱动

    BH1745NUC 亮度和颜色传感器驱动 文章目录 BH1745NUC 亮度和颜色传感器驱动 2 硬件准备 3 软件准备 4 驱动实现 BH1745NUC 是具有 I C 总线接口的数字颜色传感器 IC 该 IC 感应红光 绿光和蓝光 RG
  • ESP32设备驱动-LPS25H压阻式压力传感器驱动

    LPS25H压阻式压力传感器驱动 文章目录 LPS25H压阻式压力传感器驱动 1 LPS25H介绍 2 硬件准备 3 软件准备 4 驱动实现 1 LPS25H介绍 LPS25H 是一款超紧凑型绝对压阻式压力传感器 它包括一个单片传感元件和一
  • ESP32设备驱动-LPS25H压阻式压力传感器驱动

    1 LPS22HB介绍 文章目录 1 LPS22HB介绍 2 硬件准备 3 软件准备 4 驱动实现 LPS22HB 是一款超紧凑型压阻式绝对压力传感器 可用作数字输出气压计 该设备包括一个传感元件和一个 I2C 接口 该接口通过 I2C 或
  • ESP32设备驱动-LIS3MDL磁场传感器驱动

    LIS3MDL磁场传感器驱动 文章目录 LIS3MDL磁场传感器驱动 1 LIS3MDL介绍 2 硬件准备 3 软件准备 4 驱动实现 1 LIS3MDL介绍 LIS3MDL 具有 4 8 12 16 高斯的用户可选满量程 自检功能允许用户
  • Stm32L0 STM32CUBE中UART和使用LPUART1以及串口不进中断问题解决

    使用STM32CUBE配置串口USART2 USART2中断 使用STM32CUBE配置串口LPUART1 xff0c 这个串口要配置115200可能需要修改时钟 xff0c 太低的系统时钟可能无法达到这个速度 配置中断LPUART1 GP
  • ESP32设备驱动-BMM150数字地磁传感器驱动

    BMM150数字地磁传感器驱动 文章目录 BMM150数字地磁传感器驱动 1 BMM150介绍 2 硬件准备 3 软件准备 4 驱动实现 1 BMM150介绍 BMM150 是一款低功耗 低噪声的 3 轴数字地磁传感器 用于罗盘应用 具有
  • ESP32设备驱动-VEML7700光照度传感器驱动

    VEML7700光照度传感器驱动 1 VEML7700介绍 文章目录 VEML7700光照度传感器驱动 1 VEML7700介绍 2 硬件准备 3 软件准备 4 驱动实现 VEML7700 是一款高精度环境光数字 16 位分辨率传感器 它包
  • ESP32设备驱动-TSL2591数光转换器驱动

    TSL2591数光转换器驱动 文章目录 TSL2591数光转换器驱动 1 TSL2591介绍 2 硬件准备 3 软件准备 4 驱动实现 1 TSL2591介绍 TSL2591 是一款非常高灵敏度的光数字转换器 可将光强度转换为能够直接 I2

随机推荐

  • 数字图像处理与Python实现-图像滤波-Frangi滤波器

    Frangi滤波器 文章目录 Frangi滤波器 1 Frangi滤波器及其数学描述 2 代码实现 1 Frangi滤波器及其数学描述 Frangi滤波器是Koen L Vinc Alejandro F Frangi Wiro J Nies
  • OpenCV4.x图像处理实例-搭建身份识别系统

    搭建身份识别系统 文章目录 搭建身份识别系统 1 人脸识别系统介绍 2 人脸特征数据提取 3 人脸识别模型训练 4 从静态图像进行身份识别 5 从视频流识别身份 在本文中 将介绍如何使用 OpenCV 搭建一个人脸检测与身份识别系统 为了构
  • ESP32-设备驱动TMP102数字温度传感器驱动

    TMP102数字温度传感器驱动 文章目录 TMP102数字温度传感器驱动 1 TMP102介绍 2 硬件准备 3 软件准备 4 驱动实现 1 TMP102介绍 TMP102 器件是一款数字温度传感器 非常适合需要高精度的 NTC PTC 热
  • ESP32设备驱动-Si1145红外接近-紫外 (UV) 指数和环境光传感器驱动

    Si1145红外接近 紫外 UV 指数和环境光传感器驱动 文章目录 Si1145红外接近 紫外 UV 指数和环境光传感器驱动 1 Si1145介绍 2 硬件准备 3 软件准备 4 驱动实现 1 Si1145介绍 Si1145 46 47 是
  • ESP32设备驱动-PCF8575IO扩展器驱动

    PCF8575IO扩展器驱动 文章目录 PCF8575IO扩展器驱动 1 PCF8575介绍 2 硬件准备 3 软件准备 4 驱动实现 1 PCF8575介绍 PCF8575用于两线双向总线 I2C 的 16 位 I O 扩展器专为 2 5
  • ESP32设备驱动-Si4703调频收音机模块驱动

    Si4703调频收音机模块驱动 文章目录 Si4703调频收音机模块驱动 1 Si4703介绍 2 硬件准备 3 软件准备 4 驱动实现 1 Si4703介绍 Si4702 03 FM 无线电接收器系列通过小尺寸和电路板面积 最少的组件数量
  • ESP32设备驱动-PCA9685 LED控制器驱动

    PCA9685 LED控制器驱动 文章目录 PCA9685 LED控制器驱动 1 PCA9685介绍 2 硬件准备 3 软件准备 4 驱动实现 1 PCA9685介绍 PCA9685 是一款 I C 总线控制的 16 通道 LED 控制器
  • 飞桨EasyDL闪退解决方法

    当点击训练时 xff0c 软件消失 xff0c 用cmd运行软件查看输出信息未见异常 解决办法 xff0c 换一台电脑安装 xff0c 很大概率就好了
  • WM_QUIT,WM_CLOSE区别[转]

    总结 我们要使用代码关闭程序的话 应该向窗口发送WM CLOSE或者直接调DestroyWindow HWND 函数 默认情况下WM CLOSE的消息响应就是调用DestroyWindow HWND 函数 所以我们直接调用也达到一样的效果
  • ESP32设备驱动-LIS3DSH加速度传感器驱动

    LIS3DSH加速度传感器驱动 文章目录 LIS3DSH加速度传感器驱动 1 LIS3DH介绍 2 硬件准备 3 软件准备 4 驱动实现 1 LIS3DH介绍 LIS3DSH 是一款超低功耗高性能三轴线性加速度计 属于 纳米 系列 具有嵌入
  • 66老师推荐书单

    应用词汇 四级 星火英语 新要求大学英语词汇星火式巧记速记 精华本 附MP3 光盘1 张 http product dangdang com 23315816 html 词典 柯林斯COBUILD 高阶英语学习词典 英语版 http pro
  • NetAssist 网络助手

    电脑上的网络助手找不到了 xff0c 百度搜各种不能用的和下载要积分啊什么的 xff0c 真是现在鸟大了什么林子都有 xff0c 人家开发者都还免费提供软件的使用 xff0c 你一个使用者居然还拿别人的东西赚积分 xff0c 真TM恶心 x
  • 64位的linux装的hadoop是32位的,需要手工编译

    64位的linux装的hadoop是32位的 coco by coco 2014 07 02 64位的linux装的hadoop是32位的 xff0c 需要手工编译 遇到的问题描述 xff1a root 64 db96 hadoop had
  • Unable to preventDefault inside passive event listener due to target being treated as passive.

    最近做项目经常在 chrome 的控制台看到如下提示 xff1a Unable to preventDefault inside passive event listener due to target being treated span
  • GBK 编码

    GBK编码范围 xff1a 8140 xff0d FEFE xff0c 汉字编码范围见第二节 xff1a 码位分配及顺序 GBK编码 xff0c 是对GB2312编码的扩展 xff0c 因此完全兼容GB2312 80标准 GBK编码依然采用
  • 子类能否重写父类的静态方法?

    今天在看到了一道面试题 xff0c 题目是一道代码阅读题 xff0c 问下面的代码输出结果是什么 xff1f 我最开始的理解 xff1a 上面的代码我们可以看到 xff0c 上面的类中有两个内部类Sub和Super xff0c Sub继承了
  • docker build命令详解

    docker build命令用于根据给定的Dockerfile和上下文以构建Docker镜像 docker build命令的使用格式 xff1a docker build span class token punctuation span
  • Blazor 从入门到放弃

    Blazor 从入门到放弃 Intro Blazor 是微软在 NET 里推出的一个 WEB 客户端 UI 交互的框架 xff0c 使用 Blazor 你可以代替 JavaScript 来实现自己的页面交互逻辑 xff0c 可以很大程度上进
  • WPF知识学习

    RelativeSource 61 RelativeSource AncestorType 61 x Type Window 是一种 WPF XAML 绑定方式 xff0c 它表示要从当前控件的父级元素中找到类型为 Window 的元素 x
  • STM32H7并行读取AD7606数据以及片内AD值不准解决办法

    一 硬件 先了解一下AD7606 xff0c 16位 xff0c 单电源 xff0c 200k采样率 xff0c 8路 xff0c 除了贵没有其他缺点 xff0c 数据相当的稳 xff0c 一个5V供电 xff0c 不用运放的情况下采集电压