IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 教程2—ADC—有效值检测+输入阻抗的测试+最大值检测 -> 正文阅读

[嵌入式]教程2—ADC—有效值检测+输入阻抗的测试+最大值检测

教程2——stm32CubeMx—HAL库—ADC—有效值检测+输入阻抗的测试+最大值检测

写在前面:本专栏的所有代码都是在H743VIT6的基础上开发的,本人接触这块板子的时间也不长,写这个的目的是给自己规定一个ddl,很多具体管脚的用法可以直接在IDE里面看见。因为时间紧迫,文章力求简单明了,以功能实现为目标,如有错误,希望各位斧正。

一级目录

二级目录

三级目录

一、CubeMx的配置

1.芯片的选择

请添加图片描述

2.RCC的配置

在这里插入图片描述

3.adc单通道采样配置

请添加图片描述
请添加图片描述
请添加图片描述
配置adc的单通道采样时,选择adc独立模式,对齐的方式是右对齐,单通道时adc的扫描模式关闭(扫描模式在ADC多通道采样时会自动打开),采样的模式是间断模式连续转换使能,触发通道为1,触发方式为软件触发,注意开启adc的全局中断
adc单通道配置完毕。

4.adc多通道采样配置

请添加图片描述
请添加图片描述
请添加图片描述
配置adc的多通道采样与单通道的区别是需要改两个地方的number,还要设置三个通道的rank,即采样的优先级,然后多通道模式ide会自动开启自动扫描模式,这个时候注意,将之前单通道设置的连续采样模式关闭,改为间断采样(之后我们是用间断模式循环采样)。
至此,adc的多通道配置完毕。

二、实验板块

实验1 单通道adc采样

// 定义变量
  /* USER CODE BEGIN 0 */
	uint16_t ADC_Value;//定义adc的采样值
  /* USER CODE END 0 */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	 HAL_ADC_Start(&hadc1);     //启动ADC转换
	 HAL_ADC_PollForConversion(&hadc1, 50);   //等待转换完成,50为最大等待时间,单位为ms
	
	 if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
	 {
	  ADC_Value = HAL_ADC_GetValue(&hadc1);   //获取AD值
	}
HAL_Delay(1000);
  /* USER CODE END 3 */
}

实验2 多通道adc采样测阻抗特性

// 多通道采样测量输入电阻,输出电阻,测量电路的增益
/* USER CODE BEGIN PD */
uint16_t i,j = 0;
uint32_t adcBuf[3];
uint32_t Ri = 0;
uint32_t Ro = 0;
double Au = 0;
/* USER CODE END PD */
// 注意开启adc中断转换
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  	HAL_ADC_Start_IT(&hadc1); //开启adc中断转换
  	Ri = (adcBuf[2] * 5600 / (adcBuf[0] - adcBuf[2]));//测得输入电阻的值
  	Ro = (((adcBuf[1]*10000)/3080)-10000);//测得输出电阻的值
  	Au = (adcBuf[1]*100.0)/adcBuf[0];//测得放大倍数的值
//这里的输入电阻,输出电阻,放大倍数是随机设置的值,具体的根据电路的表达式来写
	HAL_Delay(100);//延时
  }
  /* USER CODE END 3 */
}
// A code block
/* USER CODE BEGIN 4 */

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)    //ADC转换完成回调
{
    HAL_ADC_Stop_IT(&hadc1);           //关闭ADC
//开了三个adc通道,所以要按照rank读取三次
	for(j=0;j<3;j++)
	{
		HAL_ADC_Start(&hadc1);
		HAL_ADC_PollForConversion(&hadc1,0xffff);
		adcBuf[j]=HAL_ADC_GetValue(&hadc1);//有四个管道,轮番读值,每进一次中断就更新一下
	}
	HAL_ADC_Stop(&hadc1);
}

我们设置的是12bit的adc采样,所以最终单片机采样的结果值应该是0~4095。还要注意的是,adc多通道采样的时候最好让每个通道属于非悬空状态(即让每个通道都要连接到需要测的值),不然测试出来的值会有问题。

实验3 最大值检测

// 非常简单粗暴的算法,本人在测试的时候发现这种算法兼容性非常不强,在面对外界干扰的时候最高值最低值不能实时更新,所以可以考虑开个定时器定时初始化更新
/* USER CODE BEGIN PTD */
uint32_t adcBuf[3];//adc多通道采样的数值

uint16_t ADC_max0 = 0;
uint16_t ADC_max1 = 0;
uint16_t ADC_max2 = 0;
uint16_t ADC_min2 = 4095;
/* USER CODE END PTD */


/* USER CODE BEGIN 4 */
//定时器的板块可以先用,之后会写
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim == (&htim3))
    {
		i++;
    	if(i > 15)
    	{
    	i = 0;
    	//每隔15个定时器周期就清一次零,当然可以更大,这是为了实时更新
   		ADC_max0 = 0;
   		ADC_max1 = 0;
   		ADC_max2 = 0;
   		ADC_min2 = 4095;
    	HAL_ADC_Start_IT(&hadc1); //定时器中断里面开启ADC中断转换,固定定时器的间隔开启一次采集,
    }
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)    //ADC转换完成回调
{
    HAL_ADC_Stop_IT(&hadc1);           //关闭ADC
    HAL_TIM_Base_Stop_IT(&htim3);		//关闭定时器
	for(j=0;j<3;j++)
	{
		HAL_ADC_Start(&hadc1);
		HAL_ADC_PollForConversion(&hadc1,0xffff);
		adcBuf[j]=HAL_ADC_GetValue(&hadc1);//有3个管道,轮番读值,每进一次定时器就更新一下

	}
	//最大值检测
	if(ADC_max0 < adcBuf[0])
	{
		ADC_max0 = adcBuf[0];
	}
	if(ADC_max1 < adcBuf[1])
	{
		ADC_max1 = adcBuf[1];
	}
	if(ADC_max2 < adcBuf[2])
	{
		ADC_max2 = adcBuf[2];
	}
	if(ADC_min2 > adcBuf[2])
	{
		ADC_min2 = adcBuf[2];
	}
	HAL_ADC_Stop(&hadc1);
    HAL_TIM_Base_Start_IT(&htim3);		//开启定时器
}
/* USER CODE END 4 */

实验4 有效值检测电路

//有几种思路实现有效值检测的功能,现在采用一种比较玄学(本人还没有想通的办法来检测正弦波的有效值)的方法。但是需要注意,单片机大多以3.3V为测量上限,一旦幅值超过3.3V采用12bits的adc采样就会有很大的误差

	//有效值检测,总共检测4095个数,每次检测的时候判断其值是否大于2048,如果大于,则计数,最终计数的值为有效值(有误差,可根据实际情况修正)
	ADC_Value = adcBuf[0];
    if(p > 4095)
    {
    	p = 0;
    	average = q;
    	q = 0;
    }

	if(ADC_Value>2048)
		q++;
	p++;
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章           查看所有文章
加:2021-08-02 20:50:34  更:2021-08-02 20:50:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:16:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码