STM32F407 HAL库单通道ADC采集并串口打印电压值

本文将介绍如何使用STM32F407的HAL库实现单通道ADC采集,并通过串口将采集到的电压值打印出来。具体地,我们将使用ADC1读取通道5(对应引脚PA5),并将转换后的电压值用串口1发送到串口助手上进行显示。

 一、开发环境

硬件:正点原子探索者 V3 STM32F407开发板

单片机:STM32F407ZGT6

Keil版本:5.32

STM32CubeMX版本:6.9.2

STM32Cube MCU Packges版本:STM32F4 V1.27.1

  二、配置STM32CubeMX

  1. 启动STM32CubeMX,新建STM32CubeMX项目
  2. 选择MCU:在软件中选择你的STM32型号-STM32F407ZGT6。
  3. 选择时钟源:

  4. 配置时钟:
  5. 使能Debug功能:Serial Wire
  6. HAL库时基选择:SysTick
  7. USART1配置:选择异步模式。
  8. 开启外部时钟:配置系统时钟,确保ADC和串口的外部时钟已开启。

  9. 配置ADC

1)选择ADC1作为采集模块。

2)设置ADC1的通道5(对应引脚PA5)为采集通道。

3)配置采样时间和分辨率。通常,采样时间越长,ADC的转换精度越高,但也会增加转换时间。

4)启用连续转换模式,以便ADC能够持续采集数据。

5)禁用扫描模式,因为我们只采集一个通道。

10.配置工程参数:在Project标签页中,配置项目名称和位置,选择工具链MDK-ARM。​ 11.生成代码:在Code Generator标签页中,配置工程外设文件与HAL库,勾选头文件.c和.h文件分开,然后点击Project > Generate Code生成代码。 

三、代码实现与部署

  1.  main.c增加代码:main.c的第1行添加printf的头文件#include<stdio.h>,在 while(1)里增加数行代码。​​​​​ADC电压换算时用到公式:待测电压=(ADC的返回值/4096​)∗3.3V​.

    /* USER CODE BEGIN Header */
    #include<stdio.h>
    /**
      ******************************************************************************
      * @file           : main.c
      * @brief          : Main program body
      ******************************************************************************
      * @attention
      *
      * Copyright (c) 2024 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 */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    		
    		HAL_ADC_Start(&hadc1); // 启动ADC采集  
      
            // 轮询ADC转换状态  
            if (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK)  
            {  
                adc_value = HAL_ADC_GetValue(&hadc1); // 获取转换后的数字值  
      
                // 将数字值转换为电压值并格式化为字符串  
                sprintf(buffer, "Voltage: %.3fV\r\n", (adc_value / 4096.0) * 3.3);  
      
                // 发送电压值到串口  
                printf("%s",buffer);  
            }  
      
            HAL_Delay(500); // 添加延时  
        }  
      
      /* USER CODE END 3 */
  2.  usart.c增加代码:usart.c的第1行添加头文件#include <stdio.h>
    #include <string.h>,在末尾用户代码区增加如下代码。printf调用“fputc()”,fgetc(),该函数会使用HAL_UART_Transmit发送数据。
    /*
    * 添加如下代码,可不在工程设置中勾选Use MicroLIB
    */
    #pragma import(__use_no_semihosting)
    
    struct __FILE
    {
    	int a;
    };
    
    FILE __stdout;
    FILE __stdin;
    
    void _sys_exit(int x)
    {
    }
    
    
    /*****************************************************
    *function: 写字符文件函数
    *param1: 输出的字符
    *param2: 文件指针
    *return: 输出字符的ASCII码
    ******************************************************/
    int fputc(int ch, FILE *f)
    {
    	HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 10);
    	return ch;
    }
    /*****************************************************
    *function: 读字符文件函数
    *param1: 文件指针
    *return: 读取字符的ASCII码
    ******************************************************/
    int fgetc(FILE *f)
    {
    	uint8_t ch = 0;
    	HAL_UART_Receive(&huart1, (uint8_t*)&ch, 1, 10);
    	return (int)ch;
    }
  3. 连接USART1:用USB转TTL工具连接当前硬件USART1的PA9、PA10,GND。​​
  4. 打开串口助手:​​
  5. 编译代码:Keil编译生成的代码。
  6. 烧录程序:将编译好的程序用ST-LINK烧录到STM32微控制器中。

四、运行结果

观察结果:一旦程序烧录完成并运行,串口助手打印出PA5的电压,当接地的时候得出的电压值是0,当输入正弦波得到如下结果。

voltage	0.956
Voltage	0.16
Voltage	0.175
Voltage	0.997
Voltage	2.22
Voltage	3.19
Voltage	3.299
Voltage	2.829
Voltage	1.695
Voltage	0.582
Voltage	0.076
Voltage	0.419
Voltage	1.482
Voltage	2.681
Voltage	3.299
Voltage	3.273
Voltage	2.402
Voltage	1.191
Voltage	0.272
Voltage	0.118
Voltage	0.827
Voltage	2.017
Voltage	3.082
Voltage	3.299
Voltage	2.989
Voltage	1.88
Voltage	0.702
Voltage	0.085
Voltage	0.325
Voltage	1.304
Voltage	2.516
Voltage	3.299
Voltage	3.299
Voltage	2.52
Voltage	1.304
Voltage	0.338
Voltage	0.083
Voltage	0.706
Voltage	1.859
Voltage	2.977
Voltage	3.299
Voltage	3.057
Voltage	1.994
Voltage	0.808
Voltage	0.109
Voltage	0.265
Voltage	1.196

​导入excel看波形

​五、注意事项

1.确保你的开发环境和工具已经正确安装和配置。

2.如果没有打印电压值,按一下复位键,检查连接和电源是否正确,注意根据你所用的硬件来接线,不要接错线了。

STM32HAL库提供了对内置ADC模块的支持,可以使用HAL库中的函数来配置和使用ADC模块。对于温度传感器通道的读取,可以使用内置的温度传感器通道,该通道在STM32芯片中被映射到了ADC通道16。以下是使用HAL库进行ADC温度通道读取的基本步骤: 1. 配置ADC模块,并使能ADC时钟。 2. 配置ADC通道和采样时间。 3. 配置ADC模式为单次转换模式。 4. 配置ADC转换触发源为软件触发。 5. 配置ADC通道为温度传感器通道。 6. 启动ADC转换,等待转换完成。 7. 读取ADC转换结果,并进行温度计算。 以下是一个使用HAL库进行ADC温度通道读取的示例代码: ```c #include "stm32f4xx_hal.h" ADC_HandleTypeDef hadc1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); uint16_t adc_value; float temperature; while (1) { // Start ADC conversion HAL_ADC_Start(&hadc1); // Wait for conversion to complete HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); // Read ADC value adc_value = HAL_ADC_GetValue(&hadc1); // Calculate temperature temperature = (float)((adc_value * 3.3) / 4096 - 0.76) / 0.0025 + 25; // Print temperature printf("Temperature: %f\n", temperature); HAL_Delay(1000); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 16; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); } void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig; __HAL_RCC_ADC1_CLK_ENABLE(); hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.NbrOfDiscConversion = 0; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.EOCSelection = DISABLE; HAL_ADC_Init(&hadc1); sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; HAL_ADC_ConfigChannel(&hadc1, &sConfig); } void MX_GPIO_Init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } ``` 在上述示例代码中,我们使用了ADC模块的HAL库函数来配置ADC通道和采样时间,使用了温度传感器通道读取温度,并进行了温度计算。最后,我们将温度打印串口终端上,以便进行调试和观察。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值