32ADC模数转换器&AD单通道&多通道

news2024/10/8 11:56:30

目录

一.简介

二.逐次逼近法​编辑

三.结构框图

四.小tips

(1)转换模式

(2)触发控制

 (3)数据对齐

(4)转换时间

(5)校准

(6)硬件电路 

五.相关函数

六.代码实现

(1)单通道

(2)多通道


一.简介

数字电路只有高低电平,没有几伏电压的概念 

PWM就是DAC的功能,同时PWM只有完全导通和完全断开的两种状态,这两种状态都没有功率损耗

12位(0~2的12次方减1=0~4095),位数越高,量化结果就越精细,对应的分辨率就越高

1us对应AD转换频率为1MHz(最快),ADC转换的信号频率不要超过AD最快转换频率

温度传感器可以测量CPU的温度 

规则组:常规使用;注入组:用于突发事件

模拟看门狗可以检测某些通道,当AD值高于或低于设定的上阈值或低于下阈值时,就会申请中断执行对应的操作

二.逐次逼近法

三.结构框图

四.小tips

(1)转换模式

每次转换都需要进行触发,且要判断是否结束,并没有使用到列表

只用在最开始的时候进行触发,每次转换完成后立刻开始下一次转换,并没有使用到列表

扫描模式下,每个单独的通道转换完之后,不会产生标志位,也不会触发中断 

(2)触发控制

 

 (3)数据对齐

(4)转换时间

(5)校准

(6)硬件电路 

五.相关函数

问题: 

数值跳变得太剧烈、

解决:

(1)

施密特触发原理

(2)滤波,让AD值变得平滑

均值滤波,读取多个值,取平均值,作为滤波的AD值

(3)裁剪分辨率,去除数据的尾数

六.代码实现

(1)单通道

AD.c

#include "stm32f10x.h"                  // Device header
uint16_t i;
void AD_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;//必须要写在程序的开头位置
	ADC_InitTypeDef ADC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//ADC都是APB2上的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	//在AIN模式下GPIO是无效的,专门为ADC服务
	//断开GPIO,防止GPIO的输入和输出对模拟电压造成干扰
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//分频设置ADC时钟,ADCCLK=12MHz
	
	
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	//若想要在多个序列填充多个通道,可以复制19行进行填充,配置不同的采样时间
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//配置ADC独立模式
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;//是否为扫描模式
	ADC_InitStructure.ADC_NbrOfChannel=1;//扫描模式下会用到的通道数目
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//配置成单次转换
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//不使用外部触发源
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);//开启ADC电源
	
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//复位校准完成后硬件自动置0
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)== SET);//校准完成后硬件自动置0
	
	
}
uint16_t ADC_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发转换
			//软件触发在扫描连续转换模式,要放在ADC_Init结尾
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//软件触发在扫描连续转换模式,可以去除这一句
	//规则组或注入组完成时都会置1,可以由软件清除或由读取ADC_DR时清除
	//等待时间=68/12MHz=5.6us,68=55.5+12.5
	return ADC_GetConversionValue(ADC1);//读取ADC_DR
	
}
float ADC_VA(uint16_t i)
{
	float Temp;
	i=ADC_GetValue();
	Temp = (float)i*3.3/(float)4095;
	return Temp;
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"  
#include "OLED.h" 
#include "AD.h" 
uint16_t ADC_Value;
float VA;
int main()
{
	OLED_Init();
	AD_Init();
	OLED_ShowString(1,1,"ADC:");
	OLED_ShowString(2,1,"Va:0.00V");
	while(1)
	{
		ADC_Value=ADC_GetValue();
		VA=ADC_VA(ADC_Value);
		OLED_ShowNum(1,5,ADC_Value,5);
		OLED_ShowNum(2,4,VA,1);
		OLED_ShowNum(2,6,(int)(VA*100)%100,2);
	}	
}
	

(2)多通道

多通道的实现最好采用DMA转运数据,但这里还没有学到,所以不采用真正的多通道实现

可以用单次转换,非扫描模式,每转换一个通道就用ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);

对通道进行更新,多次读值

AD.c

#include "stm32f10x.h"                  // Device header
uint16_t i;
void AD_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;//必须要写在程序的开头位置
	ADC_InitTypeDef ADC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//ADC都是APB2上的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	//在AIN模式下GPIO是无效的,专门为ADC服务
	//断开GPIO,防止GPIO的输入和输出对模拟电压造成干扰
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//分频设置ADC时钟,ADCCLK=12MHz
	
	
	//若想要在多个序列填充多个通道,可以复制19行进行填充,配置不同的采样时间
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//配置ADC独立模式
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;//是否为扫描模式
	ADC_InitStructure.ADC_NbrOfChannel=1;//扫描模式下会用到的通道数目
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//配置成单次转换
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//不使用外部触发源
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);//开启ADC电源
	
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//复位校准完成后硬件自动置0
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)== SET);//校准完成后硬件自动置0
}
uint16_t ADC_GetValue(uint8_t ADC_Channel)
{
	ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);

	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发转换
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
	//规则组或注入组完成时都会置1,可以由软件清除或由读取ADC_DR时清除
	//等待时间=68/12MHz=5.6us,68=55.5+12.5
	return ADC_GetConversionValue(ADC1);//读取ADC_DR
}

main.c 

#include "stm32f10x.h"                  // Device header
#include "Delay.h"  
#include "OLED.h" 
#include "AD.h" 
uint16_t AD1,AD2,AD3,AD4;
float VA;
int main()
{
	OLED_Init();
	AD_Init();
	OLED_ShowString(1,1,"AD1:");
	OLED_ShowString(2,1,"AD2:");
	OLED_ShowString(3,1,"AD3:");
	OLED_ShowString(4,1,"AD4:");
	

	while(1)
	{
		AD1 = ADC_GetValue(ADC_Channel_0);
		AD2 = ADC_GetValue(ADC_Channel_1);
		AD3 = ADC_GetValue(ADC_Channel_2);
		AD4 = ADC_GetValue(ADC_Channel_3);
		OLED_ShowNum(1,5,AD1,5);
		OLED_ShowNum(2,5,AD2,5);
		OLED_ShowNum(3,5,AD3,5);
		OLED_ShowNum(4,5,AD4,5);
		Delay_ms(100);

	}	
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1432014.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java语法学习IO流

Java语法学习IO流 大纲 文件IO流 具体案例 1. 文件 基本介绍 创建文件 第一种: public static void main(String[] args) {String filePathName "d:\\news1.txt";File file new File(filePathName);try {file.createNewFile();} catch (IOExceptio…

vulhub中Apache Druid 代码执行漏洞复现(CVE-2021-25646)

Apache Druid是一个开源的分布式数据存储。 Apache Druid包括执行嵌入在各种类型请求中的用户提供的JavaScript代码的能力。这个功能是为了在可信环境下使用,并且默认是禁用的。然而,在Druid 0.20.0及以前的版本中,攻击者可以通过发送一个恶…

2018 年全国职业院校技能大赛高职组“信息安全管理与评估”赛项任务书(笔记解析)

1. 网络拓扑图 2. IP 地址规划表 3. 设备初始化信息 阶段一 任务 1:网络平台搭建 1、根据网络拓扑图所示,按照 IP 地址参数表,对 WAF 的名称、各接口 IP 地址 进行配置。 2、根据网络拓扑图所示,按照 IP 地址参数表,对 DCRS 的名称、各接口 IP 地址 进行配置。 3、根据网…

C++项目 -- 高并发内存池(二)Thread Cache

C项目 – 高并发内存池(二)Thread Cache 文章目录 C项目 -- 高并发内存池(二)Thread Cache一、高并发内存池整体框架设计二、thread cache设计1.整体设计2.thread cache哈希桶映射规则3.TLS无锁访问4.thread cache代码 一、高并发…

CCF迎来新风采:揭晓2024-2026年度执行机构负责人名单!

会议之眼 快讯 中国计算机学会(CCF)成立于1962年,是一家全国性学会,拥有独立社团法人地位,同时是中国科学技术协会的会员单位。作为中国计算机及相关领域的学术团体,CCF的宗旨在于为该领域专业人士的学术和…

C

extern int a; //同一个项目声明 int r a > b ? a : b; 错误 scanf 不输入‘\n’,getchar()输入\n; printf()返回值 0次 system("cls"); 可以调用命令行函数 time(NULL)时间戳 srand((unsigned)time(NULL)); //随机数种子 int rev rand()%1001; //随…

Linux---yum命令详解

📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 目录 1.概念2.yum的配置信…

Open CASCADE学习|拓扑变换

目录 平移变换 旋转变换 组合变换 通用变换 平移变换 TopoDS_Shape out;gp_Trsf theTransformation;gp_Vec theVectorOfTranslation(0., 0.125 / 2, 0.);theTransformation.SetTranslation(theVectorOfTranslation);BRepBuilderAPI_Transform myBRepTransformation(out, th…

一篇文章了解区分指针数组,数组指针,函数指针,链表。

最近在学习指针,发现指针有这许多的知识,其中的奥妙还很多,需要学习的也很多,今天那我就将标题中的有关指针知识,即指针数组,数组指针,函数指针,给捋清楚这些知识点,区分…

【Linux取经路】进程控制——程序替换

文章目录 一、单进程版程序替换看现象二、程序替换的基本原理三、程序替换接口学习3.1 替换自己写的可执行程序3.2 第三个参数 envp 验证四、结语一、单进程版程序替换看现象 #include <stdio.h> #

【Funny guys】龙年专属测试鼠标寿命小游戏...... 用Python给大家半年了......

目录 【Funny guys】龙年专属测试鼠标寿命小游戏...... 用Python给大家半年了...... 龙年专属测试鼠标寿命小游戏用Python给大家半年了贪吃龙游戏 文章所属专区 码农新闻 欢迎各位编程大佬&#xff0c;技术达人&#xff0c;以及对编程充满热情的朋友们&#xff0c;来到我们的程…

Spring Boot + flowable 快速实现工作流

背景 使用flowable自带的flowable-ui制作流程图 使用springboot开发流程使用的接口完成流程的业务功能 文章来源&#xff1a;https://blog.csdn.net/zhan107876/article/details/120815560 一、flowable-ui部署运行 flowable-6.6.0 运行 官方demo 参考文档&#xff1a; htt…

SpringBoot整合Flowable最新教程(二)启动流程

介绍 文章主要从SpringBoot整合Flowable讲起&#xff0c;关于Flowable是什么&#xff1f;数据库表解读以及操作的Service请查看SpringBoot整合Flowable最新教程&#xff08;一&#xff09;&#xff1b;   其他说明&#xff1a;Springboot版本是2.6.13&#xff0c;java版本是1…

4. 树(二叉树、二叉查找树/二叉排序树/二叉搜索树、平衡二叉树、平衡二叉B树/红黑树)

树 1. 二叉树1.1 概述1.2 特点1.3 二叉树遍历方式1.3.1 前序遍历(先序遍历)1.3.2 中序遍历1.3.3 后序遍历1.3.4 层序遍历 2. 二叉查找树&#xff08;二叉排序树、二叉搜索树&#xff09;2.1 概述2.2 特点 3. 平衡二叉树3.1 概述3.2 特点3.3 旋转3.3.1 左旋3.3.2 右旋 3.4 平衡二…

指针的学习2

目录 数组名的理解 使用指针访问数组 一维数组传参的本质 冒泡排序 二级指针 指针数组 指针数组模拟二维数组 数组名的理解 数组名是数组首元素的地址 例外&#xff1a; sizeof(数组名),sizeof中单独放数组名&#xff0c;这里的数组名表示整个数组&#xff0c;计算的…

EasyCVR智能视频监控平台云台降低延迟小tips

TSINGSEE青犀视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&…

彻底学会系列:一、机器学习之线性回归

1.基本概念 线性回归&#xff1a; 有监督学习的一种算法。主要关注多个因变量和一个目标变量之间的关系。 因变量&#xff1a; 影响目标变量的因素&#xff1a; X 1 , X 2 . . . X_1, X_2... X1​,X2​... &#xff0c;连续值或离散值。 目标变量&#xff1a; 需要预测的值: t…

智慧未来已至:人工智能与数字孪生共筑城市新纪元

随着科技的飞速发展&#xff0c;人工智能与数字孪生技术正逐步成为智慧城市建设的核心驱动力。 这两项技术的结合&#xff0c;不仅将彻底改变城市的传统面貌&#xff0c;更将引领我们走向一个更加高效、便捷、绿色的未来。 一、智慧城市的新内涵 智慧城市&#xff0c;是指在城…

DDoS攻击:分布式拒绝服务攻击的威胁与对策

DDoS攻击&#xff1a;分布式拒绝服务攻击的威胁与对策 随着互联网的快速发展&#xff0c;网络安全威胁也在不断增加。其中&#xff0c;分布式拒绝服务攻击&#xff08;DDoS&#xff09;是一种常见且具有破坏性的攻击方式&#xff0c;给个人用户、企业和组织的网络基础设施带来了…

爬虫工作量由小到大的思维转变---<第四十五章 Scrapyd 关于gerapy遇到问题>

前言: 本章主要是解决一些gerapy遇到的问题,会持续更新这篇! 正文: 问题1: 1400 - build.py - gerapy.server.core.build - 78 - build - error occurred (1, [E:\\项目文件名\\venv\\Scripts\\python.exe, setup.py, clean, -a, bdist_uberegg, -d, C:\\Users\\Administrat…