STM32F407寄存器操作(多通道单ADC+DMA)
1.前言
又是半年没更新了,趁着端午放假有点时间,并且最近项目要用这块知识,我就顺带研究一下ADC吧。
一般来说ADC主要用法包含了1.单通道软件触发(这是最简单和最常用的用法)2.单通道多次采集(需要快速采集数据,常见应用场景就是示波器)3.多通道采集(多个传感器数据)。
其中1、2我在前面的文章里也都介绍过了,这次我就说一说多通道采集。若是不能使用多通道采集,那么407里面两个ADC只能用两个通道,非常浪费。而407内一个ADC包涵16个通道,如此多的通道量基本能覆盖大部分应用场景了。
OK,那么废话不多说,下面我们正式开始介绍。
2.理论介绍
首先我们看看手册上关于这块的描述
这次我就以规则通道为例了,我们所有数据应该都是存放在DR寄存器里,这就会导致一个问题——数据覆盖。因此我们使用扫描模式时必须要用DMA配合使用。理论上来说如果全部使用注入通道,配置会比较简单,因为每个注入通道ADC都有保存的寄存器。不过这次教程我还是以较难的规则通道为例,一次性解决这个问题。
我们看到手册上对于扫描模式的开启只需要关注ADC->CR1里的SCAN,还是比较简单的。
我们看到CR1寄存器里,SCAN是第八位
给第八位置1即可
3.ADC配置
3.1ADC初始化
我首先把程序放出来,这里我用的是通道0和通道3
void init_adc1()
{init_adc12_chinal(0); //初始化通道0init_adc12_chinal(3); //初始化通道3ADC1->CR1&=~(3<<24); //15 ADCCLK 周期ADC1->CR1|=(1<<8); //扫描模式ADC1->CR2&=~(1<<1); //单次转换ADC1->CR2&=~(1<<11); //数据右对齐ADC1->CR2&=~(3<<28); //禁止触发检测ADC1->SQR1&=~(0XF<<20); //重置规则通道序重置列长度ADC1->SQR1|=1<<20; //2个转换在规则序列中//设置通道0的采样时间ADC1->SMPR2&=~(7<<(3*0)); //通道0 采样时间清空 ADC1->SMPR2|=(7<<(3*0)); //通道0 480个周期,提高采样时间可以提高精确度//设置通道3的采样时间ADC1->SMPR2&=~(7<<(3*3)); //通道3 采样时间清空 ADC1->SMPR2|=(7<<(3*3)); //通道3 480个周期,提高采样时间可以提高精确度//ADC1->CR2|=1<<8; //使能DMA模式ADC1->CR2|=1<<0; //开启AD转换器
}
基本上没有什么特殊的,按照手册上描述的,给第8位置1
记得把要使用的ADC通道初始化好,配置好采样时间,通道数量正确即可
然后是触发的程序
void adc1_scanf(void)
{ADC1->SQR3=0; //重置规则通道转换配置ADC1->SQR3|=0<<0; //设置第一次规则转换通道0ADC1->SQR3|=3<<5; //设置第二次规则转换通道3ADC1->CR2|=1<<30; //开始转换
}
与软件触发类似,就是要多配置一个通道
3.2主程序
主程序里我们依次初始化DMA,ADC然后触发一次ADC即可
int main(void)
{Stm32_Clock_Init(336,25,2,7);//设置时钟,168MhzNVIC_SetGroup(1);//设置中断分组,分组1init_PinClock();//初始化所有时钟delay_init(168);//初始化延时init_DMAClock();//初始化DMA时钟init_DMA2_S0C0(2);//DMA2 ADC1转换init_adc1(0);//初始化ADCadc1_scanf();//触发ADC
}
3.3测试
我们首先要看一下ADC程序是否正确
那么改如何测试呢?我们外部通道是PA0和PA3,我们的转换顺序是PA0-PA3。那么我们首先将PA3接地,那么程序运行结束后ADC的DR寄存器里应该是最后一次转换的数据,即PA3管脚的电压,但是因为PA3接地的,那么DR寄存器里首先应该是PA0的浮空值,之后应该被PA0覆盖为0。之后我们再把PA0接地,同理DR寄存器里应首先是PA0管脚的0,之后被覆盖为PA3的浮空值。
OK,我们来测试一下,首先把PA3接地。
可以看到DR寄存器内的数据为0
之后我们再把PA0接地
数据也是正常的浮空数据了
4.DMA配置
下面我来说说加上DMA后该怎么写,配合上DMA后ADC读取到的数据就不会丢失了,所有的数据都可以正常读取进RAM里,而且没有什么标志位,比较简单。
4.1DMA初始化
程序如下,与上一次篇配置是一样的,这里不做过多的介绍了
unsigned short adc_scanf[5];//初始化DMA2 组0 通道0
//ADC1
void init_DMA2_S0C0(unsigned int ADCDMAWei)
{DMA2_Stream0 ->CR = 0;//禁止数据流 ,才能写寄存器 //外设地址寄存器//将所需寄存器的地址放入PAR寄存器DMA2_Stream0 ->PAR = (unsigned int)(&ADC1->DR);//数据流地址寄存器//M1AR仅在双通道模式下有用//将数据所在地址给M0AR寄存器DMA2_Stream0 ->M0AR = (unsigned int)(&adc_scanf);DMA2_Stream0 ->NDTR = ADCDMAWei; // 一次传输数量 DMA2_Stream0 ->FCR = 0x21; //FIFO所有配置失效DMA2_Stream0 ->CR |= 0<< 6; //外设到储存器模式//循环模式//当NDTR寄存器减到0时自动重装//单次模式(普通模式)//NDTR减到0后停止DMADMA2_Stream0 ->CR |= 0<< 8; //非循环模式DMA2_Stream0 ->CR |= 0<< 9; //外设非增量模式DMA2_Stream0 ->CR |= 1<<10; //存储器增量模式,指针增加,可用于传输数组DMA2_Stream0 ->CR |= 1<<11; //外设数据长度:16位DMA2_Stream0 ->CR |= 1<<13; //存储器数据长度:16位DMA2_Stream0 ->CR |= 2<<16; //高等优先级//突发传输//DMA占用CPU总线时间,此时CPU无法工作//一个节拍:传输多少次32位变量//应用场景:从ram里读出字节DMA2_Stream0 ->CR |= 0<<21; //外设突发单次传输DMA2_Stream0 ->CR |= 0<<23; //存储器突发单次传输DMA2_Stream0 ->CR |= 0<<25; //通道0DMA2_Stream0 ->CR |= 1<<0; //使能数据流
}
4.2ADC初始化修改
ADC这里我们需要把CR2里DMA置1
程序如下
void init_adc1()
{init_adc12_chinal(0); //初始化通道0init_adc12_chinal(3); //初始化通道3ADC1->CR1&=~(3<<24); //15 ADCCLK 周期ADC1->CR1|=(1<<8); //扫描模式ADC1->CR2&=~(1<<1); //单次转换ADC1->CR2&=~(1<<11); //数据右对齐ADC1->CR2&=~(3<<28); //禁止触发检测ADC1->SQR1&=~(0XF<<20); //重置规则通道序重置列长度ADC1->SQR1|=1<<20; //2个转换在规则序列中//设置通道0的采样时间ADC1->SMPR2&=~(7<<(3*0)); //通道0 采样时间清空 ADC1->SMPR2|=(7<<(3*0)); //通道0 480个周期,提高采样时间可以提高精确度//设置通道3的采样时间ADC1->SMPR2&=~(7<<(3*3)); //通道3 采样时间清空 ADC1->SMPR2|=(7<<(3*3)); //通道3 480个周期,提高采样时间可以提高精确度ADC1->CR2|=1<<8; //使能DMA模式ADC1->CR2|=1<<0; //开启AD转换器
}
主函数里面使用方法也是一样的
4.3测试
首先把PA0接地
可以看到第0位数据为0了
然后再把PA3接地
可以看到第1为是0了
5.结语
STM32F407多通道扫描模式至此就结束了,整个过程还是比较简单的。这样一来ADC的使用范围也比较大了。在此之外ADC还有一个非连续扫描模式,那么我们下一篇文章去看。那么好的,还是老样子,有什么问题评论区见,我们下一篇文章见。
相关文章:

STM32F407寄存器操作(多通道单ADC+DMA)
1.前言 又是半年没更新了,趁着端午放假有点时间,并且最近项目要用这块知识,我就顺带研究一下ADC吧。 一般来说ADC主要用法包含了1.单通道软件触发(这是最简单和最常用的用法)2.单通道多次采集(需要快速采…...

基于React和TypeScript的金融市场模拟器开发与模式分析
基于React和TypeScript的金融市场模拟器开发与模式分析 项目概述 本项目开发了一个基于React和TypeScript的金融市场模拟器,通过模拟订单流和价格发现机制,重现了真实市场的动态特性。该模拟器不仅提供了实时价格图表、订单簿和交易功能,还…...
剑指offer13_剪绳子
剪绳子 给你一根长度为 n 绳子,请把绳子剪成 m 段(m、n都是整数,2≤n≤58 并且 m≥2)。 每段的绳子的长度记为 k[1]、k[2]、……、k[m]。 k[1]k[2]…k[m] 可能的最大乘积是多少? 例如当绳子的长度是 8 时࿰…...

reverse_ssh 建立反向 SSH 连接指南 混淆AV [好东西哟]
目录 🌐 工具简介 ⚙️ 前提条件 攻击主机 (Linux) 目标主机 (Windows) 📋 详细步骤 步骤 1:安装 Go 环境 步骤 2:安装必要依赖 步骤 3:下载并编译 reverse_ssh 步骤 4:配置密钥 步骤 5ÿ…...
vue+elementUi+axios实现分页(MyBatis、Servlet)
vueelementUiaxios实现分页 文章目录 vueelementUiaxios实现分页1.代码实现【HTML】**【Servlet层】****【Service层】****【Dao层】** 2.总结步骤3.实现要点4.注意事项4.注意事项 注:此项目 前端为 html、 后端采用 mybatis、servlet实现 1.代码实现 【HTML】…...
WebBuilder数据库:企业数据管理的能力引擎
在数据成为核心生产要素的时代,企业对数据库的需求早已超越“存储与查询”的基础功能,转而追求高性能、高安全、高兼容与高效开发的综合能力。WebBuilder作为企业级快速开发平台的佼佼者,其数据库能力正式破解数据管理难题的关键钥匙。本文将…...
QtWidgets,QtCore,QtGui
目录 三者的关系示例代码主要功能模块QtCore**一、核心功能与常用类****1. 信号与槽机制(Signals and Slots)****2. 事件处理(Event Handling)****3. 定时器(Timers)****4. 线程(Threading)****5. 文件与目录操作****6. 属性系统(Property System)****二、高级特性**…...

lvs-keepalived高可用群集
目录 1.Keepalived 概述及安装 1.1 Keepalived 的热备方式 1.2 keepalived的安装与服务控制 (1)安装keep alived (2)控制 Keepalived 服务DNF 安装 keepalived 后,执行以下命令将keepalived 服务设置为开机启动。 2.使用 Keepalived 实现双机热备 …...
【Elasticsearch】suggest
在Elasticsearch中,suggest 是一个非常强大的功能,用于实现自动补全、拼写纠错和模糊搜索等功能。它可以帮助用户更快地找到他们想要的内容,同时提升搜索体验。以下是关于 suggest 的详细使用方法和常见场景。 1\. Suggest 的基本概念 sugges…...

高速收发器
一、高速收发器 1.FPGA高速收发器:GTP,GTX,GTH,GTZ 2.每个Quad有4对高速收发器GT(4个TX和4个RX)和一个COmmon 3.走差分,提高抗干扰性 4.CPLL是每个lane私有的,QPLL是整个Quad的所有通道共享的 5.每个MGT的bank有两对差分参考时钟 6.CPLL的时钟…...

webpack的安装及其后序部分
npm install原理 这个其实就是npm从registry下载项目到本地,没有什么好说的 值得一提的是npm的缓存机制,如果多个项目都需要同一个版本的axios,每一次重新从registry中拉取的成本过大,所以会有缓存,如果缓存里有这个…...

如何利用自动生成文档工具打造出色的技术文档
文章目录 每日一句正能量前言一、自动生成文档工具的优势(一)提高效率(二)保持一致性(三)实时更新 二、常见的自动生成文档工具(一)Sphinx(二)Javadoc&#x…...
读《Go语言圣经记录》(二):深入理解Go语言的程序结构
读《Go语言圣经记录》(二):深入理解Go语言的程序结构 在编程的世界里,Go语言以其简洁、高效和强大的并发能力而备受开发者青睐。今天,我将带大家深入探索Go语言的程序结构,通过详细解读《Go语言圣经》中的…...

实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.7 R语言解题
本文是实验设计与分析(第6版,Montgomery著,傅珏生译) 第5章析因设计引导5.7节思考题5.7 R语言解题。主要涉及方差分析,正态假设检验,残差分析,交互作用图,等值线图。 dataframe <-data.frame…...
nacos Sentinel zipkin docker运行
服务注册发现 分布配置中⼼nacos dockerdocker pull nacos/nacos-server:1.3.2docker run -d --name nacos-server -p 8848:8848 -e MODEstandalone nacos/nacos-server:1.3.2访问 http://localhost:8848/nacos 服务限流降级:Sentinel docker docker pul…...

OpenCv高阶(二十)——dlib脸部轮廓绘制
文章目录 一、人脸面部轮廓绘制代码实现1、定义绘制直线段的函数2、定义绘制凸包轮廓的函数3、读取输入图像4、初始化dlib的人脸检测器5、使用检测器在图像中检测人脸(参数0表示不进行图像缩放)6、加载dlib的68点人脸关键点预测模型7、遍历检测到的每个人…...

pikachu靶场通关笔记08 XSS关卡04-DOM型XSS
目录 一、XSS原理 二、DOM型XSS 三、源码分析 1、进入靶场 2、XSS探测 3、源码分析 四、渗透实战 1、Payload1 2、Payload2 3、Payload3 本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关)渗透集合,通过对XSS关卡源码的代码审计找到XSS风…...
python集成inotify-rsync实现跨服务器文件同步
1、实现功能 通过结合 Python 的 watchdog 库(类似 Linux 的 inotify 机制)和 rsync 命令,实现了文件系统变化的实时监控和增量同步。下面详细解释其工作原理和运行方式: 2、核心工作原理 2.1、文件监控 使用watchdog库监控源目…...
005 ElasticSearch 许可证过期问题
ElasticSearch 许可证过期问题 项目启动报错 org.elasticsearch.client.ResponseException: method [GET], host [http://127.0.0.1:9200], URI [/_cluster/health/], status line [HTTP/1.1 403 Forbidden] {"error":{"root_cause":[{"type":…...

Spring AI 系列之使用 Spring AI 开发模型上下文协议(MCP)
1. 概述 现代网页应用越来越多地集成大型语言模型(LLMs)来构建解决方案,这些解决方案不仅限于基于常识的问答。 为了增强 AI 模型的响应能力,使其更具上下文感知,我们可以将其连接到外部资源,比如搜索引擎…...

[Python] Python运维:系统性能信息模块psutil和系统批量运维管理器paramiko
初次学习,如有错误还请指正 目录 系统性能信息模块psutil 获取系统性能信息 CPU信息 内存信息 磁盘信息 网络信息 其他信息 进程信息 实用的IP地址处理模块IPy IP地址、网段的基本处理 多网络计算方法 系统批量运维管理器paramiko paramiko 的安装 Li…...

Linux 简单模拟实现C语言文件流
🌇前言 在 C语言 的文件流中,存在一个 FILE 结构体类型,其中包含了文件的诸多读写信息以及重要的文件描述符 fd,在此类型之上,诞生了 C语言 文件相关操作,如 fopen、fclose、fwrite 等,这些函数…...
ArcPy错误处理与调试技巧(3)
三、调试技巧 调试是编程过程中不可或缺的一部分,以下是一些常用的调试技巧: 1. 打印调试信息 在代码中添加print语句,可以帮助你了解程序的运行状态和变量的值。例如: # 打印提示信息,表示开始执行缓冲区分析 print(…...

小程序使用npm包的方法
有用的链接 npm init -y 这个命令很重要, 会初始化 package.json 再重新打开微信小程序开发工具 选择工具中npm构建 在程序中引用时在main.js中直接使用包名的方式引用即可 如安装的是generator包,npm构建后就会生成 const myPackage require(***-generato…...
Asp.Net Core SignalR的协议协商问题
文章目录 前言一、协议协商的原理二、常见的协商问题及解决办法1.跨域资源共享(CORS)问题2.身份验证和授权问题3.传输方式不兼容问题4.路由配置错误5.代理和负载均衡器问题6.自定义协商(高级) 总结 前言 在ASP.NET Core SignalR …...

Rust 学习笔记:发布一个 crate 到 crates.io
Rust 学习笔记:发布一个 crate 到 crates.io Rust 学习笔记:发布一个 crate 到 crates.io提供有用的文档注释常用标题文档注释作为测试注释所包含的项目 使用 pub use 导出一个方便的公共 API设置 crates.io 账户添加 metadata 到一个新的 crate发布到 c…...
剪枝中的 `break` 与 `return` 区别详解
在回溯算法的剪枝操作中: if (sum candidates[i] > target) break;这个 break 既不等效于 return,也不会终止整个回溯过程。它只会终止当前层循环的后续迭代,而不会影响其他分支的回溯。让我用图解和示例详细说明: …...
Spring Boot 4.0实战:构建高并发电商系统
Spring Boot 4.0作为Java生态的全新里程碑,首次原生支持虚拟线程(Virtual Threads)与Project Loom特性,单机QPS处理能力较3.x版本提升5-8倍。本文以电商系统为实战场景,深度解析Spring Boot 4.0在微服务架构、分库分表…...

Vert.x学习笔记-EventLoop与Context的关系
Vert.x学习笔记 1. EventLoop 的核心作用2. Context 的核心作用3. EventLoop 与 Context 的关系1. 事件循环(EventLoop)的核心职责2. 上下文(Context)的核心职责3. 事件循环与上下文的关系(1)一对一绑定&am…...

2025030给荣品PRO-RK3566开发板单独升级Android13的boot.img
./build.sh init ./build.sh -K ./build.sh kernel 【导入配置文件】 Z:\Android13.0\rockdev\Image-rk3566_t\config.cfg 【更新的内核】 Z:\Android13.0\rockdev\Image-rk3566_t\boot.img 【导入分区表,使用原始的config.cfg会出错的^_】 Z:\Android13.0\rockdev\…...