HAL STM32F4内部温度读取+ADC阻塞式读取

HAL STM32F4内部温度读取+ADC阻塞式读取


  • 🔖对于大多数stm32型号,基本上内部都集成了温度传感器。

⛳不同型号的STM32单片机,计算温度的公式差异

  • 🌿对于STM32F1系列:(计算公式在参考手册上)
    在这里插入图片描述
    在这里插入图片描述

  • 🌿STM32F4系列:
    在这里插入图片描述
    在这里插入图片描述

📗ADC转换方式说明

-🌿普通方式开启:HAL_ADC_Start (ADC_HandleTypeDef *hadc)

  • 🔖通过查询EOC状态寄存器,来判断是否转换完成,HAL_IS_BIT_CLR(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)
  • 🌿中断方式:HAL_ADC_Start_IT (ADC_HandleTypeDef *hadc)
  • 🔖通过对于转换完成回调函数,通知转换完成,HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
  • 🌿DMA方式:HAL_ADC_Start_DMA (ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length)
  • 🔖在DMA开启循环模式情况下,可以直接读取对应的变量存储值。
  • 🎉从上面罗列的开启方式来看,最节省cpu负担的方式,属于DMA+中断组合方式。DMA方式开启后,就无须cpu干预,等到转换完成时,通过中断响应。

🛠STM32CubeMX配置

  • 🌿配置通道0:
    在这里插入图片描述
  • 🌿勾选内部温度通道以及参数配置
    在这里插入图片描述

🛠业务代码

  • 🌿adc读取函数
uint16_t Read_Adc() {
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 100);
	while(!HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC));
//    while (HAL_IS_BIT_CLR(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) {}
    return HAL_ADC_GetValue(&hadc1);
}
  • 🌿main函数
int main(void)
{

  /* USER CODE BEGIN 1 */
 uint16_t Adcbuf[2] = {0,0};
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		for (uint8_t i = 0; i < 2; i++)
            Adcbuf[i] = Read_Adc();
		float Voltage = (Adcbuf[0]/ 4095.f)* 3.3f;
			float	Temperature = ( Adcbuf[1]*3.3/4095 - 0.76)/0.0025 + 25 ;//计算方法
        printf("CH0 Voltage = %.2f,Temp Sensor= %.2f\r\n", \
                Voltage, Temperature);
        HAL_Delay(500);
		HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
  }
  /* USER CODE END 3 */
}
  • 🌿串口输出相关函数
#include "stdio.h"//勾选MicroLib
/*可调用printf*/
int fputc(int ch, FILE *f)
{
    /*&huart1指的是串口1,如果用别的串口就修改数字*/
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
    return ch;
}
  • 📜测试打印信息:
    在这里插入图片描述

📚测试工程

  • 🌿内部温度读取+ADC阻塞式读取
链接:https://pan.baidu.com/s/16J-BQyDwcB8klYTaKL8gxA?pwd=bu2y 
提取码:bu2y
  • 🌿单通道DMA+IT模式读取
链接:https://pan.baidu.com/s/1rI1DcfQrlOEsOlFuIidiOQ?pwd=3v0a 
提取码:3v0a
### STM32F4 ADC 信号采集教程 #### 配置环境与初始化 为了在STM32F4上成功执行ADC信号采集,首先要确保开发环境已正确安装并配置好必要的库文件。通常情况下,推荐使用官方提供的HAL库简化外设操作。 ```c #include "stm32f4xx_hal.h" // 定义全局变量用于存储ADC句柄 extern ADC_HandleTypeDef hadc1; ``` #### 初始化ADC模块 接下来是对ADC硬件资源的具体配置,这一步骤决定了后续采样的精度与时序特性: ```c static void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 设置时钟分频因子 hadc1.Init.Resolution = ADC_RESOLUTION_12B; // 设定分辨率为12位 hadc1.Init.ScanConvMode = DISABLE; // 单次转换模式 hadc1.Init.ContinuousConvMode = ENABLE; // 连续转换模式开启 hadc1.Init.DiscontinuousConvMode = DISABLE; // 关闭不连续转换模式 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 软件触发启动 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐 hadc1.Init.NbrOfConversion = 1; // 只有一个通道参与转换 if (HAL_ADC_Init(&hadc1) != HAL_OK){ Error_Handler(); } /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_0; // 使用第0号模拟输入端口作为测量源 sConfig.Rank = 1; // 排列顺序为第一个位置 sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; // 指定采样时间为三个周期 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){ Error_Handler(); } } ``` 上述代码片段展示了如何针对特定应用需求调整ADC的工作参数[^1]。 #### 启动ADC转换 一旦完成了初始化阶段,则可以调用`HAL_ADC_Start()`函数来激活ADC设备,并通过轮询方法读取最新一次的转换结果;或者利用中断机制,在每次新的样本可用时获得通知。 ```c uint32_t adcValue; if(HAL_ADC_Start(&hadc1)!= HAL_OK){ // 开始ADC转换 Error_Handler(); // 如果失败则进入错误处理程序 } while(1){ if(HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY)== HAL_OK){ adcValue= HAL_ADC_GetValue(&hadc1); // 获取当前ADC值 printf("ADC Value:%lu\n",adcValue); }else { Error_Handler(); } } ``` 这段示例说明了基本的阻塞式循环查询方式获取ADC数值的方法[^5]。 #### 利用DMA提高效率 当面对更高频率或更大量级的数据流时,单纯依靠CPU去频繁地请求状态更新显然不够高效。此时引入DMA技术便显得尤为重要——它允许外围设备之间直接交换信息而无需占用过多处理器资源。 ```c __IO uint16_t aADCxConvertedData[BUFFER_SIZE]; // DMA缓冲区定义 MX_DMA_Init(); /* Start ADC with DMA transfer */ if (HAL_ADC_Start_DMA(&hadc1,(uint32_t*)aADCxConvertedData,BUFFER_SIZE) != HAL_OK){ /* Start Error */ Error_Handler(); } ``` 这里给出了一个简单例子展示怎样借助DMA控制器实现批量化的数据搬运任务[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值