stm32cubemx配置stm32H743IIT6初始化,阻塞采集单通道和多通道ADC值,亲测有效!

之前写到stm32cubemx配置采集stm32F4,本次分享如何通过配置stm32cubemx采集stm32H743IIT6。

本篇文章分享通过阻塞实现单通道和多通道的ADC的采集。

stm32cubemx的版本6.10.0。

一、阻塞采集单通道ADC数据

阻塞采集是每次采集adc数据,cpu死等,直到采集完或者在设定时间超时没能采集,返回到cpu。

配置sm32cubemx:

1、配置时钟源

使用的是25M无源晶振。

这里power regulator voltage scale 选择"Power Regulator Voltage Scale 0",系统时钟能达到480MHz。查看数据手册

2、时基选择系统滴答定时器

3、配置时钟

配置时钟为480MHz,系统自动生成时钟树。

ADC的时钟是50MHz。

4、配置ADC

5、配置串口

6、调试模式

配置成SW模式

7、项目管理

配置完成后,生成初始化代码。

代码部分

(1)添加头文件

复制代码
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "stdio.h" //添加头文件
/* USER CODE END Includes */

(2)添加打印函数

复制代码
/* USER CODE BEGIN 0 */

int fputc(int c, FILE *stream)    //重写fputc函数
{
 /*
    huart1是工具生成代码定义的UART1结构体,
    如果以后要使用其他串口打印,只需要把这个结构体改成其他UART结构体。
*/
    HAL_UART_Transmit(&huart1, (unsigned char *)&c, 1, 1000);   
    return 1;
}

/* USER CODE END 0 */

(3)添加变量

复制代码
int main(void)
{
  /* USER CODE BEGIN 1 */

  uint32_t ADC_value;//adc读到的数据
	uint8_t i;
	float ADCx;//转换后的电压值
  /* USER CODE END 1 */

(4)添加提示

复制代码
 /* USER CODE BEGIN 2 */
  printf("<<<<<<<ADC 非DMA单通道采集\r\n "); 
	 HAL_Delay(2000);
  /* USER CODE END 2 */

(5)while添加采集

复制代码
 while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
		printf("\r\n *****ADC 输出 *****\r\n");  //我这里设置间断数为1,也就是将1个通道分成了1组,那么我每次采集的时候都需要手动去触发ADC采集,也就是调用一次HAL_ADC_Start函数
   ADC_value=0;//采集的电压值清零
		for(i=0;i<50;i++)//循环采集50次
		{
			HAL_ADC_Start(&hadc1);//启动ADC转换,必须放在for循环中,否则只能采集第一个通道的ADC值;
			HAL_ADC_PollForConversion(&hadc1,100); //用于轮询转换,是一个阻塞函数,等待转换完成,参数100ms是阻塞时间
			if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)) //判断转换完成标志位是否设置,为1的时候产生中断。
				ADC_value+=HAL_ADC_GetValue(&hadc1); //读到的ADC的值,累加
			}
		ADC_value=ADC_value/50;//求平均值
			ADCx =ADC_value *3.3/65536;//转换成电压值
	printf("AD value =%d 电压= %.2fV",ADC_value,ADCx);//打印输出
	 HAL_Delay(1000);

  }

(6)添加adc校准函数

**这里很关键!**stm32cubemx初始化不包含校准函数,需要自己手动添加。

在adc.c的初始化函数void MX_ADC1_Init(void)内添加

复制代码
  /* USER CODE BEGIN ADC1_Init 2 */
  HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED); /* ADC校准 */
  /* USER CODE END ADC1_Init 2 */

(7)编译

stm32H7系列编译起来时间超级长

花了十分钟多。有两个解决办法:

①、不勾选"Browse information"

②编译器选择"version 6"

两个方法都能编译速度极大的提升!

运行

如果不进行校准。

对接地采集电压,

上面添加校准函数,

下面去掉校准函数。

这里就体现出校准函数的重要性!

二、阻塞采集多通道ADC数据

和阻塞采集单通道ADC数据一样的配置就不贴图了。

(1)ADC配置

配置完成后,生成初始化代码。

代码部分

(1)添加头文件

复制代码
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "stdio.h" //添加头文件
/* USER CODE END Includes */

(2)添加打印函数

复制代码
/* USER CODE BEGIN 0 */

int fputc(int c, FILE *stream)    //重写fputc函数
{
 /*
    huart1是工具生成代码定义的UART1结构体,
    如果以后要使用其他串口打印,只需要把这个结构体改成其他UART结构体。
*/
    HAL_UART_Transmit(&huart1, (unsigned char *)&c, 1, 1000);   
    return 1;
}

/* USER CODE END 0 */

(3)添加变量

复制代码
int main(void)
{
   /* USER CODE BEGIN 1 */

	 uint32_t ADC_value[100];//存放采集到数据
	uint32_t temp1,temp2;//存放累加值,这里要选择32位,因为adc采集的位数是16位
	uint16_t ADC_value1,ADC_value2;//adc采集的值
	
	uint8_t i;
	float ADCx1,ADCx2;//转换后的电压值
	
  /* USER CODE END 1 */

(4)添加提示

复制代码
 /* USER CODE BEGIN 2 */
  printf("<<<<<<<ADC 非DMA多通道采集\r\n "); 
	 HAL_Delay(2000);
  /* USER CODE END 2 */

(5)while添加采集

复制代码
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

			temp1=0;		//清零
			temp2=0;   //清零
			printf("\r\n *****ADC 输出 *****\r\n");  //我这里设置间断数为1,也就是将2个通道分成了2组,那么我每次采集的时候都需要手动去触发ADC采集,也就是调用一次HAL_ADC_Start函数
			for(i=0;i<100;i++)
			{
			HAL_ADC_Start(&hadc1);//启动ADC转换,必须放在for循环中,否则只能采集第一个通道的ADC值;
			HAL_ADC_PollForConversion(&hadc1,100); //用于轮询转换,是一个阻塞函数,等待转换完成,参数100ms是阻塞时间
			if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)) //判断转换完成标志位是否设置,为1的时候产生中断。
				ADC_value[i]=HAL_ADC_GetValue(&hadc1); //开始读ADC的值
			}
			for(i=0;i<50;i++)
			{
			temp1=temp1+ADC_value[2*i];//50次采集求和
			temp2=temp2+ADC_value[2*i+1];//50次采集求和
			}
							
			ADC_value1=temp1/50; //平均值
			ADC_value2=temp2/50;  //平均值
			ADCx1 =ADC_value1 *3.3/65536;   //转化成电压值
			ADCx2 =ADC_value2 *3.3/65536;       //转化成电压值
			printf("AD1 value =%d 电压= %.2fV ",ADC_value1,ADCx1);//打印输出
			printf("AD2 value =%d 电压= %.2fV ",ADC_value2,ADCx2);//打印输出

			HAL_Delay(1000);

		
		
  }

(6)添加adc校准函数

**这里很关键!**stm32cubemx初始化不包含校准函数,需要自己手动添加。

在adc.c的初始化函数void MX_ADC1_Init(void)内添加

复制代码
  /* USER CODE BEGIN ADC1_Init 2 */
  HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED); /* ADC校准 */
  /* USER CODE END ADC1_Init 2 */

运行

相关推荐
ACP广源盛1392462567320 小时前
IX8024@ACP# 搭配此芯 AI 服务器 + 爱芯元智产品完整方案
大数据·运维·服务器·人工智能·分布式·嵌入式硬件
ShallWeL21 小时前
NVIDIA Jetson 早期系列演进
人工智能·嵌入式硬件·边缘计算·智能硬件
2501_914245931 天前
C语言与硬件交互:从GPIO到中断的嵌入式编程实践
c语言·单片机·交互
2401_854151551 天前
嵌入式 Bootloader 与 OTA 固件升级深度解析——从 Flash 分区到安全回滚
开发语言·stm32·单片机·嵌入式硬件·安全·php
炸膛坦客1 天前
单片机/C/C++八股:(二十四)编译文件( .bin 和 .hex ,包括 .elf 和 .axf )
c语言·c++·单片机
Yunhoa1 天前
51单片机(DS18B20 数字温度传感器)
单片机·嵌入式硬件·51单片机
zlinear数据采集卡1 天前
2mV纹波的代价:硬核拆解ZLinear模拟前端放大器与正负可调电源设计
arm开发·单片机·嵌入式硬件·fpga开发·架构·开源
Wallystech-Linda1 天前
Exploring WiFi 7 Module Designs for Next-Generation Wireless Applications
嵌入式硬件
不上岸的旱鸭子1 天前
PCB设计
单片机·pcb工艺
吠品1 天前
多语言支持,从后台到前端我都趟过哪些坑
stm32·单片机·嵌入式硬件