ADC模数转换器的基本工作原理
例子:
-
温湿度传感器可以将温度变化转化为电压变化。
-
通过ADC将模拟的电压变化转换为数字变化,将其编码
-
中央处理器根据温度数据,进行计算和逻辑控制
-
计算的结果将通过DAC转化为电压/电流信号,进行控制。
ADC:将时间和幅值连续的模拟量转化为时间和幅值离散的数字量,A/D转换一般要经过采样、保持、量化、和编码4个过程
常用的ADC:逐次逼近型、双积分型、
AD转换的技术指标
-
量程:是指ADC所能输入模拟信号的类型和电压范围,也就是参考电压。信号类型呢包括共阴/共阳两种。
-
转换位数:量化过程中的量化位数N。A/D转换后的输出结果用n位二进制数表示
例子:10位ADC输出的值时0~1023
-
分辨率:ADC能够分辨的模拟信号的最小变化量。
例子:量程为单极性-5V 8位ADC的分辨率是 5/256=0.0195V
-
转换时间: ADC完成一次完整的A/D转换所需要的时间,包括采样、保持、量化、和编码4个过程
STM32的ADC开发基础
STM32的ADC资源概述“
1.STM32F103芯片中有ADC1、ADC2、ADC3共有3个12位逐次逼近型模数转换器,具有18个测量通道,可以测量16个外部和2个内部信号源。这两个内部信号源只能连接到ADC1
2.ADC的各个通道的A/D转换可以单次、连续、扫描或间断模式执行。
3.按照A/D转换的组织形式来划分,ADC的模拟输入通道分为规则组和注入组两种。
ADC可以对一组最多16个通道按照指定的顺序逐个进行转换,这组指定的通道称为规则组。(常用)
在实际应用中,可能需要中断规则组的转换,临时对某些通道进行转换,好像这些通道注入了原来的规则 组,故称注入组,最多由4个通道组成。
4.A/D转换结果以左对齐或右对齐的方式,存储在16位规则组或者注入组数据寄存器中。(默认右对齐)
查询方式和中断方式的HAL库函数
查询方式:阻塞式的A/D转换 在查询时不能进行其他的工作
HAL_ADC_Start(&hadc); 以查询的方式启动ADC
if(HAL_OK == HAL_ADC_PollForConversion(&hadc1,10))//等待一次规则组的ADC转换完成,并将结果读出
{
ADC0_Value = HAL_ADC_GetValue(&hadc1); //读取转换结果
}
中断方式:非阻塞式AD/转换 不用进行等待
HAL_ADC_Start_IT(&hadc); //以中断的方式启动ADC
/*重写ADC转换完成中断回调函数*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
ADC0_Value = HAL_ADC_GetValue(&hadc1); //读取转换结果
}
实训案例:ADC单次数据采样与电压换算
利用STM32CubeMX和Keil5协同开发,完成以下的功能:
【2】分别用查询和中断这2种方式,每隔0.5秒采样一次ADC的数据。
查询方式:
void ADC0_get_Value() //定义ADC换算函数
{
HAL_ADC_Start(&hadc1); //用查询的方式打开ADC
LED_kai(); //打开灯
if (HAL_ADC_PollForConversion(&hadc1,10)==HAL_OK) //判读是否转化正常
{
ADC_value=HAL_ADC_GetValue(&hadc1); //如果正常将至存至ADC_value中
ADC_volt=ADC_value*330/4096; //进行换算将读取到的数值X330/4096得到电压
}
UR1_Send_info() ; //用串口发送数据
LED_guan(); //关灯
HAL_ADC_Stop(&hadc1); //关闭ADC外设
}
中断方式:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (hadc->Instance==ADC1) //判断是不是打开的ADC1
{
ADC_value=HAL_ADC_GetValue(&hadc1); //如果正常将至存至ADC_value中
ADC_volt=ADC_value*330/4096; //进行换算将读取到的数值X330/4096得到电压
UR1_Send_info() ; //用串口发送数据
LED_guan(); //关灯
}
}
【3】将每次读取到的ADC采样值转换为对应电压值,发送到上位机。
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),1000); //利用串口发送函数发送数据
}