从轮询到DMA:STM32F030多通道ADC的三种实现方式对比

STM32F030C8T6(ADC DMA方式)7路检测 STM32F030C8T6 7路ADC检测 DMA方式 阅读详情

从轮询到DMA:STM32F030多通道ADC的三种实现方式对比

在嵌入式系统开发中,模拟信号采集是连接物理世界与数字世界的桥梁。对于使用STM32F030这类Cortex-M0内核微控制器的开发者来说,ADC(模数转换器)的多通道采集效率直接影响到整个系统的实时性和响应能力。我曾在多个工业传感器项目中,面对过采样率不足导致数据丢失的窘境,也经历过从简单轮询到高效DMA方案的完整技术演进路径。

STM32F030的ADC模块虽然不如高端型号功能丰富,但其12位精度、最高1Msps的采样率以及多通道扫描能力,足以应对大多数中低速应用场景。关键在于如何根据项目需求,在软件轮询、中断模式和DMA传输这三种经典实现方式中做出明智选择。每种方案背后都涉及CPU占用率、代码复杂度、实时性保证和功耗控制等多维度权衡,而不仅仅是技术实现的差异。

本文将深入剖析这三种方案的实现细节、性能表现和适用场景,结合具体代码示例和实际调试经验,帮助你构建清晰的选型思路。无论你是刚接触STM32的新手,还是寻求性能优化的资深工程师,都能从中找到实用的技术见解。

1. 基础概念与硬件配置要点

在深入三种实现方式之前,我们需要先理解STM32F030 ADC模块的几个核心概念。这些基础知识决定了后续方案设计的边界条件。

1.1 ADC工作模式与触发机制

STM32F030的ADC支持多种工作模式,对于多通道采集来说,扫描模式(Scan Mode)和连续转换模式(Continuous Conversion Mode)是最常用的组合。扫描模式允许ADC自动按预设顺序转换多个通道,而连续模式则让转换在完成后自动重新开始,形成不间断的数据流。

触发方式的选择同样关键:

  • 软件触发:通过设置ADC_CR2寄存器的SWSTART位或调用HAL_ADC_Start()启动转换
  • 硬件触发:可由定时器、外部引脚等事件自动触发,实现精确的定时采样
// STM32Cube HAL库中的ADC初始化结构体关键配置
ADC_HandleTypeDef hadc;
hadc.Instance = ADC1;
hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;          // 启用扫描模式
hadc.Init.ContinuousConvMode = ENABLE;             // 启用连续转换
hadc.Init.DiscontinuousConvMode = DISABLE;         // 禁用间断模式
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;   // 软件触发
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;         // 数据右对齐
hadc.Init.NbrOfConversion = 3;                     // 转换通道数

注意:STM32F030的ADC时钟最大为14MHz,实际配置时需要根据系统时钟分频。过高的ADC时钟可能导致精度下降,而过低则影响采样率。

1.2 多通道配置与采样时间

多通道ADC配置的核心在于转换序列的设置。每个通道的转换顺序和采样时间都需要仔细规划,特别是当各通道信号源阻抗不同时。

通道 GPIO引脚 采样时间(周期) 转换顺序 适用场景
CH0 PA0 239.5 1 高阻抗传感器
CH1 PA1 71.5 2 低阻抗电压监测
CH2 PA2 28.5 3 快速变化信号
CH3 PA3 13.5 4 内部温度传感器

采样时间的计算公式为:

总转换时间 = 采样时间 + 12.5个ADC时钟周期

例如,当ADC时钟为14MHz,采样时间设为239.5周期时:

总时间 = (239.5 + 12.5) / 14MHz ≈ 18μs

这意味着每个通道的转换需要约18微秒,三个通道的完整扫描周期约为54微秒,理论最大采样率约18.5kSPS。

1.3 数据对齐与校准

STM32F030的ADC转换结果支持左对齐和右对齐两种格式。12位ADC的结果通常存储在16位寄存器中,对齐方式影响数据处理:

// 右对齐时直接读取低12位
uint16_t raw_value = ADC1->DR & 0x0FFF;

// 左对齐时需要右移4位
uint16_t raw_value = (ADC1->DR >> 4) & 0x0FFF;

ADC校准是保证精度的关键步骤。上电后或环境温度变化较大时,必须执行校准:

HAL_ADCEx_Calibration_Start(&hadc);  // HAL库校准函数

// 标准库校准流程
ADC_GetCalibrationFactor(ADC1);      // 获取校准因子
ADC_SetCalibrationFactor(ADC1, cal_factor);  // 应用校准

校准过程会测量内部参考电压的偏移,并自动修正转换结果。忽略这一步可能导致高达±5%的测量误差。

2. 软件轮询方案:简单但低效的实现

软件轮询是最直观的实现方式,适合对实时性要求不高、通道数少的应用。它的核心思想是CPU主动查询ADC转换完成标志,然后读取数据。

2.1 基本实现流程

轮询方式的代码结构通常如下:

#define ADC_CHANNELS 3
uint16_t adc_values[ADC_CHANNELS];

void ADC_Polling_Read(void) {
    uint8_t i;
    
    // 启动ADC转换
    HAL_ADC_Start(&hadc);
    
    for(i = 0; i < ADC_CHANNELS; i++) {
        // 等待转换完成,超时时间50ms
        if(HAL_ADC_PollForConversion(&hadc, 50) == HAL_OK) {
            // 读取转换结果
            adc_values[i] = HAL_ADC_GetValue(&hadc);
        } else {
            // 处理超时错误
            adc_values[i] = 0xFFFF;  // 错误标志
        }
    }
    
    // 停止ADC以节省功耗
    HAL_ADC_Stop(&hadc);
}

这种方式的优缺点非常明显:

优点:

  • 代码简单,易于理解和调试
  • 不需要中断或DMA配置,入门门槛低
  • 对系统其他部分影响小,适合简单应用

缺点:

  • CPU利用率高,在等待转换期间完全阻塞
  • 实时性差,无法响应其他紧急事件
  • 采样率受限于轮询开销

2.2 性能分析与优化

为了量化轮询方案的性能,我在STM32F030F4P6(48MHz主频)上进行了实测:

通道数 采样时间(周期) 理论采样率 实测采样率 CPU占用率
1通道 13.5 370kSPS 280kSPS 85%
3通道 71.5 66kSPS 42kSPS 92%
5通道 239.5 18kSPS 11kSPS 95%

从数据可以看出,随着通道数和采样时间的增加,实际采样率远低于理论值,CPU占用率却接近100%。这是因为HAL_ADC_PollForConversion()内部是忙等待循环:

// HAL库轮询
【STM32】stm32f030软件触发多通道ADC扫描采样 测试过程中发现采集到的数据总是不正确,于是将ADC的Discontinuous Conversion Mode选项配置为Enabled,问题解决。 阅读详情

相关推荐

stm32f030 学习笔记 (1)adc单/双通道采集

ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None, //启用软件触发,禁止外部启用模数转换。.USART_HardwareFlowControl = USART_HardwareFlowControl_None,//无流控。.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,//rx接收,tx发送。.USART_StopBits = USART_StopBits_1,//停止位 1。//等待adc1启用。

qq_56542113的博客 4478

STM32F030 HAL ADC多通道采样DMA传输

我所选用的芯片是STM32F030C6,采用官方STM32CubeMX配置ADC多通道时只需勾选相应的ADC通道,而对于大部分说的Rank设置是不需要的,F0默认按通道数字号配置了通道顺序。 关于ADC多通道DMA配置的顺序:Enable DMA时钟 -> 配置ADC -> 配置DMA -> 开启传输 1、配置ADC ADC_ChannelConfT...

yhl_sophia的博客 7477

STM32F030 多通道ADC DMA采集

利用STM32F030C8T6的PA0和PA1引脚来进行两通道ADC采集,通过DMA方式。直接上代码。 1、ADC的GPIO引脚配置 void ADC_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /* GPIOC Periph clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_InitStruc...

qq_21226319的博客 5806

STM32同一个ADC多通道传输非DMA方式

最后参考的文章--------------------------->:https://blog.csdn.net/jxwzh/article/details/80611774 网上多通道传输方式很多都是说的DMA方式的,下面我介绍非DMA方式的多通道转换方式 ADC的通道是什么 stm32有多个ADC,比如有ADC1、ADC2,每个ADC又有16个外部通道和两个内部通道,每个通道都可...

baidu_39491365的博客 2184

STM32CubeMx实现ADC多通道+DMA读取(HAL库)

stm32f407ZG基于STM32CubeMx HAL库开发

LZLkie的博客 8340

告别轮询!用STM32CubeMX给STM32F030配置ADC多通道+DMA,实测代码分享

本文详细介绍了如何使用STM32CubeMX为STM32F030配置ADC多通道采集与DMA传输,显著提升采集效率。通过实测对比轮询与DMA模式的性能差异,提供完整的代码实现和优化技巧,帮助开发者快速掌握这一高效采集方案。

weixin_42570296的博客 408

STM32 ADC与DMA多通道连续采样实现方法

学习教程(传送门)本人详解作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯转载说明:务必注明来源(注明:作者:王文峰哦)STM32 ADC与DMA多通道连续采样实现方法学习教程(传送门)学习教程(传送门)往期文章学习教程(传送门)1、掌握入门到进阶知识(持续写作中……2、学会数据库用法(创作中……

王大师企业官方博客 3151

STM32F030C8T6多通道ADC数据采集实战项目

当启用扫描模式(Scan Mode)时,ADC会按照预定义的通道序列逐一执行转换。该序列由规则组(Regular Group)定义,最多支持16个通道。在STM32CubeMX或HAL库中,可通过如下方式配置:// PA0// 第一个转换// PA1// 第二个转换参数说明:Rank:决定转换顺序,从1到n依次执行;每次调用添加一个通道;所有通道共用相同的触发源(如软件启动或定时器TRGO);

weixin_36382073的博客 1148

STM32F030使用ADC功能的例子

STM32F030使用ADC功能的例子,用定时器控制采样频率,用了DMA传输。程序注释也比较详细。其中还对比了STM32F103和STM32F030使用ADC时代码的细微区别。

STM32F030DMA加ADC的配置文件

关于STM32F030DMA加ADC的配置文件,请自行删除无用的代码

海思Hi3061M MCU:为高速吹风筒市场注入智能动力

此外,海思还提供了丰富的软件开发工具和生态环境组件,帮助开发者快速实现复杂功能。高速吹风筒因其高效的风力和快速的干燥效果,近年来在市场上越来越受欢迎。然而,传统的高速吹风筒在性能、噪音和使用寿命等方面仍有改进的空间。凭借其高性能、低功耗、低噪声和易用的开发工具,为高速吹风筒市场带来了全新的解决方案。这不仅提高了用户的使用体验,还延长了电机的使用寿命。这不仅减少了电机的电磁噪声,还提高了电机的运行效率。还支持风机顺逆风启动适配多种电阻范围的电机,进一步提高了吹风筒的适用性和灵活性。

2401_83448585的博客 2006

Unity中实现HLS视频加密与流式播放的完整方案

本文详细介绍了在Unity中实现HLS视频加密与流式播放的完整方案。针对Unity原生VideoPlayer无法直接支持实时解密的问题,提出了基于HLS协议与AES-128加密的成熟解决方案,并重点阐述了如何利用AVPro Video插件进行集成。文章涵盖了从密钥生成、使用FFmpeg进行视频加密切片,到在Unity中动态加载密钥并播放加密流的全流程,为保护付费课程、独家动画等视频内容提供了安全且高效的实践路径。

weixin_29290963的博客 389

白话机器学习算法理论+实战番外篇之Xgboost

1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集成算法Adaboost等 无监督算法:聚类,降维,关联规则, PageRank等 我前面已经尝试用最白话的语言完成了一个白话机器学习算法理论+实战系列,这个系列已经基本包含了上面这些算...

Miracle8070 1万+

Open3D 点云转深度图像【2026最新版】

python版本Open3D 实现的点云转深度图像,博客长期更新,本文最新更新时间为:2026年5月10日。

点云侠的博客 2833

基于FPGA的以太网设计(1)----大白话解释什么是以太网

基于FPGA的千兆以太网设计(1)----大白话解释什么是以太网

孤独的单刀 3850

OpenClaw三层记忆系统:让你的AI助理记住你的习惯,越用越顺手

对于更早的、已经移出滑动窗口的对话内容,我们没有直接丢弃,而是用大模型做摘要压缩,只保留核心信息,然后把摘要存入短期会话记忆的末尾,或者长期用户记忆。比如,10轮之前的对话内容,我们会压缩成:“用户之前查询了仓山万达店4月1日-4月7日的库存数据,对报表的要求是纯文本,不要Markdown”,既保留了核心信息,又不会占用太多上下文窗口。如果说Agent的执行链路是AI的“骨架”,工具调用体系是AI的“手脚”,那么记忆系统就是AI的“大脑”

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 375

RT-DETR改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进

1️⃣本专栏已更新260多种不同的改进方法,所使用并改进的每一个模块均包含详细的模块分析、原理讲解、个人总结、多种改进方式以及完整的修改流程,所有改进100%可直接运行。2️⃣所有改进点均为近三年顶会,顶刊提出的先进算法,将其融入到中,紧跟学术热点,适应不同的任务场景。3️⃣团队内发表数篇SCI论文,熟悉完整的发表流程,订阅专栏即可进群享受模型训练、模型改进、论文写作、投稿选刊,从入门到论文的各种答疑内容。4️⃣专栏内容会持续更新,最近更新时间:2024-12-4。项目介绍在大家购买专栏后,加入学习

Limiiiing的博客 2万+

目前最强的价格行为技术分析AI!大A也能用!还免费!

有球友推荐了一个历史最强的价格行为技术分析AI工具,使用下来确实很惊艳,解决了 很多AI工具黑盒过程,难以回溯的问题,他的决策过程可解释,提供决策树、诊断结果、原始响应、调试信息和未来走势预期。用户能够看到模型为什么选择“做多、做空或不下单”。会检查置信度、入场条件、盈亏比、结构失效和冷却期。最大的优点不是“预测一定准确”,而是把主观的价格行为分析整理成了可重复、可解释、可校验、可持续跟踪的工程化流程。本文记录本项目在 Windows 上的实际部署与启动方法。

木头大左的博客 53

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

上一篇: Python实战:用混淆矩阵和ROC曲线优化客户流失预警模型(附完整代码)
下一篇: 技术解析 | 反绎学习 (Abductive Learning):如何让机器学会“猜”与“证”的循环?
对方正在偷人346
博客等级 码龄3年 1176粉丝 1380原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值