ADC基本工作原理和Cubemx相关开发基础

目录

基本原理

A/D转换器的几个技术指标

基本转换过程

Cubemx相关开发

STM32的ADC资源概述

Cubemx配置

查询方式和中断方式的HAL库函数应用 

 实例

cubemx配置

 代码编写


基本原理

以一个恒温锅炉为例:通过温度传感器,将温度变化转换为电压变化。通过ADC将模拟的电压变化,转换为数字变化,将其编码。中央处理器根据温度数据,进行计算和逻辑控制。计算结果通过DAC转化为电压/电流信号,控制加热和冷却。

A/D转换一般要经过采样、 保持、量化和编码4个过程,将时间和幅值连续的模拟量转化为时间和幅值离散的数字量。

A/D转换器的几个技术指标

量程:指ADC所能输入模拟信号的类型和电压范围,即参考电压。信号类型包括单极性和双极性。

转换位数:量化过程中的量化位数n。A/D转换后的输出结果用n位二进制数来表示。例: 10位ADC 的输出值就是0~1023。

分辨率: ADC能够分辨的模拟信号最小变化量。公式:分辨率=量程/2n。例:量程为单极性0-5V,8位ADC的分辨率是:5/256= 0.0195V 

转换时间:ADC完成一次完整的A/D转换所需要的时间,包括采样、保持、量化、编码的全过程。

基本转换过程

四个过程:采样、保持、量化、编码。

Cubemx相关开发

STM32的ADC资源概述

STM32F103ZE芯片(144脚)中有ADC1、ADC2、ADC3共3个12位逐次逼近型模数转换器,具有18个测量通道,可测量16个外部和2个内部信号源(内部温度和内部参考电压)。这2个内部信号源只能连接到ADC1。各个通道的A/D转换可以单次、连续、扫描或间断模式执行。

按照A/D转换的组织形式来划分,ADC的模拟输入通道分为规则组注入组两种。ADC可以对一组最多16个通道按照指定的顺序逐个进行转换,这组指定的通道称为规则组。在实际应用中,可能需要中断规则组的转换,临时对某些通道进行转换,好像这些通道注入了原来的规则组,故称注入组,最多由4个通道组成。

A/D转换结果有2种存储方式:左对齐、右对齐(默认)。

ADC 的输入电压范围设定在:0~3.3v,因为 ADC是12位的,那么12位满量程对应的就是 3.3V,12位满量程对应的数字值是:2^12。数值0对应的就是 0V。如果转换后的数值为X,X对应的模拟电压为Y,那么会有这么一个等式成立:2^12 / 3.3 = X / Y=> Y = (3.3 * X ) / 2^12。

Cubemx配置

 基础开发时使用默认参数即可

查询方式和中断方式的HAL库函数应用 

 实例

STM32应用开发,完成功能:
[1]将ADC_ IN1设置为12位ADC,右对齐,启用中断。
[2]分别用查询和中断这2种方式,每隔0.5秒采样一次ADC 的数据。
[3]将每次读取到的ADC采样值转换为对应电压值,发送到上位机。
[4] LED0(PB5)作为采样指示灯,在ADC转换过程中点亮,其余时间熄灭。

cubemx配置

首先对RCC、SYS、时钟树进行配置(参照最开始的文章),然后对ADC进行配置(这里采用默认),打开中断:

 初始化LED:

由原理图可以知道,IO口应设置为高电平使其熄灭,低电平亮

配置串口:

生成代码即可。 

 代码编写

一些定义准备

#define LED_ON()  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET)
#define LED_OFF() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET)

#include "stdio.h"//因为需使用sprint函数
uint16_t ADC_value = 0,ADC_v = 0;//前者存放ADC采取的数据,后者是电压值
uint8_t str_buff[64];//缓冲区

采用查询方式,并使用串口进行数据发送:

void UR1_Send_Info()
{
	sprintf((char *)str_buff,"采样值:%d,电压值:%d.%d%d V\r\n",ADC_value,ADC_v/100,(ADC_v%100)/10,ADC_v%10);
	HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000);
}

void ADC_Get_Value()
{
	HAL_ADC_Start(&hadc1);
	LED_ON();
	if(HAL_ADC_PollForConversion(&hadc1,10) == HAL_OK)
	{
		ADC_value = HAL_ADC_GetValue(&hadc1);
		ADC_v = ADC_value * 330 / 4096;
	}
	UR1_Send_Info();
	LED_OFF();
	HAL_ADC_Stop(&hadc1);
}

像&hadc1这些实例,可以在相关文件开头看见相关的定义:

 然后加到主函数并且延时即可:

 接着采用中断方式:

先寻找回调函数:

void UR1_Send_Info()
{
	sprintf((char *)str_buff,"²ÉÑùÖµ£º%d£¬µçѹֵ£º%d.%d%d V\r\n",ADC_value,ADC_v/100,(ADC_v%100)/10,ADC_v%10);
	HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000);
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	if(hadc->Instance == ADC1)
	{
		ADC_value = HAL_ADC_GetValue(&hadc1);
		ADC_v = ADC_value * 330 / 4096;	
		UR1_Send_Info();
		LED_OFF();		
	}
}

在启动AD的时候开灯:(主函数)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值