多路ADC的采集——stm32

2023-11-09

         在对实际应用过程中,ADC的采集大多是多个通道同时采集的,比如同时采集多个传感器的数据,就可能需要我们配置多个通道的ADC采集了,而多通道的ADC采集大多用到了DMA,笼统的讲通过DMA来传输数据不经过CPU,可以有效的为CPU减负,我们在使用时只需要通过CPU完成相应的初始化,而传输本身呢,是由DMA来进行的,而对于采集到的不同通道的数据我们只需要将其放入指定的数组便可以获得到不同通道具体的数据了。

DMA通道配置过程:
1、在DMA_CPARx寄存器中设置外设寄存起的地址,发生外设数据请求时,这个地址将是数据传输的源或目标。
2、在DMA_CMARx寄存器中设置数据存储寄存器的地址,发生外设数据请求时,传输的数据将从这个地址读出或写入这个地址。
3、在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
4、在DMA_CCRx寄存器的PL[1:0]位中设置优先级。
5、在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断,或
     传输完成产生中断。
6、设置DMA_CCRx寄存器的ENABLE位,启动该通道。

具体的配置过程我们通过代码来 展示

首先定义一个数组以便我们存放数据,数组大小按照实际需求即可。

u16 ADC_convered[2]={0,0};

然后是io口的初始化(我这儿把ADC的时钟也直接使能了) 

static void ADC_GPIO_CONFIG(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1	, ENABLE );	//使能 
    ADC1通道时钟
	//PA1 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//初始化两个GPIO
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
}

再接下来便是重头戏了——DMA和ADC的初始化(有些部分是需要配置多个通道的)

static void ADC_MODE_CONFIG_(void)
{ 	
	
	DMA_InitTypeDef DMA_InitInstructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	DMA_DeInit(DMA1_Channel1);//复位
	DMA_InitInstructure.DMA_PeripheralBaseAddr =(u32)(&(ADC1->DR));//配置外设的基址,取adc 
    数据寄存器的地址
	DMA_InitInstructure.DMA_MemoryBaseAddr = (u32)ADC_convered;//把DMA的数据存入数组
	DMA_InitInstructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设到DMA
	DMA_InitInstructure.DMA_BufferSize = 2;//2个通道
	DMA_InitInstructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//
	DMA_InitInstructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitInstructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitInstructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitInstructure.DMA_Mode = DMA_Mode_Circular;//不断地传输,有数据就传输
	DMA_InitInstructure.DMA_Priority = DMA_Priority_High;//DMA优先级
	DMA_InitInstructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel1,&DMA_InitInstructure);
	DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA请求
	
	
	
	
	
	ADC_InitTypeDef ADC_InitStructure; 
	ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立 
    模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;	//模数转换工作在多通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;	//模数转换工作在连续转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是 
    外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 2;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄 
    存器   




	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
		//设置指定ADC的规则组通道,一个序列,采样时间
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1,1, ADC_SampleTime_239Cycles5 );	 
      //ADC1,ADC1通道1,采样时间为239.5周期
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2,2, ADC_SampleTime_239Cycles5 );	 
     //ADC1,ADC1通道2,采样时间为239.5周期

    ADC_DMACmd(ADC1,ENABLE);	
    ADC_Cmd(ADC1,ENABLE);

	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	 
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
	
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能	
	 
	//while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束


}				  

然后把初始化的程序整到一块,方便调用

void Adc_Init()
{
   ADC_GPIO_CONFIG();
   ADC_MODE_CONFIG_();
}

接下来便是主函数部分了,主函数主要看要实现什么样的功能,初始化之后其实也就是把采集到的数据展示或设置阈值再进行相应的操作。

extern u16 ADC_convered[2];

int main(void)
{ 
   delay_init();
	//uart_init(9600);//串口初始化为9600,串口打印需要对其进行初始化
   float temp[2];
   delay_init();
   Oled_Init();
   Adc_Init();

	float value;
	float value1;
	char buf[5];
	char buf1[5];

	while(1)
	{
	    temp[0]=(float)ADC_convered[0]/4096*3.3;
		temp[1]=(float)ADC_convered[1]/4096*3.3;//结果-电压转换
		
		//printf("\r\n THE AD1 is = %f V \r\n",temp[0]);
		//printf("\r\n THE AD2 is = %f V \r\n",temp[1]);
	
        value = temp[0];
		sprintf(buf,"%f",value);
		Oled_Display_String(0,0,buf);//显示电压值
		
		value1 = temp[1];  
	    sprintf(buf1,"%f",value1);	
		Oled_Display_String(2,0,buf1);//显示电压值
		
		//Oled_Display_String(4,0,buf1);//	
		
		delay_ms(500);//延时了一小会儿,要不数据变化太快,看的心烦
        //我这儿是把电压值显示在了oled上
	}	  
}	

如有错误还请指出,谢谢

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多路ADC的采集——stm32 的相关文章

  • c++学生信息管理系统(window控制台实现鼠标点击操作)

    翻起大一时写过的作业代码 一个学生信息管理系统 当时不会使用QT 不会MFC等库 只会c 但是又想做一个有界面的 能够实现鼠标操作的程序 于是绞尽脑汁查资料 自己造轮子 最终写出来了下面的这个现在连我自己也看不懂的代码 代码虽然有些长 单文
  • 图书管理系统服务器,图书管理系统的服务器

    图书管理系统的服务器 内容精选 换一换 eBackup备份管理系统支持对VMware环境下虚拟机的保护 您需要在系统中增加VMware受保护环境 从而对受保护环境中的虚拟机进行备份和恢复 增加VMware受保护环境时 如果虚拟机名称中包含
  • 回文序列

    题目描述 如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列 例如 1 2 1 15 78 78 15 112 是回文序列 1 2 2 15 78 87 51 112 2 11 不是回文序列 现在给出一个数字序列 允许使用
  • Unity3D的断点调试功能

    Unity3D的断点调试功能 2013 03 14 16 27 51 分类 Unity教程 标签 unity monodevelop 断点调试 debug 举报 字号 订阅 断点调试功能可谓是程序员必备的功能了 Unity3D支持编写js和
  • C#获取字符串中括号中内容的正则表达式

    正则表达式为 lt w 2 如 string str1 发送奥点奥点 66 dasaa213434esdf Regex rex new Regex lt w 2 Match m rex Match str1 Console WriteLin
  • 【自然语言处理】ChatGPT 相关核心算法

    ChatGPT 相关核心算法 ChatGPT 的卓越表现得益于其背后多项核心算法的支持和配合 本文将分别介绍作为其实现基础的 Transformer 模型 激发出其所蕴含知识的 Prompt Instruction Tuning 算法 其涌
  • 使用jq让页面滚动到顶部

    以下是完整代码

随机推荐

  • 求任何时间下不同纬度太阳高度角的计算公式

    太阳高度角简称太阳高度 其实是角度 对于地球上的某个地点 太阳高度是指太阳光的入射方向和地平面之间的夹角 太阳 高度是决定地球表面获得太阳热能数量的最重要的因素 我们用h来表示这个角度 它在数值上等于太阳在天球地平坐标系中的地平高度 太阳高
  • 【111】支持向量机原理及python实现

    内容目录 一 基本概念二 鸢尾花实验三 乳腺癌检测实验 一 基本概念 024 SVM有监督学习LinearSVC LinearSVR SVC SVR参数解释 线性支持向量机 在超平面确定的情况下 可以相对地表示点距离超平面的远近 对于两类分
  • sublime Text3 自定义配色方案

    自定义配色方案地址 使用引导 首先 点击General gt background gt 修改一般 txt文件的默认背景 护眼的RGB值 豆沙绿的rgb颜色 199 237 204 色调 85 饱和度 1 2 3 亮度 2 0 5 对应成1
  • 504. Base 7

    Given an integer return its base 7 string representation Example 1 Input 100 Output 202 Example 2 Input 7 Output 10 Note
  • Mysql实现行列转换

    mysql数据库如何实现行列转换 1 行转列 方案一 select name sum case when course java then grade end as java sum case when course C then grad
  • React 封装组件的一些心得(一)

    起因 最近公司业务不是那么多 就抽空写了下组件库的东西 然后看了很多组件库的源码 由于我这里封装的主要是 taro 移动端的组件 所以主要是参考了 antd mobile react vant tard 等组件库 然后根据他们的源码 整合出
  • openGL贝塞尔曲面细分

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一 贝塞尔曲面细分原理 二 代码 1 主程序c 效果 前言 现在让我们扩展我们的程序 使它将我们简单的矩形网格转换为贝塞尔曲面 细分网格 应该为我们提供了足够的顶点来对曲面
  • Sublime Text 2 添加到右键

    转载于 把Sublime Text 2 加入右键菜单 带图标 Edit with Sublime Text Sublime Text 2 是现在很受大家欢迎的编辑器了 不仅是在web前端 在书定简单的php Js等代码时 也是相当的好用 再
  • 注册ChatGPT时提示Oops! The email you provided is not supported

    问题描述 今天本想出一个ChatGPT的注册与使用的教程 结果上来吃了个闭门羹 之前我通过微软账号登录验证是没有问题的 但这次想使用另一个微软账号 结果提示Oops The email you provided is not support
  • JDBC编程的六大步骤

    1 注册驱动 把驱动程序类加载到内存中 利用反射机制 这里是利用反射机制去加载某个类的特性 并不是要获取这个镜像对象来操作 加载这个类就会让这个类中的static 被执行 这个静态代码块中的代码就是注册驱动的代码 String driver
  • top5数据高级分析必备的Python库

    top5数据高级分析必备的Python库 1 Pandas 2 Numpy 3 Matplotlib https blog csdn net qq 40985985 article details 119676953 4 Scikit 学习
  • 【 Python 全栈开发 - 语法基础篇 - 19 】模块和包

    文章目录 一 模块 二 包 在 Python 中 模块指的是一个包含 Python 代码的文件 它可以被其他 Python 程序导入和使用 模块通常包括一些函数 类和变量 可以用于执行特定的任务或实现特定的功能 而包指的是一个包含多个模块的
  • 抖音短视频矩阵系统多账号管理,功能框架及开发逻辑

    目录 文章目录 前言 一 矩阵号系统是什么 二 使用步骤 1 创建推广项目 2 多账号授权 3 企业号智能客服系统 总结 前言 短视频多账号矩阵系统 通过多账号一键授权管理的方式 为运营人员打造功能强大及全面的 矩阵式 管理平台 使用矩阵系
  • MOS管、BJT 饱和区 不同

    1 深刻理解并记住工作在开关状态下 两种器件工作在何种工作区 三极管 从左到右 依次为 饱和 放大 截至 开关状态下是工作在截至与饱和区之间 MOS 从左到右 依次为可变电阻 非饱和区 完全导通区 饱和 横流区 放大区 有源区 线性区 截至
  • Vue3报错Property “xxx“ was accessed during render but is not defined on instance.

    使用Vue3重构自己项目时遇到报错 Property xxx was accessed during render but is not defined on instance 碰到这个报错已经不是一次两次了 写篇文章记录一下 翻译 Pro
  • 软件缺陷的管理

    目录 1 软件缺陷产生的原因 1 1 需求不明确 1 2 软件结构复杂 1 3 编码问题 1 4 项目期限太短 1 5 使用新技术 2 软件缺陷的分类 2 1 从测试种类划分缺陷 2 2 从缺陷严重程度划分 2 3 从缺陷的优先级划分 2
  • 【计算机视觉

    文章目录 一 检测相关 18篇 1 1 Neural Network Training Strategy to Enhance Anomaly Detection Performance A Perspective on Reconstru
  • Ubuntu更换源-清华大学源

    文章目录 前言 备份原来的源 更换源 更新源 前言 安装好ubuntu系统后 默认的软件更新源是国外的 在国内使用速度很慢 安装软件时可能出现 各种各样的错误 所以我们需要更换成国内的源 这样才能更快更安全的安装和更新软件 此次我们选用的是
  • scratch 鼠标控制角色移动

    scratch 鼠标控制角色 本程序使用鼠标操作 机器人 角色跟随鼠标 距离较小时暂停移动 小狗 角色连续在随机位置生成 水平移动 碰到边缘反弹 碰到 机器人 角色时删除 目前scratch程序的制作已经告一段落了 进一步开发需要更多规划
  • 多路ADC的采集——stm32

    在对实际应用过程中 ADC的采集大多是多个通道同时采集的 比如同时采集多个传感器的数据 就可能需要我们配置多个通道的ADC采集了 而多通道的ADC采集大多用到了DMA 笼统的讲通过DMA来传输数据不经过CPU 可以有效的为CPU减负 我们在