ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STM32学习笔记(CubeMX配HAL)(第七天:ADC的了解及应用)

2021-10-19 23:33:56  阅读:232  来源: 互联网

标签:采样 转换 AD Value STM32 ADC HAL


今天需要了解下A/D转换模块。大概就是ADC或者DAC。

一般来说除了老版的51单片机,现在的单片机大多都是自带AD转换的。主要是电压的变化,弄成数字变化,就可以进行编程了。

详细的说明就:

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

其中常用的一般类型就不再赘述了。反正也记不住。一般我们考虑的就是用到的时候在取看一下手册。

一般来讲有以下几个基本的技术指标:

量程:即它可以测量的电压范围,信号类型这种参考类的参数。信号包括了单极性和双极性。

转换位数:量化过程中的量化位数n(听不懂没啥,就是AD转换之后A/D用多少位来表示):比如10位AD就是0-1023;

分辨率:能分辨的最小变化量。分辨率=量程/2n;有些低功耗的物件,需要更小的电压变化量,这时候你就需要更高转换位数的AD了。

转换时间:一次AD转换的全过程所需要的时间。

那么接下来讲讲AD转换的基本过程:

采样:把连续的模拟信号,编程一种数字信号,就是一根一根的。这个东西我记得《信号与系统》或者《自动化原理》里都有讲,所以需要大家去学习一下。

之后就开始保持信号状态,然后进行量化和编码。就慢慢从模拟信号编程数字信号了。

咋解释呢,就是我通过傅里叶拉氏变换这些变化之后,现在我的信号已经变成离散的了。我需要一点一点来得出每一部分的一个数字信号,这个过程就需要我的信号在一段时间内保持住才可以。

当然这个过程,可以理解为啥函数每一个点来求微分的一个过程,只不过用滤波的思维去思考感觉会好一点。

然后整个过程是存在量化和编码误差的,这无法避免。不过分辨率越高,整个过程就误差越小。

一般来说,ADC的一个采样可以通过反馈的数据,来得到目前的电压值。我们可以简单讲一讲。因为我记得这个是我本科EDA需要学的东西.系统里可以通过现有的程序,已经给你算好了。不过同样的可以理解下,加深印象。

比如,一个温度传感器模块,范围为0-100度,参考电压是5V,AD转换器是8位的,0度是测得温度1.8V,100度时测的温度时4.3V,这时候我们需要求他的分辨率以及采集数据比如说时10010001的时候,多大的电压和温度?

电压分辨率:5 X 1/28=0.0195V;

温度分辨率:0.0195 X 40=0.78℃;

假设变化时Y=kX+B这样的线性变化;

求一下斜率k=(100-0)/(4.3-1.8)=40;

所以说就可以求的Y=40 X (x - 1.8);

所以说最后求的温度时(二进制)10010001=(十进制)145;

所以:0.0195 X 145=2.83V;

所以:(2.83-1.8)X 40=41.2℃;

STM32的ADC资源

(以下来自其他的资料,简单阐述下)一般来说,这个我们可以看芯片手册上的东西。比如STM32F103上面就有ADC1/2/3的共三个12位逐次逼近型模数转换器。具有18个测量通道。可以测量16个外部和2个内部的信号。其中呢,只有ADC1可以测量这两个信号源。

各个ADC通道中,A/D转换可以单次、连续、扫描、间断模式进行执行。

按照A/D转换的组织形式来说,ADC的模拟输入通道分为规则组和注入组:

规则组:ADC可以对一组最多16个通道按照指定的一个顺序进行逐个转换,这组指定通道称为规则组。

注入组:如果说需要中断规则组的转换,临时对某些通道进行转换,好像这些通道注入了原来的规则组,就称为注入组。一般来说,没咋用。最多有4个。

那么接下来,我们来配置一下。

ADC:一般来说12位,右对齐,然后使能个中断就行了。

然后需要了解下AD的一个查询方式。

一般来说ADC和USART一样,存在阻塞式的查询方式和非阻塞式的查询方式。

主要来看看这两种函数的结构:

阻塞式:

Uint_16 ADC_Value = 0;

HAL_ADC_Start(&hadc);

If(HAL_OK == HAL_ADC_PollForConversion(&hadc,10))

{

ADC0_Value = HAL_ADC_GetValue(&hadc);

}

非阻塞式:

Uint_16 ADC_Value(&hadc);

Void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef*hadc1)

{

ADC0_Value = HAL_ADC_GetValue(&hadc);

那么接下来,同样的做一个简单的例子。用到采样来实现功能。

首先ADC设置为12位,右对齐,中断使能

分别使用查询和中断,每0.5S检测ADC数据

每次读取的ADC采样值转换为电压值发送到上位机

LED1作为采样的指示灯,在ADC转换中点亮,其余时间熄灭。

那么接下来,根据题目,我觉得需要配置一个0.5s的定时器,一个LED的输出,ADC以及串口发送数据。那么大致我看来就是这几个操作。

接下来,我把核心的代码发在下面,大家作为一个参考。

#include "main.h"
#include "adc.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"

void SystemClock_Config(void);
#define LED1_ON() HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_RESET);//两个宏定义,用于定义LED的开关亮灭
#define LED1_OFF() HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET);

uint16_t ADC_Value =0,ADC_Volt =0;//这是初始化的两个值,分别用于计算采样值和电压值
uint8_t str_buff[64];//用于字符串的格式化
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);
}

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_OFF();
	}
}




/*下面我进行注释的时通过查询的方式进行的采样*/
/*void ADC0_GET_VALUE()
{
	HAL_ADC_Start(&hadc1);//初始化
	LED1_ON();//初始化后点灯
	if(HAL_ADC_PollForConversion(&hadc1,10)==HAL_OK)//如果ADC转换查询正常
	{
		ADC_Value = HAL_ADC_GetValue(&hadc1);//那么就读取ADC此时的值
		ADC_Volt = ADC_Value * 3300/4096;//计算电压值,3300就是3300mV,4096就是2的12次方
	}
	UR1_Send_Info();
	LED1_OFF();
	HAL_ADC_Stop(&hadc1);


}*/


/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();

  while (1)
  {
    /* USER CODE END WHILE */
	/*ADC0_GET_VALUE();
	HAL_Delay(500);*/
	
	  
	LED1_ON(); 
	HAL_ADC_Start_IT(&hadc1);
	HAL_Delay(500);
  }
}

今天在实验室加班到了11:00,现在还没下班,点个赞吧

标签:采样,转换,AD,Value,STM32,ADC,HAL
来源: https://blog.csdn.net/m0_57628341/article/details/120857026

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有