嵌入式学习--江协stm32day4

news2025/6/9 5:25:07

只能说拖延没有什么好结果,欠下的债总是要还的。

ADC

模拟信号转化为数字信号,例如温度传感器将外部温度的变化(模拟信号),转换为内部电压的变化(数字信号)

IN是八路输入,下方是选择输入端,ALE是锁使能,DAC是数字信号,通过与模拟信号在比较器的比较,通过SAR的调整逐步逼近,最终生成八位输出

这里推荐大家在复习的时候借助ai啊,这样比再去视频里找效率高的多

1. 输入通道与选择

  • 外部模拟输入ADCx_IN0 ~ ADCx_IN15,共 16 路外部引脚,可接传感器等模拟信号。
  • 内部模拟信号
    • 温度传感器:内置温度传感器的模拟输出(用于采集芯片温度)。
    • V_REFINT:内部参考电压(稳定的基准电压,可用于校准或辅助测量)。

2. 转换触发控制

ADC 转换可通过 软件触发 或 硬件触发 启动,硬件触发支持灵活的外部 / 定时器同步:

  • 注入组触发(JEXTTRIG)
    • 触发源由 JEXTSEL[2:0] 配置,可选 TIM1_TRGOTIM8_CH4 等定时器触发输出,或外部引脚 EXTI_15
    • 用于紧急场景(如突发信号优先采集)。
  • 规则组触发(EXTTRIG)
    • 触发源由 EXTSEL[2:0] 配置,可选 TIM1_CH1TIM2_TRGO 等定时器触发,或外部引脚 EXTI_11
    • 用于周期性采集(如定时器定时触发,实现 “定时采样”)。
  • 重映射控制(如 ADCx_ETRGINJ_REMAP):调整触发信号的引脚映射(STM32 引脚功能可重映射,适配硬件布局)。

3. 转换核心与时钟

  • 模拟至数字转换器:核心模块,将选中的模拟信号转换为 12 位数字量(STM32 标准 ADC 精度)。
  • ADCCLK:转换时钟,来自 ADC 预分频器(需配置分频比,控制转换速度,避免时钟过高导致误差)。

4. 数据存储与传输

  • 规则通道数据寄存器(16 位):存储规则通道的转换结果,支持 DMA 请求(转换完成后直接触发 DMA,将数据搬运到内存,减轻 CPU 负担)。
  • 注入通道数据寄存器(4×16 位):存储 4 路注入通道的结果,无 DMA 支持(因注入通道优先级高,数据需快速响应,直接存寄存器供 CPU 读取)。

5. 监控与中断机制

  • 模拟看门狗:监测转换结果是否在 阈值高限(12位) 和 阈值低限(12位) 之间:
    • 若超出范围,触发 AWD 标志位,结合 AWDIE(中断使能),向 NVIC 发送中断请求(用于异常监测,如电压超限报警)。
  • 转换结束中断
    • EOC(规则转换结束):规则通道转换完成标志,EOCIE 使能后触发中断。
    • JEOC(注入转换结束):注入通道转换完成标志,JEOCIE 使能后触发中断。

四种转换模式

单次转换:每次只转换序列一

非扫描模式:每次转换后停止

因为只支持12位,但用16位储存需要选择对齐模式

  1. 采样:指对模拟信号按一定时间间隔进行取值,获取模拟信号在离散时间点上的瞬时值,就像每隔固定时间给模拟信号拍张 “快照”。例如对一个随时间连续变化的电压信号,每隔 0.01 秒记录一次其电压值。
  2. 保持:将采样得到的瞬时值在一段时间内维持不变,以便后续的量化和编码处理。相当于把 “快照” 固定住,使其在后续操作中有稳定的数值。比如采样得到一个电压值后,在完成量化编码前,让这个电压值保持恒定。
  3. 量化:把采样保持后的信号幅值按一定的量化等级进行划分,将其变为离散的数字量。例如将 0 - 5V 的电压范围划分为 10 个量化等级,每个等级 0.5V,采样得到的电压值就根据所处范围对应到相应量化等级。
  4. 编码:将量化后的结果用二进制代码等特定代码形式表示出来,最终得到数字信号。比如量化后的结果是第 3 个等级,编码为二进制的 “011” 。

AD单通道

#include "stm32f10x.h"                  // Device header
void AD_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
	ADC_InitStructure.ADC_NbrOfChannel=1;
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)==SET);
	
	
}
uint16_t AD_GetValue()
{
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
	return ADC_GetConversionValue(ADC1);
	
}

AD多通道

#include "stm32f10x.h"                  // Device header
void AD_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	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(GPIOB,&GPIO_InitStructure);
	
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
	ADC_InitStructure.ADC_NbrOfChannel=1;
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)==SET);
	
	
}
uint16_t AD_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);
	return ADC_GetConversionValue(ADC1);
	
}

DMA

1. DMA 控制器(DMA1、DMA2)
  • 作用:管理数据传输的 “指挥官”,内置 多个通道(如 DMA1 有通道 1/2/7,DMA2 有通道 1/2/5),每个通道可独立配置 “源地址、目标地址、传输长度、触发源” 等参数。
  • 通道分工:不同通道对应不同外设请求(如 DMA1 通道 1 可接 TIM2,通道 7 接 ADC1;DMA2 通道 5 接 USB),通过 仲裁器 决定同一 DMA 内通道的优先级。
2. 仲裁器
  • 功能:解决 “同一 DMA 内多个通道同时请求传输” 的冲突,按 “通道优先级(软件配置) + 硬件优先级(通道编号,如通道 7 比通道 1 优先级高)” 裁决,确保高优先级数据先传输。
3. AHB 从设备 & 总线矩阵
  • AHB 从设备:DMA 作为 AHB 总线的 “从设备”,可访问 SRAM、Flash 等 AHB 总线上的存储区域。
  • 总线矩阵:协调 ICode(指令总线,取 Flash 指令)、DCode(数据总线,取 Flash/SRAM 数据)、系统总线(访问外设) 的访问冲突,让 DMA、CPU 能并行工作(如 CPU 取指令时,DMA 可同时传输数据)。
4. 外设侧(APB1/APB2 总线)
  • 外设举例:ADC1/2(模拟转数字)、USART(串口)、TIM(定时器)、GPIO 等,这些外设可产生 DMA 请求信号(如 ADC 转换完成后发请求,触发数据从 ADC 寄存器→SRAM 传输)。

DMA数据转运

#include "stm32f10x.h"                  // Device header

uint16_t My_DMA_Size;
void MyDMA_Init(uint32_t AddrA,uint32_t AddrB,uint16_t Size)
{
	My_DMA_Size=Size;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr=AddrA;
	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Enable;
	DMA_InitStructure.DMA_MemoryBaseAddr= AddrB;
	DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize=Size;
	DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;
	DMA_InitStructure.DMA_M2M=DMA_M2M_Enable;
	DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);

	DMA_Cmd(DMA1_Channel1,DISABLE);
}

void MyDMA_Transfer()
{
	DMA_Cmd(DMA1_Channel1,DISABLE);
	DMA_SetCurrDataCounter(DMA1_Channel1,My_DMA_Size);
	DMA_Cmd(DMA1_Channel1,ENABLE);
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
	DMA_ClearFlag(DMA1_FLAG_TC1);
}

DMA+AD多通道

#include "stm32f10x.h"                  // Device header

uint16_t AD_Value[4];

void AD_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	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(GPIOB,&GPIO_InitStructure);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3,4,ADC_SampleTime_55Cycles5);

	
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
	ADC_InitStructure.ADC_NbrOfChannel=4;
	ADC_InitStructure.ADC_ScanConvMode=ENABLE;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)&ADC1->DR;
	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryBaseAddr= (uint32_t)&AD_Value;
	DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize=4;
	DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;
	DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
	DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);

	DMA_Cmd(DMA1_Channel1,ENABLE);
	
	ADC_DMACmd(ADC1,ENABLE);	
	ADC_Cmd(ADC1,ENABLE);
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)==SET);
	
	
}
void AD_GetValue( )
{
	DMA_Cmd(DMA1_Channel1,DISABLE);
	DMA_SetCurrDataCounter(DMA1_Channel1,4);
	DMA_Cmd(DMA1_Channel1,ENABLE);
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
	DMA_ClearFlag(DMA1_FLAG_TC1);
	
}

只能说拖延只会让自己难受,六级和期末考试摆在那里,拖延就需要2天把剩余的学完,整天都得按在椅子上了....

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

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

相关文章

【Matlab】连接SQL Server 全过程

文章目录 一、下载与安装1.1 SQL Server1.2 SSMS1.3 OLE DB 驱动程序 二、数据库配置2.1 SSMS2.2 SQL Server里面设置2.3 设置防火墙2.4 设置ODBC数据源 三、matlab 链接测试 一、下载与安装 微软的,所以直接去微软官方下载即可。 1.1 SQL Server 下载最免费的Ex…

9.RV1126-OPENCV 视频的膨胀和腐蚀

一.膨胀 1.视频流的膨胀流程 之前膨胀都是在图片中进行的,现在要在视频中进行也简单,大概思路就是:获取VI数据,然后把VI数据给Mat化发给VENC模块,然后VENC模块获取,这样就完成了。流程图: 2.代…

华为OD机考-内存冷热标记-多条件排序

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextInt();int[] arr new int[a];for(int…

AI时代:学习永不嫌晚,语言多元共存

最近看到两个关于AI的两个问题,“现在开始学习AI,是不是为时已晚?”、“AI出现以后,翻译几乎已到末路,那么,随着时代的进步,中文会一统全球吗?” 联想到自己正在做的“万能AI盒”小程…

行为型设计模式之Mediator(中介者)

行为型设计模式之Mediator(中介者) 1)意图 用一个中介对象来封装一系列的对象的交互。中介者使各对象不需要显示的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 2)结构 其中&#xff…

三维图形、地理空间、激光点云渲染技术术语解析笔记

三维图形、地理空间、激光点云渲染技术术语解析笔记 code review! 文章目录 三维图形、地理空间、激光点云渲染技术术语解析笔记1. Minecraft风格的方块渲染2. Meshing(网格化)3. Mipmapping(多级纹理映射)4. Marching Cubes&…

从webrtc到janus简介

1.基础知识 1.1 信令的基础知识 在 WebRTC(Web Real-Time Communication) 中,信令(Signaling) 是实现浏览器之间实时通信的关键机制,负责在通信双方(或多方)之间传递控制信息&…

JVM 核心概念深度解析

最近正在复习Java八股,所以会将一些热门的八股问题,结合ai与自身理解写成博客便于记忆 一、JVM内存结构/运行时数据区 JVM运行时数据区主要分为以下几个部分: 程序计数器(PC Register) 线程私有,记录当前线程执行的字节码行号唯…

api将token设置为环境变量

右上角 可以新增或者是修改当前的环境 环境变量增加一个token,云端值和本地值可以不用写 在返回token的接口里设置后执行操作,通常是登录的接口 右侧也有方法提示 //设置环境变量 apt.environment.set("token", response.json.data.token); 在需要传t…

SIFT算法详细原理与应用

SIFT算法详细原理与应用 1 SIFT算法由来 1.1 什么是 SIFT? SIFT,全称为 Scale-Invariant Feature Transform(尺度不变特征变换),是一种用于图像特征检测和描述的经典算法。它通过提取图像中的局部关键点,…

AlphaDrive:通过强化学习和推理释放自动驾驶中 VLM 的力量

AlphaDrive: Unleashing the Power of VLMs in Autonomous Driving via Reinforcement Learning and Reasoning 25年3月来自华中科技大学和地平线的论文 OpenAI 的 o1 和 DeepSeek R1 在数学和科学等复杂领域达到甚至超越了人类专家水平,其中强化学习(R…

【八股消消乐】如何解决SQL线上死锁事故

😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本专栏《八股消消乐》旨在记录个人所背的八股文,包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法等相关知识点&#xff…

如何使用 HTML、CSS 和 JavaScript 随机更改图片颜色

原文:如何使用 HTML、CSS 和 JavaScript 随机更改图片颜色 | w3cschool笔记 (请勿标记为付费!!!!) 在网页开发中,为图片添加动态效果可以显著提升用户体验。今天,我将向…

CAN通信收发测试(USB2CAN模块测试实验)

1.搭建测试环境 电脑:安装 USB 驱动,安装原厂调试工具,安装cangaroo(参考安装包的入门教程即可) USB驱动路径:~\CAN分析仪资料20230701_Linux\硬件驱动程序 原厂调试工具路径:~\CAN分析仪资料2…

OSCP备战-BSides-Vancouver-2018-Workshop靶机详细步骤

一、靶机介绍 靶机地址:https://www.vulnhub.com/entry/bsides-vancouver-2018-workshop%2C231/ 靶机难度:中级(CTF) 靶机发布日期:2018年3月21日 靶机描述: Boot2root挑战旨在创建一个安全的环境&…

PDF转Markdown/JSON软件MinerU最新1.3.12版整合包下载

MinerU发布至今我已经更新多版整合包了,5天前MinerU发布了第一个正式版1.0.1,并且看到在18小时之前有更新模型文件,我就做了个最新版的一键启动整合包。 2025年02月21日更新v1.1.0版整合包 2025年02月27日更新v1.2.0版整合包 2025-06-05 更…

【深入学习Linux】System V共享内存

目录 前言 一、共享内存是什么? 共享内存实现原理 共享内存细节理解 二、接口认识 1.shmget函数——申请共享内存 2.ftok函数——生成key值 再次理解ftok和shmget 1)key与shmid的区别与联系 2)再理解key 3)通过指令查看/释放系统中…

编程基础:执行流

能帮到你的话,就给个赞吧 😘 文章目录 执行流同步:顺序执行,只有一个执行流异步:新开后台(次)执行流,后台执行流要确保不能影响主执行流。共有两个执行流。 阻塞:任务阻塞执行流,导致…

理解非结构化文档:将 Reducto 解析与 Elasticsearch 结合使用

作者:来自 Elastic Adel Wu 演示如何将 Reducto 的文档处理与 Elasticsearch 集成以实现语义搜索。 Elasticsearch 与业界领先的生成式 AI 工具和提供商有原生集成。欢迎观看我们的网络研讨会,了解如何超越 RAG 基础,或使用 Elastic 向量数据…

[面试精选] 0094. 二叉树的中序遍历

文章目录 1. 题目链接2. 题目描述3. 题目示例4. 解题思路5. 题解代码6. 复杂度分析 1. 题目链接 94. 二叉树的中序遍历 - 力扣(LeetCode) 2. 题目描述 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 3. 题目示例 示例 1 : 输入&…