STM32的ADC资源概述
STM32F103ZE芯片(144脚)中有ADC1 、ADC2 、ADC3 共3个12位逐次逼近型 模数转换器,具有18个测量通道,可测量16个外部 和2个内部 信号源(内部温度和内部参考电压)。这2个内部信号源只能连接到ADC1 。 ADC的各个通道的A/D转换可以单次 、连续 、扫描 或间断 模式执行。 A/D转换结果以左对齐 或右对齐 的方式,存储在16位 规则组或者注入组数据寄存器中。
按照A/D转换的组织形式来划分,ADC的模拟输入通道分为规则组和注入组两种。 ADC可以对一组最多16个通道按照指定的顺序逐个进行转换,这组指定的通道称为规则组 。 在实际应用中,可能需要中断规则组的转换,临时对某些通道进行转换,好像这些通道注入了原来的规则组,故称注入组 ,最多由4个通道组成。
ADC启动与停止相关的HAL库函数 1 2 3 4 5 6 7 8 HAL_StatusTypeDef HAL_ADC_Start (ADC_HandleTypeDef* hadc) ;HAL_StatusTypeDef HAL_ADC_Stop (ADC_HandleTypeDef* hadc) ;HAL_StatusTypeDef HAL_ADC_Start_IT (ADC_HandleTypeDef* hadc) ;HAL_StatusTypeDef HAL_ADC_Stop_IT (ADC_HandleTypeDef* hadc) ;
ADC转换结果读取的HAL库函数 1 2 3 4 uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);参数1 :hadc,ADC实例指针。 返回值:uint32_t ,ADC转换结果。
查询方式,阻塞式A/D转换HAL库函数 1 2 3 4 5 HAL_StatusTypeDef HAL_ADC_PollForConversion (ADC_HandleTypeDef* hadc, uint32_t Timeout) ;参数1 :hadc,ADC实例指针。 参数2 :Timeout,超时时间。 返回值:HAL_StatusTypeDef,函数执行状态。
1 2 3 4 5 6 7 8 9 应用实例:用查询的方式,进行一次A/D采样并将结果读出。 uint16_t ADC_Value = 0 ;HAL_ADC_Start(&hadc); if (HAL_OK == HAL_ADC_PollForConversion(&hadc1,10 )){ ADC0_Value = HAL_ADC_GetValue(&hadc1); }
中断方式,非阻塞式A/D转换HAL库函数 1 2 3 4 5 6 7 8 9 应用实例:用中断的方式,进行一次A/D采样并将结果读出。 uint16_t ADC_Value = 0 ;HAL_ADC_Start_IT(&hadc); void HAL_ADC_ConvCpltCallback (ADC_HandleTypeDef* hadc) { ADC0_Value = HAL_ADC_GetValue(&hadc1); }
实训案例:ADC单次数据采样与电压换算 在XMF07A 或XMF07C 开发板上,利用STM32CubeMX 和Keil5 协同开发,完成以下的功能: 【1】将ADC_IN0 设置为12位 ADC,右对齐 ,启用中断。 【2】分别用查询 和中断 这2种方式,每隔0.5秒 采样一次ADC的数据。 【3】将每次读取到的ADC采样值 转换为对应电压值 ,发送到上位机。 【4】LED1 作为采样指示灯,在ADC转换过程中点亮,其余时间熄灭。
1 2 3 4 5 6 7 #include "stdio.h" #define LED1_ON() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET) #define LED1_OFF() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET) uint16_t ADC0_Value = 0 , ADC0_Volt = 0 ;uint8_t str_buff[64 ];
1 2 3 4 5 void UR1_Send_Info () { sprintf ((char *)str_buff,"采样值:%d,电压值:%d.%d%dV\r\n" ,ADC0_Value,ADC0_Volt/100 ,(ADC0_Volt%100 )/10 ,ADC0_Volt%10 ); HAL_UART_Transmit(&huart1,str_buff,sizeof (str_buff),10000 ); }
用查询,阻塞的方式来实现
1 2 3 4 5 6 7 8 9 10 11 12 13 void Get_ADC_Value () { HAL_ADC_Start(&hadc1); LED1_ON(); if (HAL_OK == HAL_ADC_PollForConversion(&hadc1,10 )) { ADC0_Value = HAL_ADC_GetValue(&hadc1); DC0_Volt = ADC0_Value * 330 / 4096 ; } UR1_Send_Info(); LED1_OFF(); HAL_ADC_Stop(&hadc1); }
1 2 3 4 5 6 7 8 9 10 11 12 while (1 ){ Get_ADC_Value(); UR1_Send_Info(); HAL_Delay(500 ); }
用中断,非阻塞的方式来实现
1 2 3 4 5 6 7 8 9 10 void HAL_ADC_ConvCpltCallback (ADC_HandleTypeDef* hadc) { if (hadc->Instance == ADC1) { ADC0_Value = HAL_ADC_GetValue(&hadc1); ADC0_Volt = ADC0_Value * 330 / 4096 ; UR1_Send_Info(); LED1_OFF(); } }
1 2 3 4 5 6 7 8 9 10 11 12 while (1 ){ HAL_ADC_Start_IT(&hadc1); LED1_ON(); HAL_Delay(500 ); }