只能说拖延没有什么好结果,欠下的债总是要还的。
ADC
模拟信号转化为数字信号,例如温度传感器将外部温度的变化(模拟信号),转换为内部电压的变化(数字信号)
IN是八路输入,下方是选择输入端,ALE是锁使能,DAC是数字信号,通过与模拟信号在比较器的比较,通过SAR的调整逐步逼近,最终生成八位输出
这里推荐大家在复习的时候借助ai啊,这样比再去视频里找效率高的多
1. 输入通道与选择
- 外部模拟输入:
ADCx_IN0 ~ ADCx_IN15
,共 16 路外部引脚,可接传感器等模拟信号。 - 内部模拟信号:
- 温度传感器:内置温度传感器的模拟输出(用于采集芯片温度)。
- V_REFINT:内部参考电压(稳定的基准电压,可用于校准或辅助测量)。
2. 转换触发控制
ADC 转换可通过 软件触发 或 硬件触发 启动,硬件触发支持灵活的外部 / 定时器同步:
- 注入组触发(JEXTTRIG):
- 触发源由
JEXTSEL[2:0]
配置,可选TIM1_TRGO
、TIM8_CH4
等定时器触发输出,或外部引脚EXTI_15
。 - 用于紧急场景(如突发信号优先采集)。
- 触发源由
- 规则组触发(EXTTRIG):
- 触发源由
EXTSEL[2:0]
配置,可选TIM1_CH1
、TIM2_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 发送中断请求(用于异常监测,如电压超限报警)。
- 若超出范围,触发 AWD 标志位,结合
- 转换结束中断:
- EOC(规则转换结束):规则通道转换完成标志,
EOCIE
使能后触发中断。 - JEOC(注入转换结束):注入通道转换完成标志,
JEOCIE
使能后触发中断。
- EOC(规则转换结束):规则通道转换完成标志,
四种转换模式
单次转换:每次只转换序列一
非扫描模式:每次转换后停止
因为只支持12位,但用16位储存需要选择对齐模式
- 采样:指对模拟信号按一定时间间隔进行取值,获取模拟信号在离散时间点上的瞬时值,就像每隔固定时间给模拟信号拍张 “快照”。例如对一个随时间连续变化的电压信号,每隔 0.01 秒记录一次其电压值。
- 保持:将采样得到的瞬时值在一段时间内维持不变,以便后续的量化和编码处理。相当于把 “快照” 固定住,使其在后续操作中有稳定的数值。比如采样得到一个电压值后,在完成量化编码前,让这个电压值保持恒定。
- 量化:把采样保持后的信号幅值按一定的量化等级进行划分,将其变为离散的数字量。例如将 0 - 5V 的电压范围划分为 10 个量化等级,每个等级 0.5V,采样得到的电压值就根据所处范围对应到相应量化等级。
- 编码:将量化后的结果用二进制代码等特定代码形式表示出来,最终得到数字信号。比如量化后的结果是第 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天把剩余的学完,整天都得按在椅子上了....