A/D转换器的几个技术指标:
量程:指ADC所能输入模拟信号的类型和电压范围,即参考电压。信号类型包括单极性和双极性。
转换位数:量化过程中的量化位数n。
A/D转换后的输出结果用n位二进制数来表示。例:10位ADC的输出值就是0~1023。
分辨率:ADC能够分辨的模拟信号最小变化量。公式:分辨率=量程/2n
例:量程为单极性0-5V,8位ADC的分辨率是:
5/256= 0.0195V
转换时间:ADC完成一次完整的A/D转换所需要的时间,包括采样、保持、量化、编码的全过程。
A/D转换结果有2种存储方式:左对齐、右对齐,一般采用右对齐。
题目描述:
(1)将ADC_INO设置为12位ADC,右对齐,启用中断。
(2)分别用查询和中断这2种方式,每隔0.5秒采样一次ADC的数据。 (3)将每次读取到的ADC采样值转换为对应电压值,发送到上位机。LED1作为采样指示灯,在ADC转换过程中点亮,其余时间熄灭。
查询方式(阻塞式):
#include "main.h"
#include "adc.h"
#include "gpio.h"
#include "stdio.h"
#define LED1_ON() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_SET);
#define LED1_OFF() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_RESET);
/* USER CODE BEGIN PD */
uint16_t ADC_Value = 0, ADC_Volt=0;
uint8_t str_buff[64];
/* USER CODE END PD */
void UR1_Send_Info()
{
sprintf((char *)str_buff,"采样值:%d,电压值:%d.%d%dv\r\n",ADC_Value,ADC_Volt/100,ADC_Volt%100/10,ADC_Volt%10);//数据格式化
HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000);//send
}
void ADC_Get_Value()
{
HAL_ADC_Start(&hadc1);//开启间断模式,每次需要先使用HAL_ADC_Start()开启转换
LED1_ON();
if(HAL_ADC_PollForConversion(&hadc1,10)== HAL_OK)//明转换完成
{
ADC_Value=HAL_ADC_GetValue(&hadc1);//读取ADC原始值
ADC_Volt=ADC_Value *330/4096;//3.3v/2^12
}
UR1_Send_Info();
LED1_OFF();
HAL_ADC_Stop(&hadc1);停止转换
}
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
ADC_Get_Value();
HAL_Delay(500);//每隔0.5S读取一次数据
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
中断方式(非阻塞式):
#include "main.h"
#include "adc.h"
#include "gpio.h"
#include "stdio.h"
#define LED1_ON() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_SET);
#define LED1_OFF() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_RESET);
/* USER CODE BEGIN PD */
uint16_t ADC_Value = 0, ADC_Volt=0;
uint8_t str_buff[64];
/* USER CODE END PD */
void UR1_Send_Info()//串口发送数据
{
sprintf((char *)str_buff,"采样值:%d,电压值:%d.%d%dv\r\n",ADC_Value,ADC_Volt/100,ADC_Volt%100/10,ADC_Volt%10);//数据格式化
HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000);//send
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1)
{
ADC_Value=HAL_ADC_GetValue(&hadc1);
ADC_Volt=ADC_Value *330/4096;
UR1_Send_Info();
LED1_ON();
}
}
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
LED1_OFF();
HAL_ADC_Start_IT(&hadc1);
HAL_Delay(500);//每隔0.5S
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
注:stm32f103系列是12bit ADC,所以转换完是12位的无符号整型,C语言中没有能够12bit的数据类型,所以取最节省系统资源又能保持数值不变的uint16_t 类型,由于ADC采样电压范围是0-3.3v,采样值呈线性分布,那么实际电压就等于ADC_Volt=* 3.3 / 2 ^12 即 ADC_Volt = 3.3 / 4096
串口显示如下: