当前位置: 首页 > news >正文

STM32的ADC模块中,**采样时机(Sampling Time)**和**转换时机(Conversion Time),获取数据的时机详解

在STM32的ADC模块中,**采样时机(Sampling Time)转换时机(Conversion Time)**是ADC工作流程中的两个关键阶段,直接影响采样精度和系统实时性。以下是详细解析:


1. 采样时机(Sampling Time)

(1)定义
  • 采样阶段:ADC对输入信号进行保持和稳定的过程。
  • 采样时间:由ADC_SMPRx寄存器配置,决定采样电容充电时间。
(2)配置参数

STM32F103的采样时间可设置为:

typedef enum {ADC_SampleTime_1Cycles5,    // 1.5周期ADC_SampleTime_7Cycles5,    // 7.5周期ADC_SampleTime_13Cycles5,   // 13.5周期ADC_SampleTime_28Cycles5,   // 28.5周期ADC_SampleTime_41Cycles5,   // 41.5周期ADC_SampleTime_55Cycles5,   // 55.5周期ADC_SampleTime_71Cycles5,   // 71.5周期ADC_SampleTime_239Cycles5   // 239.5周期(用于高阻抗信号)
} ADC_SampleTime;
(3)选择原则
信号类型推荐采样时间原因
低阻抗信号1.5~28.5周期信号源阻抗低(如运放输出),快速稳定。
高阻抗信号55.5~239.5周期信号源阻抗高(如温度传感器、分压电路),需更长时间充电。
内部通道≥239.5周期内部温度传感器和VREFINT阻抗极高,必须延长采样时间。
(4)代码示例
// 配置PA0(低阻抗)和温度传感器(高阻抗)
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5);  // 快速采样
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5); // 慢速采样

2. 转换时机(Conversion Time)

(1)定义
  • 转换阶段:ADC核心将采样到的模拟量转换为数字量的过程。
  • 固定耗时:12位分辨率下恒定为12.5个ADC时钟周期(与采样时间无关)。
(2)总转换时间计算

[
T_{total} = (T_{sampling} + 12.5) \times \frac{1}{f_{ADC}}
]

  • 示例
    • ADC时钟 = 14 MHz,采样时间 = 55.5周期
    • 总时间 = (55.5 + 12.5) / 14MHz ≈ 4.86μs
(3)吞吐量限制
  • 理论最大采样率
    [
    f_{max} = \frac{1}{T_{total}}
    ]
    • T_total=4.86μs,则f_max≈205kHz(单通道)。

3. 采样与转换的时序图

采样阶段                       转换阶段
|-------- Sampling Time --------|-- 12.5 Cycles --|
|<----------- Total Conversion Time ------------>|

4. 关键影响因素

(1)ADC时钟频率
  • 最大14MHz(STM32F103),需分频APB2时钟:
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);  // 72MHz/6=12MHz
    
  • 更高时钟 → 更快转换,但可能降低精度。
(2)通道切换延迟
  • 多通道扫描时,每个通道需单独配置采样时间,切换通道会增加额外延迟。
(3)触发方式
  • 硬件触发(如定时器):精确控制采样间隔。
  • 软件触发:灵活性高但时序不易控制。

5. 优化策略

(1)动态调整采样时间

根据信号类型切换采样时间:

void Set_ADC_SampleTime(ADC_TypeDef* ADCx, uint8_t channel, uint8_t isHighImpedance) {ADC_SampleTime time = isHighImpedance ? ADC_SampleTime_239Cycles5 : ADC_SampleTime_28Cycles5;ADC_RegularChannelConfig(ADCx, channel, 1, time);
}
(2)使用注入组中断

高优先级信号通过注入组立即响应:

// 过压时紧急采样
void ADC1_2_IRQHandler(void) {if (ADC_GetITStatus(ADC1, ADC_IT_JEOC)) {uint16_t emergencyData = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);}
}
(3)DMA传输规则组数据

避免CPU轮询,提高效率:

uint16_t adcValues[3];
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adcValues;
ADC_DMACmd(ADC1, ENABLE);

6. 实际应用示例

电机电流监测系统
  • 规则组
    • 通道PA0(电流传感器),采样时间7.5周期(低阻抗)。
    • 定时器触发1kHz采样,DMA传输数据。
  • 注入组
    • 比较器检测过流时触发PA8中断,注入组采集PA1(备份传感器)。
  • 计算总延迟
    • 采样+转换时间 = (7.5 + 12.5) / 14MHz ≈ 1.43μs
    • 1kHz采样率下,CPU负载极低。

总结

  • 采样时机:由信号源阻抗决定,需足够时间稳定信号。
  • 转换时机:固定12.5周期,与ADC时钟频率直接相关。
  • 优化核心:在精度和速度间平衡,优先保证信号完整性。

在STM32的ADC编程中,采样转换数据获取的流程分布在程序的不同位置,具体取决于触发方式(软件/硬件)和数据读取方式(轮询/DMA/中断)。以下是基于STM32F103的详细说明和代码示例:


1. 采样(Sampling)

触发采样的位置
  • 软件触发:在代码中显式调用启动转换函数。
    // 在需要采样的地方(如主循环或定时器回调中)
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // 启动规则组采样
    ADC_SoftwareStartInjectedConv(ADC1);     // 启动注入组采样
    
  • 硬件触发:由定时器、外部中断等自动触发,无需手动调用。
    // 配置TIM2触发规则组采样(无需在主循环中操作)
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
    
采样时间配置

在ADC初始化阶段设置:

// 配置规则组通道的采样时间(在ADC初始化时)
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

2. 转换(Conversion)

转换的触发
  • 转换由硬件自动完成,无需程序干预
  • 转换时间固定为12.5个ADC时钟周期(如14MHz时钟下约0.89μs)。
判断转换完成
  • 轮询方式:检查标志位。
    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));  // 规则组
    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC)); // 注入组
    
  • 中断方式:在中断服务函数中处理。
    void ADC1_2_IRQHandler(void) {if (ADC_GetITStatus(ADC1, ADC_IT_EOC)) {uint16_t data = ADC_GetConversionValue(ADC1);  // 规则组数据ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);}if (ADC_GetITStatus(ADC1, ADC_IT_JEOC)) {uint16_t data = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);}
    }
    

3. 获取数据(Data Readout)

规则组数据
  • 轮询读取
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
    uint16_t adcValue = ADC_GetConversionValue(ADC1);  // 读取规则组数据
    
  • DMA传输(推荐多通道):
    uint16_t adcValues[3];  // 存储3个通道的数据
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adcValues;
    ADC_DMACmd(ADC1, ENABLE);
    // 数据会自动更新到adcValues数组
    
注入组数据
  • 中断读取
    void ADC1_2_IRQHandler(void) {if (ADC_GetITStatus(ADC1, ADC_IT_JEOC)) {uint16_t injData = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);}
    }
    

4. 完整流程示例(规则组+注入组)

初始化配置
void ADC_Init(void) {// 1. 时钟和GPIO初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);// 2. 规则组配置(PA0)ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_Init(ADC1, &ADC_InitStructure);// 3. 注入组配置(PA1)ADC_InjectedChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_Ext_IT15);// 4. 启用中断ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);NVIC_EnableIRQ(ADC1_2_IRQn);// 5. 校准和启动ADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1));
}
主程序中的采样与读取
int main(void) {ADC_Init();while (1) {// 规则组:手动触发并读取ADC_SoftwareStartConvCmd(ADC1, ENABLE);while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));uint16_t regularData = ADC_GetConversionValue(ADC1);// 注入组:由PA8按键触发(中断中自动处理)Delay_ms(100);  // 模拟其他任务}
}
中断服务函数
void ADC1_2_IRQHandler(void) {if (ADC_GetITStatus(ADC1, ADC_IT_JEOC)) {uint16_t injectedData = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);// 处理紧急数据(如过压保护)}
}

5. 关键总结

操作程序位置常用函数/配置
采样触发主循环/定时器回调/中断ADC_SoftwareStartConvCmd()
采样时间ADC初始化阶段ADC_RegularChannelConfig()
转换等待轮询/中断ADC_GetFlagStatus() 或中断标志
数据读取轮询/DMA/中断ADC_GetConversionValue() 或DMA数组
  • 规则组:适合周期性采样,配合DMA提高效率。
  • 注入组:用于紧急事件,中断中即时响应。
  • 硬件触发:精确控制时序,减少CPU干预。

在STM32的ADC配置中,**连续扫描(Scan Mode)连续转换(Continuous Conversion Mode)**是两个关键的工作模式,它们决定了ADC如何对多个通道进行采样和数据更新。以下是详细解释:


1. 连续扫描模式(Scan Mode)

功能
  • 多通道自动切换:ADC按预设顺序依次采样多个通道(规则组或注入组),无需手动切换。
  • 数据存储:需配合DMA或中断将数据存入数组(规则组数据寄存器ADC_DR会被覆盖)。
配置方法
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;  // 启用扫描模式
ADC_InitStructure.ADC_NbrOfChannel = 3;       // 通道数量
ADC_Init(ADC1, &ADC_InitStructure);// 设置通道顺序(规则组)
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // 第1通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5); // 第2通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5); // 第3通道
典型应用
  • 同时监测多个传感器(如温度、电压、电流)。
  • 需配合DMA传输数据:
    uint16_t adcValues[3];  // 存储多通道数据
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adcValues;
    ADC_DMACmd(ADC1, ENABLE);
    

2. 连续转换模式(Continuous Conversion Mode)

功能
  • 自动重启转换:完成一次转换后立即开始下一次,无需手动触发。
  • 单通道/多通道:可与扫描模式组合使用。
配置方法
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  // 启用连续转换
ADC_Init(ADC1, &ADC_InitStructure);
典型应用
  • 实时监控信号变化(如音频采集)。
  • 单通道连续采样示例:
    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // 启动后自动循环采样
    

3. 组合使用场景

模式对比
模式组合行为适用场景
扫描+单次转换按顺序采样所有通道后停止定时触发多通道采样(如每1秒1次)
扫描+连续转换循环采样所有通道,数据持续更新实时多通道监测(如电机控制)
单通道+连续转换重复采样同一通道高速信号捕获(如示波器)
代码示例(扫描+连续转换)
// 初始化ADC(多通道循环采样)
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_NbrOfChannel = 3;
ADC_Init(ADC1, &ADC_InitStructure);// 配置DMA自动传输数据
uint16_t adcValues[3];
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adcValues;
ADC_DMACmd(ADC1, ENABLE);// 启动ADC
ADC_SoftwareStartConvCmd(ADC1, ENABLE);

4. 关键注意事项

  1. 数据覆盖问题

    • 规则组扫描时,ADC_DR寄存器会被新数据覆盖,必须使用DMA或中断及时读取。
  2. 触发源选择

    • 连续转换模式下,硬件触发(如定时器)可精确控制采样间隔。
  3. 功耗权衡

    • 连续转换模式功耗较高,电池供电设备建议使用单次转换+定时触发。
  4. 注入组优先级

    • 即使规则组处于连续转换中,注入组触发仍会立即中断当前转换。

5. 常见问题解答

Q1:扫描模式必须用DMA吗?
A1:不是必须,但强烈推荐。DMA可避免数据丢失,若用中断读取,需确保处理速度够快。

Q2:如何暂停连续转换?
A2:调用ADC_ContinuousConvModeCmd(ADC1, DISABLE),或直接关闭ADC:

ADC_Cmd(ADC1, DISABLE);  // 完全停止ADC

Q3:规则组和注入组能同时用扫描模式吗?
A3:可以!规则组和注入组的扫描相互独立,但注入组会打断规则组当前转换。


总结

  • 扫描模式:解决多通道自动切换问题,需注意数据存储。
  • 连续转换:实现无缝采样,适合实时性要求高的场景。
  • 组合使用:灵活应对复杂需求(如实时监测多个传感器)。

通过合理配置这两种模式,可以充分发挥STM32 ADC的性能。

在STM32的ADC模块中,**连续转换模式(Continuous Conversion Mode)单次转换模式(Single Conversion Mode)**的选择直接影响系统的实时性、功耗和采样精度。以下是针对您提到的两点的详细解释:


1. 连续转换模式 + 硬件触发的精确控制

工作原理
  • 连续转换模式:ADC完成一次转换后,立即自动启动下一次转换,形成不间断的采样循环
  • 硬件触发(如定时器TIM2):通过外部信号(如定时器更新事件)控制ADC的启动时机,实现固定间隔采样。
为何能精确控制采样间隔?
  • 硬件同步:定时器的时钟源稳定(如内部72MHz晶振),触发信号的间隔误差极小(纳秒级)。
  • 规避软件延迟:相比软件触发(需CPU干预),硬件触发完全由外设自动完成,无调度延迟。
配置示例
// 配置TIM2触发ADC(1kHz采样率,即1ms间隔)
TIM_TimeBaseInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_Period = 7200 - 1;  // 72MHz / 7200 = 10kHz
TIM_InitStructure.TIM_Prescaler = 0;
TIM_TimeBaseInit(TIM2, &TIM_InitStructure);
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);  // 更新事件触发ADC// 配置ADC为连续转换+硬件触发
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
ADC_Init(ADC1, &ADC_InitStructure);

效果:ADC以精确的1ms间隔采样,适合需要严格周期性的应用(如数字滤波器、PWM控制)。


2. 连续转换模式的功耗问题

高功耗原因
  • ADC持续工作:连续转换模式下,ADC核心和模拟电路(如采样保持电路)始终处于活动状态,电流消耗较大(STM32F103典型值约1mA@14MHz ADC时钟)。
  • 频繁数据更新:即使无实际信号变化,ADC仍持续转换,浪费功耗。
单次转换+定时触发的低功耗方案
(1)工作流程
  1. 单次转换模式:每次触发后只采样一次,然后自动停止。
  2. 定时器触发:按需唤醒ADC(如每秒1次),其余时间ADC处于低功耗状态。
(2)配置代码
// 配置ADC为单次转换+硬件触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
ADC_Init(ADC1, &ADC_InitStructure);// 配置TIM2低速触发(如1Hz)
TIM_InitStructure.TIM_Period = 72000000 - 1;  // 72MHz / 72000000 = 1Hz
TIM_TimeBaseInit(TIM2, &TIM_InitStructure);
(3)功耗对比
模式平均电流(示例)适用场景
连续转换(1kHz)~1.2mA实时控制、高速信号处理
单次转换+定时(1Hz)~50μA电池供电的传感器监测

3. 如何选择?

选择连续转换模式当:
  • 需要高实时性(如电机控制、音频采样)。
  • 系统供电充足(如插电设备)。
选择单次转换+定时触发当:
  • 设备由电池供电(如IoT传感器)。
  • 信号变化缓慢(如温度、湿度监测)。
折中方案
  • 动态切换模式:根据任务需求灵活调整。
    void Set_ADCMode(uint8_t isHighSpeed) {ADC_ContinuousConvModeCmd(ADC1, isHighSpeed ? ENABLE : DISABLE);TIM_SetAutoreload(TIM2, isHighSpeed ? 7200 - 1 : 72000000 - 1); // 切换采样率
    }
    

4. 实测建议

  • 测量电流:用万用表对比两种模式的功耗差异(注意关闭未用外设)。
  • 唤醒时间:单次模式首次转换可能有额外延迟(需重新校准)。

通过合理选择转换模式,可平衡性能与功耗,满足不同应用场景需求。

在STM32的ADC应用中,定时器触发ADC采样通常不需要在定时器中断服务函数(如TIMx_IRQHandler)中编写代码,而是直接通过定时器的硬件触发输出(如TRGO)自动控制ADC启动。以下是具体说明和代码示例:


1. 硬件触发ADC的配置流程

(1)定时器配置
  • 不依赖中断:仅用定时器的更新事件(UEV)触发ADC,无需进入中断。
  • 关键步骤
    • 设置定时器周期(决定采样间隔)。
    • 配置定时器触发输出(TRGO)。
// 配置TIM2触发ADC(1kHz采样率,72MHz主频)
TIM_TimeBaseInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_Period = 72000 - 1;  // 72000 / 72MHz = 1ms (1kHz)
TIM_InitStructure.TIM_Prescaler = 0;       // 不分频
TIM_InitStructure.TIM_ClockDivision = 0;
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_InitStructure);// 配置TIM2更新事件触发TRGO
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
TIM_Cmd(TIM2, ENABLE);  // 启动定时器
(2)ADC配置
  • 设置为硬件触发模式,选择定时器作为触发源。
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; // TIM2触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次转换模式(推荐低功耗)
ADC_Init(ADC1, &ADC_InitStructure);

2. 何时需要定时器中断?

如果需要在定时器事件中执行其他任务(如数据处理、状态检查),才需启用中断。此时需:

(1)启用定时器中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // 允许更新中断
NVIC_EnableIRQ(TIM2_IRQn);                 // 启用NVIC中断
(2)中断服务函数示例
void TIM2_IRQHandler(void) {if (TIM_GetITStatus(TIM2, TIM_IT_Update)) {// 此处可添加其他任务(如读取ADC数据、控制逻辑)// 注意:ADC采样已由硬件自动触发,无需在此启动!TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  // 清除中断标志}
}

3. 完整代码示例(无中断方案)

目标:用TIM2以1kHz触发ADC采样,DMA传输数据。
#include "stm32f10x.h"uint16_t adcValue;  // 存储ADC数据void ADC_TIM_Config(void) {// 1. 启动时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);// 2. 配置GPIO(PA0为ADC输入)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);// 3. 配置TIM2(1kHz触发)TIM_TimeBaseInitTypeDef TIM_InitStructure;TIM_InitStructure.TIM_Period = 72000 - 1;  // 1ms间隔TIM_InitStructure.TIM_Prescaler = 0;TIM_TimeBaseInit(TIM2, &TIM_InitStructure);TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);  // 更新事件触发ADCTIM_Cmd(TIM2, ENABLE);// 4. 配置ADC1(单次转换+定时器触发)ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次转换ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);// 5. 配置ADC通道ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);// 6. 启用ADCADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1));
}int main(void) {ADC_TIM_Config();while (1) {// 数据通过DMA或中断自动更新(此处为轮询示例)if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)) {adcValue = ADC_GetConversionValue(ADC1);ADC_ClearFlag(ADC1, ADC_FLAG_EOC);}}
}

4. 关键注意事项

  1. 无需中断触发ADC:硬件触发本身不需要CPU干预,直接由定时器信号启动ADC。
  2. 中断的用途:仅当需要在定时器事件中执行额外逻辑(如数据处理、状态机更新)时才启用中断。
  3. DMA推荐:高频采样时,务必使用DMA传输数据,避免CPU轮询开销。

总结

  • 纯硬件触发:配置定时器TRGO + ADC外部触发,无需中断,效率最高。
  • 中断的适用场景:同步执行其他任务(如报警检查、数据打包)。
  • 低功耗设计:单次转换模式 + 定时器触发,适合电池供电设备。
    在STM32的ADC应用中,定时器触发的是ADC的启动时机,即控制何时开始一次完整的“采样+转换”过程。以下是关键概念的分步解释和代码实现:

1. 定时器触发的本质

  • 触发的内容:定时器触发的是ADC的完整转换流程,包括:
    1. 采样阶段(Sampling Phase):ADC对输入信号进行采样保持(时间由ADC_SampleTime决定)。
    2. 转换阶段(Conversion Phase):ADC将采样值转换为数字量(固定12.5个ADC时钟周期)。
  • 定时器的作用:精确控制每次“采样+转换”的启动时刻,而非单独控制采样或转换。

2. 数据获取的位置

(1)DMA自动传输(推荐方式)
  • 配置步骤
    uint16_t adcValue;  // 存储ADC数据// 启用ADC DMA
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adcValue;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 1;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    ADC_DMACmd(ADC1, ENABLE);
    
  • 数据获取
    定时器触发ADC后,转换结果会自动通过DMA传输到adcValue变量,无需程序干预
(2)中断中读取
  • 配置步骤
    // 启用ADC转换完成中断
    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
    NVIC_EnableIRQ(ADC1_2_IRQn);// 中断服务函数
    void ADC1_2_IRQHandler(void) {if (ADC_GetITStatus(ADC1, ADC_IT_EOC)) {adcValue = ADC_GetConversionValue(ADC1);ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);}
    }
    
  • 数据获取
    每次转换完成后,在中断中读取ADC_DR寄存器。
(3)轮询方式(低效,仅用于测试)
// 主循环中等待转换完成
while (1) {ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // 定时器触发时无需此句while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));adcValue = ADC_GetConversionValue(ADC1);
}

3. 完整代码示例(定时器触发+DMA)

目标:TIM2以1kHz触发ADC1采样PA0,DMA自动传输数据。
#include "stm32f10x.h"uint16_t adcValue;  // 存储ADC数据void ADC_Config(void) {// 1. 启用时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 2. 配置PA0为模拟输入GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);// 3. 配置TIM2(1kHz触发)TIM_TimeBaseInitTypeDef TIM_InitStructure;TIM_InitStructure.TIM_Period = 72000 - 1;  // 72MHz / 72000 = 1kHzTIM_InitStructure.TIM_Prescaler = 0;TIM_TimeBaseInit(TIM2, &TIM_InitStructure);TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);  // 更新事件触发ADCTIM_Cmd(TIM2, ENABLE);// 4. 配置DMADMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adcValue;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 1;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  // 循环模式DMA_Init(DMA1_Channel1, &DMA_InitStructure);DMA_Cmd(DMA1_Channel1, ENABLE);// 5. 配置ADCADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次转换ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);// 6. 配置ADC通道ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);// 7. 启用ADC和DMAADC_DMACmd(ADC1, ENABLE);ADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1));
}int main(void) {ADC_Config();while (1) {// adcValue已通过DMA自动更新,可直接使用float voltage = adcValue * 3.3f / 4095;  // 转换为电压值}
}

4. 关键总结

问题答案
定时器触发的内容触发完整的ADC转换流程(采样+转换)
采样时刻控制由定时器的触发信号决定
数据获取位置DMA自动传输到变量 / 中断中读取 / 轮询ADC_DR寄存器
最优方案定时器硬件触发 + DMA传输(无CPU干预,高效低功耗)

通过这种方式,STM32可以实现精确的定时采样,同时最小化CPU负载。

在STM32的ADC应用中,定时器触发ADC采样时,选择单次转换模式(Single Conversion)还是连续转换模式(Continuous Conversion),取决于具体的应用场景和需求。以下是两者的对比分析和配置建议:


1. 单次转换模式(Single Conversion)

特点
  • 工作流程
    每次定时器触发后,ADC执行一次完整的采样+转换,然后自动停止,等待下一次触发。
  • 功耗:较低(仅在触发时激活ADC)。
  • 数据更新:每次触发后数据更新一次。
适用场景
  • 低频采样:如温度监测(每秒几次)。
  • 电池供电设备:需要最小化功耗。
  • 事件触发采样:如按键按下后采集一次数据。
配置代码
// ADC初始化配置
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; // TIM2触发
ADC_Init(ADC1, &ADC_InitStructure);// 启动ADC(首次启动后,后续由定时器自动触发)
ADC_SoftwareStartConvCmd(ADC1, ENABLE);

2. 连续转换模式(Continuous Conversion)

特点
  • 工作流程
    定时器首次触发后,ADC持续循环执行采样+转换,直到手动停止。
    (注:在硬件触发下,连续转换模式仍依赖定时器的周期性触发。)
  • 功耗:较高(ADC持续运行)。
  • 数据更新:数据持续刷新,速率由定时器触发频率决定。
适用场景
  • 高频实时采样:如音频信号处理(>1kHz)。
  • 控制环路:如电机PID控制,需要严格周期性的数据更新。
  • 多通道扫描:配合DMA实现无缝数据流。
配置代码
// ADC初始化配置
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  // 连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; // TIM2触发
ADC_Init(ADC1, &ADC_InitStructure);// 启动ADC(首次启动后,ADC会持续运行,但每次转换仍由定时器触发)
ADC_SoftwareStartConvCmd(ADC1, ENABLE);

3. 关键区别与选择建议

特性单次转换模式连续转换模式
触发后行为采样一次后停止持续采样,直到手动停止
功耗低(适合电池供电)高(适合持续供电场景)
数据更新频率由定时器触发频率决定由定时器触发频率决定
硬件资源占用ADC间歇工作ADC持续占用
典型应用温度传感器、低速监测电机控制、音频采集
选择原则
  1. 单次转换模式

    • 需要低功耗非连续采样时使用。
    • 即使定时器触发频率很高(如1kHz),每次触发仍只采样一次。
  2. 连续转换模式

    • 需要无缝数据流严格实时性时使用。
    • 注意:在硬件触发下,连续转换模式的实际采样率仍由定时器决定,但ADC核心会保持活跃状态。

4. 常见问题解答

Q1:连续转换模式下,定时器触发还有意义吗?
  • 有意义!连续转换模式只是保持ADC核心处于工作状态,但每次转换的启动时刻仍由定时器精确控制。
  • 若禁用硬件触发(如用软件触发),ADC会以最大速度连续采样(不推荐,可能丢失时序精度)。
Q2:单次模式是否会漏掉定时器触发信号?
  • 不会。每次定时器触发都会启动一次新的转换,即使前一次转换已完成。
  • 但需确保两次触发的间隔大于单次转换的总时间(采样时间 + 12.5周期)。
Q3:如何动态切换模式?
// 运行时切换为单次模式
ADC_ContinuousConvModeCmd(ADC1, DISABLE);// 运行时切换为连续模式
ADC_ContinuousConvModeCmd(ADC1, ENABLE);

5. 完整示例(单次转换 + 定时器触发 + DMA)

#include "stm32f10x.h"uint16_t adcValue;void ADC_Config(void) {// 1. 启用时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 2. 配置PA0为模拟输入GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);// 3. 配置TIM2(100Hz触发)TIM_TimeBaseInitTypeDef TIM_InitStructure;TIM_InitStructure.TIM_Period = 720000 - 1;  // 72MHz / 720000 = 100HzTIM_InitStructure.TIM_Prescaler = 0;TIM_TimeBaseInit(TIM2, &TIM_InitStructure);TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);  // 更新事件触发ADCTIM_Cmd(TIM2, ENABLE);// 4. 配置DMA(单次传输)DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adcValue;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 1;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  // 循环模式DMA_Init(DMA1_Channel1, &DMA_InitStructure);DMA_Cmd(DMA1_Channel1, ENABLE);// 5. 配置ADC(单次转换 + TIM2触发)ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次模式ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);// 6. 配置ADC通道ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);// 7. 启用ADC和DMAADC_DMACmd(ADC1, ENABLE);ADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1));
}int main(void) {ADC_Config();while (1) {// adcValue每10ms自动更新一次(由TIM2触发)float voltage = adcValue * 3.3f / 4095;}
}

总结

  • 单次转换模式:节能,适合低频或事件触发场景。
  • 连续转换模式:实时性强,适合高频或控制环路。
  • 硬件触发:无论哪种模式,定时器均可精确控制采样间隔。
  • 推荐组合
    • 低功耗应用:单次转换 + 定时器触发 + DMA。
    • 实时控制:连续转换 + 定时器触发 + DMA。

相关文章:

STM32的ADC模块中,**采样时机(Sampling Time)**和**转换时机(Conversion Time),获取数据的时机详解

在STM32的ADC模块中&#xff0c;**采样时机&#xff08;Sampling Time&#xff09;和转换时机&#xff08;Conversion Time&#xff09;**是ADC工作流程中的两个关键阶段&#xff0c;直接影响采样精度和系统实时性。以下是详细解析&#xff1a; 1. 采样时机&#xff08;Samplin…...

iOS音视频解封装分析

首先是进行解封装的简单的配置 /// 解封装配置 class KFDemuxerConfig {// 媒体资源var asset: AVAsset?// 解封装类型&#xff0c;指定是音频、视频或两者都需要var demuxerType: KFMediaType .avinit() {} }然后是实现解封装控制器 import Foundation import CoreMedia i…...

探究电阻分压的带负载能力

我们经常使用两个电阻去分压来获得特定的电压,那么我是两个大阻值电阻分压获得的电压驱动能力强,还是小阻值电阻分压得到的电压驱动能力强呢? 一、电压相同时,电流的大小 下面是两个阻值分压得到的仿真图 电路分析: VCC都是5V,探针1和探针2测到的电压都是1.67V; 根据…...

14、Python时间表示:Unix时间戳、毫秒微秒精度与time模块实战

适合人群&#xff1a;零基础自学者 | 编程小白快速入门 阅读时长&#xff1a;约5分钟 文章目录 一、问题&#xff1a;计算机中的时间的表示、Unix时间点&#xff1f;1、例子1&#xff1a;计算机的“生日”&#xff1a;Unix时间点2、答案&#xff1a;&#xff08;1&#xff09;U…...

PCL 绘制二次曲面

文章目录 一、简介二、实现代码三、实现效果一、简介 这里基于二次曲面的公式: z = a 0 + a 1 x + a 2 y + a...

消息队列与Kafka基础:从概念到集群部署

目录 一、消息队列 1.什么是消息队列 2.消息队列的特征 3.为什么需要消息队列 二、Kafka基础与入门 1.Kafka基本概念 2.Kafka相关术语 3.Kafka拓扑架构 4.Topic与partition 5.Producer生产机制 6.Consumer消费机制 三、Zookeeper概念介绍 1.zookeeper概述 2.zooke…...

计算机指令分类和具体的表示的方式

1.关于计算机的指令系统 下面的这个就是我们的一个简单的计算机里面涉及到的指令&#xff1a; m就是我们的存储器里面的地址&#xff0c;可以理解为memory这个意思&#xff0c;r可以理解为rom这样的单词的首字母&#xff0c;帮助我们去进行这个相关的指令的记忆&#xff0c;不…...

pcie phy-电气层-gen1/2(TX)

S IP物理层讲解 在synopsys IP中对于phy层的内容分离的比较多&#xff1a; cxpl中&#xff1a; u_cx_phy_logical&#xff1a;包含ts序列的解析&#xff08;smlh&#xff09;&#xff1b; pipe层协议的转换&#xff08;rmlh,xmlh)&#xff1b;pipe转dllp包&#xff08;rplh&…...

Baklib加速企业AI数据智理转型

Baklib智理AI数据资产 在AI技术深度渗透业务场景的背景下&#xff0c;Baklib通过构建企业级知识中台架构&#xff0c;重塑了数据资产的治理范式。该平台采用智能分类引擎与语义分析模型&#xff0c;将分散在邮件、文档、数据库中的非结构化数据转化为标准化的知识单元&#xf…...

深度学习驱动下的目标检测技术:原理、算法与应用创新

一、引言​ 1.1 研究背景与意义​ 目标检测作为计算机视觉领域的核心任务之一&#xff0c;旨在识别图像或视频中感兴趣目标的类别&#xff0c;并确定其在图像中的位置&#xff0c;通常以边界框&#xff08;Bounding Box&#xff09;的形式表示 。其在现实生活中有着极为广泛且…...

window 显示驱动开发-使用有保证的协定 DMA 缓冲区模型

Windows Vista 的显示驱动程序模型保证呈现设备的 DMA 缓冲区和修补程序位置列表的大小。 修补程序位置列表包含 DMA 缓冲区中命令引用的资源的物理内存地址。 在有保证的协定模式下&#xff0c;用户模式显示驱动程序知道 DMA 缓冲区和修补程序位置列表的确切大小&#xff0c;…...

《指针与整数相加减的深入解析》

&#x1f680;个人主页&#xff1a;BabyZZの秘密日记 &#x1f4d6;收入专栏&#xff1a;C语言 &#x1f30d;文章目入 一、指针与整数相加的原理二、指针与整数相减的原理三、使用场景&#xff08;一&#xff09;数组操作&#xff08;二&#xff09;内存遍历 四、注意事项&…...

C++_STL_map与set

1. 关联式容器 在初阶阶段&#xff0c;我们已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector、list、deque、 forward_list(C11)等&#xff0c;这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面 存储的是元素本身。那什么是…...

1949-2022年各省农作物播种面积数据(22个指标)

1949-2022年各省农作物播种面积数据&#xff08;22个指标&#xff09; 1、时间&#xff1a;1949-2022年 2、来源&#xff1a;各省年鉴、国家统计局、农业部、农业年鉴 3、范围&#xff1a;31省 4、指标&#xff1a;年度标识、省份编码、省份名称、农作物总播种面积、粮食作…...

汽车二自由度系统模型以及电动助力转向系统模型

汽车二自由度系统模型与电动助力转向系统&#xff08;EPS&#xff09;的详细建模方案&#xff0c;包含理论推导、MATLAB/Simulink实现代码及参数说明&#xff1a; 一、二自由度汽车模型 1. 模型描述 包含以下两个自由度&#xff1a; 横向运动&#xff08;侧向加速度&#xf…...

【学习笔记】计算机操作系统(四)—— 存储器管理

第四章 存储器管理 文章目录 第四章 存储器管理4.1 存储器的层次结构4.1.1 多层结构的存储器系统4.1.2 主存储器与寄存器4.1.3 高速缓存和磁盘缓存 4.2 程序的装入和链接4.2.1 程序的装入4.2.2 程序的链接 4.3 连续分配存储管理方式4.3.1 单一连续分配4.3.2 固定分区分配4.3.3 …...

51单片机的lcd12864驱动程序

#include <reg51.h> #include <intrins.h>#define uchar...

(03)数字化转型之库存管理:从进库到出库的数字化运营

在当今竞争激烈的商业环境中&#xff0c;高效的库存管理已成为企业降低成本、提高运营效率的关键。本文将系统性地介绍库存管理的全流程&#xff0c;包括进库、出库、移库、盘点等核心环节&#xff0c;帮助企业构建科学合理的库存管理体系。 一、进库管理&#xff1a;从计划到执…...

windows编程中加载DLL的两种典型方式的比较

文章目录 DLL定义头文件定义CPP实现DLL的调用代码直接使用通过LoadLibrary调用导入表的依赖LoadLibrary使用DLL库中的类DLL中定义工厂函数调用时的代码补充:为什么LoadLibrary不能直接导出类在windows的编程中,使用DLL是一个非常常见的操作。一般来说,有两种集成DLL的方式:…...

存储器上如何存储1和0

在计算机存储器中&#xff0c;数据最终以**二进制形式&#xff08;0和1&#xff09;**存储&#xff0c;这是由硬件特性和电子电路的物理特性决定的。以下是具体存储方式的详细解析&#xff1a; 一、存储的物理基础&#xff1a;半导体电路与电平信号 计算机存储器&#xff08;…...

【笔记】记一次PyCharm的问题反馈

#工作记录 最近更新至 PyCharm 社区版的最新版本后&#xff0c;我遇到了多个影响使用体验的问题。令人感到不便的是&#xff0c;一些在旧版本中非常便捷的功能&#xff0c;在新版本中却变得操作复杂、不够直观。过去&#xff0c;我一直通过 PyCharm 内置的故障报告与反馈机制反…...

logrotate按文件大小进行日志切割

✅ 编写logrotate文件&#xff0c;进行自定义切割方式 adminip-127-0-0-1:/data/test$ cat /etc/logrotate.d/test /data/test/test.log {size 1024M #文件达到1G就切割rotate 100 #保留100个文件compressdelaycompressmissingoknotifemptycopytruncate #这个情况服务不用…...

基于大模型的脑出血智能诊疗与康复技术方案

目录 一、术前阶段1.1 数据采集与预处理系统伪代码实现流程图1.2 特征提取与选择模块伪代码实现流程图1.3 大模型风险评估系统伪代码实现流程图二、术中阶段2.1 智能手术规划系统伪代码实现流程图2.2 麻醉智能监控系统伪代码实现流程图三、术后阶段3.1 并发症预测系统伪代码片段…...

P21-RNN-心脏病预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、RNN 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;简称 RNN&#xff09;是一类以序列数据为输入&#xff0c;在序列的演进方向进行递归…...

懒汉式单例模式的线程安全实现

懒汉式单例模式的线程安全实现 懒汉式单例模式的核心特点是延迟实例化(在第一次使用时创建对象),但其基础实现存在线程安全问题。以下是不同线程安全实现方式的详细说明和对比: 1. 非线程安全的基础懒汉式 public class UnsafeLazySingleton {private static UnsafeLazyS…...

Java 常用的Arrays函数

文章目录 ArrayssorttoStringbinarySearchequalsfill 数组拷贝copyOfcopyOfRangearraycopy 二维数组定义遍历deepToString空指针异常 Arrays sort int[] array new int[]{1,20,3}; Arrays.sort(array);// 1 3 20toString 帮助数组转为字符串 int[] array new int[]{1,2,3…...

FEKO许可证与版本兼容性问题

随着电磁仿真技术的不断进步&#xff0c;FEKO软件不断更新迭代&#xff0c;为用户提供更强大的功能和更优秀的性能。然而&#xff0c;在升级过程中&#xff0c;FEKO许可证与版本兼容性问题往往成为用户关注的焦点。本文将为您详细解读FEKO许可证与版本兼容性问题&#xff0c;帮…...

HarmonyOs开发之——— ArkWeb 实战指南

HarmonyOs开发之——— ArkWeb 实战指南 谢谢关注!! 前言:上一篇文章主要介绍HarmonyOs开发之———合理使用动画与转场:CSDN 博客链接 一、ArkWeb 组件基础与生命周期管理 1.1 Web 组件核心能力概述 ArkWeb 的Web组件支持加载本地或在线网页,提供完整的生命周期回调体…...

冰箱磁力贴认证标准16CFR1262

在亚马逊平台&#xff0c;冰箱磁力贴这类可能被儿童接触到的产品&#xff0c;有着严格的规范哦。必须得遵守 16 CFR 1262 标准&#xff0c;还得有符合该标准的测试报告和 GCC 证书&#xff0c;不然产品就可能被禁止销售或者面临召回&#xff0c;那可就损失大啦&#xff01; ​ …...

Java中的锁机制全解析:从synchronized到分布式锁

在多线程编程中&#xff0c;锁是保证线程安全的核心工具。本文将详解Java中常见的锁机制及其实际应用场景&#xff0c;帮助开发者选择最合适的锁方案。 一、内置锁&#xff1a;synchronized 原理 通过JVM内置的监视器锁&#xff08;Monitor&#xff09;实现&#xff0c;可修…...

OptiStruct实例:3D实体转子分析

上一节介绍了1D转子的临界转速分析。在1D转子模型中&#xff0c;转子是以集中质量单元的形式建模的。此种建模方法不可避免地会带来一些简化和局部特征的缺失。接下来介绍OptiStruct3D实体转子的建模及临界转速分析实例。 3D实体转子建立详细的转子网格模型&#xff0c;然后将…...

简单记录坐标变换

以三维空间坐标系为例 rTt代表机械手末端相对robot root坐标系的变换关系 rTt dot p_in_tool 可以把tool坐标系下表示的某点转到root坐标系表示 其中rTt表示tool相对于root坐标系的平移和旋转 以二维图像坐标系为例说明 1坐标系定为图片坐标系左上角&#xff0c;横平竖直的…...

自定义快捷键软件:AutoHotkey 高效的快捷键执行脚本软件

AutoHotkey 是一种适用于 Windows 的免费开源脚本语言&#xff0c;它允许用户轻松创建从小型到复杂的脚本&#xff0c;用于各种任务&#xff0c;例如&#xff1a;表单填充、自动点击、宏等。 定义鼠标和键盘的热键&#xff0c;重新映射按键或按钮&#xff0c;并进行类似自动更…...

【Android构建系统】了解Soong构建系统

背景介绍 在Android7.0之前&#xff0c;Android使用GNU Make描述和执行build规则。Android7.0引入了Soong构建系统&#xff0c;弥补Make构建系统在Android层面变慢、容易出错、无法扩展且难以测试等缺点。 Soong利用Kati GNU Make克隆工具和Ninja构建系统组件来加速Android的…...

显性知识的主要特征

有4个主要特征&#xff1a; 客观存在性静态存在性可共享性认知元能性...

STM32F407VET6实战:CRC校验

CRC校验在数据传输快&#xff0c;且量大的时候使用。下面是STM32F407VET6HAL库使用CRC校验的思路。 步骤实现&#xff1a; CubeMX配置 c // 在CubeMX中启用CRC模块 // AHB总线时钟自动启用 HAL库代码 c // 初始化&#xff08;main函数中&#xff09; CRC_HandleTypeDef …...

LeetCode 746 使用最小花费爬楼梯

当然可以&#xff01;LeetCode 746 是一道经典的动态规划入门题&#xff0c;我来用 C 为你详细解释。 题目描述 给定一个整数数组 cost&#xff0c;其中每个元素 cost[i] 表示从第 i 个台阶向上爬需要支付的费用。一旦支付费用&#xff0c;你可以选择向上爬 1 步 或 2 步。 你…...

隧道结构安全在线监测系统解决方案

一、方案背景 隧道是地下隐蔽工程&#xff0c;会受到潜在、无法预知的地质因素影响。随着我国公路交通建设的发展&#xff0c;隧道占新建公路里程的比例越来越大。隧道属于线状工程&#xff0c;有的规模较大&#xff0c;可长达几公里或数十公里&#xff0c;往往穿越许多不同环境…...

牛客网NC22000:数字反转之-三位数

牛客网NC22000:数字反转之-三位数 &#x1f50d; 题目描述 时间限制&#xff1a;C/C/Rust/Pascal 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C/Rust/Pascal 32M&#xff0c;其他语言64M &#x1f4dd; 输入输出说明 输入描述: 输入一个3位整数n (100 ≤ n ≤ 999)…...

等离子模块【杀菌消毒】

图片来源于网络&#xff0c;与任何公司或实验室无关。 洗衣机中的等离子模块&#xff0c;又叫等离子杀菌模块或等离子发生器&#xff0c;是一种利用等离子体技术进行杀菌消毒、除异味、净化空气的部件。 输出正高压&#xff1a;3.0KV~4.0KV 输出负高压&#xff1a;-3.…...

LlamaIndex 第九篇 Indexing索引

索引概述 数据加载完成后&#xff0c;您将获得一个文档对象(Document)列表&#xff08;或节点(Node)列表&#xff09;。接下来需要为这些对象构建索引(Index)&#xff0c;以便开始执行查询。 索引&#xff08;Index&#xff09; 是一种数据结构&#xff0c;能够让我们快速检索…...

PCIe Switch 问题点

系列文章目录 文章目录 系列文章目录完善PCIe Retimer Overview Document OutlineSwitch 维度BroadComMicroChipAsmedia 祥硕Cyan其他 完善 Functional block diagram&#xff0c;功能框图Key Features and Benefits&#xff0c;主要功能和优点Fabric 链路Multi-root PCIe Re…...

Linux》Ubuntu》安装Harbor 私有仓库

Harbor 下载Harbor地址 # 下载测试镜像 docker pull hello-world# 给镜像重新打标签 docker tag hello-world serverip/library/hello-world:latest# 登录进行上传 docker login serverip docker push serverip/library/hello-world:latest...

2025 Adobe Acrobat DC安装教程

Adobe Acrobat DC是由Adobe公司开发的一款PDF编辑软件&#xff0c;具有将各种文件扫描至PDF、转换PDF文档&#xff1b;编辑PDF、将PDF转换为Word、Excel、打印PDF&#xff1b;创建富媒体PDF文件等功能。 一.软件下载 点此下载 https://pan.xunlei.com/s/VOQDq6Tk1KUFmyCw9M1E…...

第八节第三部分:认识枚举、枚举的作用和应用场景

认识枚举 枚举的概述 枚举的特点 枚举的应用场景 代码&#xff1a; 代码一&#xff1a;认识枚举 A&#xff08;枚举&#xff09; package com.d6_enum;public enum A {//注意&#xff1a;枚举类的第一行必须罗列的是枚举对象的名字X,Y,Z;private String name;public String…...

WEB安全--Java安全--shiro721反序列化漏洞

一、前言 既然我把shiro721和shiro550分开写&#xff0c;就说明两者是有区别的 不过两者的概念和作用也是大相径庭的&#xff0c;这里就不再赘述 可以参考上一篇文章&#xff1a; WEB安全--Java安全--shiro550反序列化漏洞-CSDN博客 二、shiro721 2.1、原理 区别于shiro5…...

[Lc] 5.16 One question a day周总结

感受&#xff1a; 一个数据结构 表示不了&#xff0c;那就再用一个数据结构来帮助标识 逻辑清晰的分析出过程 就一定能写出来~ dp 逆构 依照上述 3 个条件&#xff0c;筛选字符串即可 历程 最开始一眼dp&#xff0c;后来发现要return string&#xff0c;看数据也不是很大&…...

【数据机构】2. 线性表之“链表”

- 第 97 篇 - Date: 2025 - 05 - 16 Author: 郑龙浩/仟墨 【数据结构 2】 续上一篇 线性表之“顺序表” 文章目录 3 链表(用指针来首位相连)① 基本介绍② 分类 与 变量命名1 &#xff09;分类&#xff1a;2 &#xff09;大体介绍不同结构&#xff1a; ③ “单链表” 的实现:*…...

《数字藏品APP开发:解锁高效用户身份认证与KYC流程》

开发一款数字藏品APP&#xff0c;要面对诸多复杂且关键的环节&#xff0c;其中&#xff0c;实现高效的用户身份认证与KYC&#xff08;了解你的客户&#xff09;流程&#xff0c;无疑是重中之重。这不仅关乎用户资产安全与平台合规运营&#xff0c;更是构建用户信任、保障平台可…...

问题 | 国内外软件定义卫星最新进展研究

软件定义卫星 **一、国内进展****二、国际进展****三、未来发展方向****总结** 软件定义卫星&#xff08;Software-Defined Satellite, SDS&#xff09;作为航天领域的重要技术革新方向&#xff0c;近年来在全球范围内发展迅速。其核心是通过开放式架构和动态软件配置实现卫星功…...