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

stm32—ADC和DAC

ADC和DAC


在嵌入式系统中,微控制器经常需要与现实世界的模拟信号进行交互。STM32微控制器内置了模拟数字转换器(ADC)和数字模拟转换器(DAC),它们是实现这种交互的关键模块。

1. 模拟数字转换器(ADC)

ADC的作用是将连续变化的模拟电压信号转换为离散的数字值,以便微控制器进行处理。

工作原理:

STM32的ADC通常采用**逐次逼近型(SAR)**架构。其基本思想是通过一系列比较来逐渐逼近输入模拟电压的数字表示。

  • 采样(Sampling): ADC在特定时刻对模拟输入电压进行采样,将其固定在采样保持电容上。采样时间越短,对快速变化的信号捕捉能力越强。
  • 量化(Quantization): 将采样的模拟电压值映射到有限的离散数字级别。ADC的分辨率决定了量化级别数量,例如,12位ADC可以将模拟输入转换为212=4096个不同的数字值。
  • 编码(Encoding): 将量化后的级别转换为相应的二进制数字代码。

原理图示意:

虽然STM32内部的ADC结构复杂,但其简化原理可以表示为:

                   +-------------------+
模拟输入 (Vin) ----| 采样保持电路 (S/H) |----+-------------------+|V+-------------------+| 比较器 (Comparator) |----+-------------------+|V+-------------------+| 逐次逼近寄存器 (SAR) |----+-------------------+|V+-------------------+| 控制逻辑 (Control Logic) |----+-------------------+|V
数字输出 (Digital Out) <--------------------

主要特点:

  • 高分辨率: STM32的ADC通常提供12位甚至更高(如16位)的分辨率,这意味着可以精确地测量模拟电压。
  • 多通道: 大多数STM32芯片具有多个ADC通道,可以同时或顺序转换多个模拟输入。
  • 多种转换模式
    • 单次转换模式 (Single Conversion Mode): 每次触发只进行一次转换。
    • 连续转换模式 (Continuous Conversion Mode): 一旦启动,ADC会持续进行转换,直到停止。
    • 扫描模式 (Scan Mode): 自动按顺序转换多个通道。
    • 注入模式 (Injected Mode): 允许在常规转换序列中插入高优先级的转换,常用于实时控制。
  • 多种触发源: 转换可以由软件、定时器事件、外部中断等多种方式触发。
  • DMA支持: 可以通过DMA(直接内存访问)将ADC转换结果自动传输到内存中,减轻CPU负担,提高效率。
  • 自校准: 部分STM32系列支持ADC自校准功能,以提高测量精度。
  • 模拟看门狗: 可以设置模拟信号的阈值,当模拟输入超出范围时触发中断。
  • 过采样: 通过对多次采样结果进行平均,可以提高有效分辨率。

应用场景:

  • 传感器数据采集: 读取温度、光照、压力、湿度等模拟传感器的输出。
  • 电池电压监测: 实时监测电池电量。
  • 电源管理: 监测电源轨电压,确保系统稳定运行。
  • 电机控制: 通过电流传感器反馈进行闭环控制。
  • 音频信号处理: 简单的音频输入采样。

2. 数字模拟转换器(DAC)

DAC的作用是将微控制器产生的数字信号转换为连续变化的模拟电压信号。

工作原理:

STM32的DAC通常采用R-2R梯形网络电阻串型结构。其基本思想是根据数字输入的不同位,通过精确的电阻网络组合,产生不同大小的电流或电压,然后叠加形成最终的模拟输出。

  • 数字输入: 微控制器提供一个数字值给DAC。
  • 转换: DAC内部的电阻网络根据数字输入值产生相应的模拟电压。
  • 输出: DAC输出一个与数字输入值成比例的模拟电压。

原理图示意:

以简化的R-2R梯形网络为例:

                +-------------------+
数字输入 (Dout) |                   |
(例如12)    |                   |
D11 -----+---+ R/2R 网络           +----- 模拟输出 (Vout)
D10 -----|   |                   |
...      |   |                   |
D0  -----+---+                   |+-------------------+

主要特点:

  • 高分辨率: 通常提供12位分辨率,可以产生212=4096个不同的模拟输出电压级别。
  • 多通道: 部分STM32芯片具有多个DAC通道,可以同时输出多个模拟电压。
  • 多种波形生成
    • 软件模式: 通过软件直接写入数据寄存器来更新输出电压。
    • 波形生成器: 内置三角波和噪声波形生成器,可以自动生成特定波形。
  • DMA支持: 可以通过DMA自动将数据传输到DAC数据寄存器,实现连续波形生成,减轻CPU负担。
  • 外部触发: 可以通过定时器、外部中断等触发DAC的转换。
  • 输出缓冲: 部分DAC具有输出缓冲器,可以提高输出驱动能力和稳定性。

应用场景:

  • 波形生成: 生成正弦波、方波、三角波、锯齿波等各种模拟波形,用于信号发生器、测试设备等。
  • 模拟电压输出: 提供可编程的参考电压或控制电压,例如用于PWM调光、电机速度控制等。
  • 音频播放: 简单的音频信号输出(通过DAC和外部滤波)。
  • 可编程增益放大器 (PGA) 控制: 通过DAC输出控制PGA的增益。
  • 传感器校准: 提供精确的模拟电压来校准外部传感器。

1. STM32 ADC实际代码流程示例

假设我们要使用ADC1的通道0(PA0引脚)来读取一个模拟电压值,并将其通过UART打印出来。

所需硬件:

  • STM32开发板(例如STM32F407VGT6)
  • 连接在PA0上的模拟信号源(例如电位器)
  • USB转串口模块(用于UART调试输出)

代码流程概述:

  1. CubeMX配置:
    • 启用ADC1,选择Channel 0。
    • 配置ADC的时钟、分辨率、采样时间等参数。
    • 启用UART(例如USART2)用于打印结果。
    • 生成代码。
  2. HAL库代码实现:
    • 包含头文件。
    • 定义ADC句柄和变量。
    • main函数中,执行ADC和UART的初始化(CubeMX生成的)。
    • 启动ADC转换。
    • 获取转换结果。
    • 将结果通过UART发送。

代码示例:

#include "main.h" // 包含CubeMX生成的头文件
#include "string.h" // 用于字符串操作,例如sprintf// ADC句柄声明 (通常由CubeMX生成在main.h中,或自行声明)
extern ADC_HandleTypeDef hadc1; // 假设CubeMX已生成此句柄
extern UART_HandleTypeDef huart2; // 假设CubeMX已生成此UART句柄void MX_ADC1_Init(void); // ADC初始化函数声明 (CubeMX生成)
void MX_USART2_UART_Init(void); // UART初始化函数声明 (CubeMX生成)int main(void)
{/* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* Configure the System clock */SystemClock_Config(); // 系统时钟配置 (CubeMX生成)/* Initialize all configured peripherals */MX_GPIO_Init();      // GPIO初始化 (CubeMX生成)MX_ADC1_Init();      // ADC1初始化 (CubeMX生成)MX_USART2_UART_Init(); // USART2初始化 (CubeMX生成)uint32_t adc_raw_value;float voltage;char uart_buf[50];while (1){/* 1. 启动ADC转换 */HAL_ADC_Start(&hadc1);/* 2. 等待ADC转换完成 */// 超时时间设置为100ms,可以根据实际情况调整if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK){/* 3. 获取ADC转换结果 */adc_raw_value = HAL_ADC_GetValue(&hadc1);/* 4. 将原始ADC值转换为实际电压 (假设ADC参考电压为3.3V,12位分辨率) */// Vout = (ADC_Value / Max_ADC_Value) * Vref// 对于12位ADC,Max_ADC_Value = 4095voltage = (float)adc_raw_value / 4095.0f * 3.3f;/* 5. 打印结果到UART */sprintf(uart_buf, "ADC Raw: %lu, Voltage: %.3fV\r\n", adc_raw_value, voltage);HAL_UART_Transmit(&huart2, (uint8_t*)uart_buf, strlen(uart_buf), HAL_MAX_DELAY);}/* 6. 停止ADC (可选,如果是非连续模式) */HAL_ADC_Stop(&hadc1);/* 延时,以便观察结果,避免UART输出过快 */HAL_Delay(500); // 每500ms读取一次}
}// 注意:MX_ADC1_Init(), MX_USART2_UART_Init(), SystemClock_Config(), MX_GPIO_Init()
// 这些函数通常由STM32CubeMX自动生成,并放在main.c或其他独立的.c文件中。
// 它们会配置ADC和UART的寄存器,包括时钟、引脚、模式等。/* 示例:MX_ADC1_Init() 结构概要 (CubeMX生成的一部分) */
/*
void MX_ADC1_Init(void)
{ADC_ChannelConfTypeDef sConfig = {0};hadc1.Instance = ADC1;hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_DIV4; // 时钟预分频hadc1.Init.Resolution = ADC_RESOLUTION_12B;     // 12位分辨率hadc1.Init.ScanConvMode = DISABLE;              // 单通道,不扫描hadc1.Init.ContinuousConvMode = DISABLE;        // 单次转换模式hadc1.Init.DiscontinuousConvMode = DISABLE;hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; // 软件触发hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;hadc1.Init.NbrOfConversion = 1;hadc1.Init.DMAContinuousRequests = DISABLE;hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;if (HAL_ADC_Init(&hadc1) != HAL_OK){Error_Handler();}// 配置ADC通道sConfig.Channel = ADC_CHANNEL_0;          // 选择通道0sConfig.Rank = 1;                         // 序列中的第一个sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; // 采样时间if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){Error_Handler();}
}
*/

ADC DMA示例 (更高效):

如果需要连续、高速地采集数据,使用DMA是非常高效的方式,可以减轻CPU的负担。

#include "main.h"
#include "string.h"extern ADC_HandleTypeDef hadc1;
extern UART_HandleTypeDef huart2;// DMA缓冲区,用于存储ADC转换结果
#define ADC_BUF_SIZE 10 // 假设我们采集10个样本
uint16_t adc_dma_buffer[ADC_BUF_SIZE];void MX_ADC1_Init(void);
void MX_USART2_UART_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_ADC1_Init(); // 确保在CubeMX中配置ADC的DMA请求MX_USART2_UART_Init();char uart_buf[100];/* 启动ADC DMA传输 */// 一旦启动,ADC会持续转换并将结果通过DMA存入adc_dma_bufferHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_dma_buffer, ADC_BUF_SIZE);while (1){/* 在这里,你可以执行其他任务,ADC转换在后台通过DMA进行 *//* 例如,周期性地检查DMA缓冲区数据 */// 注意:如果DMA模式是Circular,数据会不断更新// 如果是Normal,需要在HAL_ADC_ConvCpltCallback中重新启动DMA// 简单地打印第一个值作为示例sprintf(uart_buf, "ADC DMA Raw (first sample): %u\r\n", adc_dma_buffer[0]);HAL_UART_Transmit(&huart2, (uint8_t*)uart_buf, strlen(uart_buf), HAL_MAX_DELAY);HAL_Delay(100); // 延时}
}// ADC转换完成回调函数 (在stm32f4xx_it.c中实现)
// 当ADC的DMA传输完成一半或全部完成时,会调用此函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){// 可以在这里处理ADC转换完成的数据// 例如,对adc_dma_buffer中的所有数据进行处理// 如果DMA模式是Normal,你需要在这里再次启动DMA传输:// HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_dma_buffer, ADC_BUF_SIZE);}
}// ADC半转换完成回调函数 (仅在DMA模式下)
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){// 可以在这里处理ADC转换到一半的数据 (例如,处理前半部分的缓冲区)}
}

2. STM32 DAC实际代码流程示例

假设我们要使用DAC1的通道1(PA4引脚)来输出一个简单的三角波。

所需硬件:

  • STM32开发板
  • 示波器(用于观察DAC输出波形)

代码流程概述:

  1. CubeMX配置:
    • 启用DAC1,选择Channel 1。
    • 配置DAC的时钟。
    • 选择DAC触发源(例如,TIM6)。
    • 启用TIM6,配置其周期以控制DAC的更新速率。
    • 生成代码。
  2. HAL库代码实现:
    • 包含头文件。
    • 定义DAC句柄和定时器句柄。
    • 定义三角波数据数组。
    • main函数中,执行DAC和定时器的初始化。
    • 启动DAC波形生成。

代码示例:

#include "main.h"
#include "math.h" // 用于生成正弦波,这里我们生成三角波,也可以手动定义// DAC句柄和定时器句柄 (CubeMX生成)
extern DAC_HandleTypeDef hdac; // 假设DAC1通道1
extern TIM_HandleTypeDef htim6; // 假设使用TIM6作为DAC触发源void MX_DAC_Init(void);      // DAC初始化函数声明
void MX_TIM6_Init(void);     // TIM6初始化函数声明// 定义三角波数据 (例如,12位分辨率DAC,0-4095)
// 这里为了简化,我们定义一个简单的上升和下降序列
#define TRIANGLE_WAVE_SIZE 20
uint16_t TriangleWave[TRIANGLE_WAVE_SIZE] = {0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, // 上升1800, 1600, 1400, 1200, 1000, 800, 600, 400, 200, 0   // 下降
};int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DAC_Init();   // 确保在CubeMX中配置DAC使用TIM6触发和DMAMX_TIM6_Init();/* 启动定时器 */HAL_TIM_Base_Start(&htim6);/* 启动DAC,通过DMA传输三角波数据 */// HAL_DAC_Start_DMA(DAC句柄, DAC通道, 数据缓冲区, 缓冲区大小, 数据对齐方式)// DAC_CHANNEL_1对应PA4// HAL_DAC_Start_DMA 会将TIM6的更新事件作为触发源,每次触发传输一个数据到DACif (HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)TriangleWave, TRIANGLE_WAVE_SIZE, DAC_ALIGN_12B_R) != HAL_OK){Error_Handler();}while (1){// DAC和定时器在后台自动运行,生成三角波// 你可以在这里执行其他任务HAL_Delay(10);}
}// 注意:MX_DAC_Init() 和 MX_TIM6_Init() 也会由CubeMX自动生成。/* 示例:MX_DAC_Init() 结构概要 (CubeMX生成的一部分) */
/*
void MX_DAC_Init(void)
{DAC_ChannelConfTypeDef sConfig = {0};hdac.Instance = DAC;if (HAL_DAC_Init(&hdac) != HAL_OK){Error_Handler();}sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO; // 定时器6触发sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; // 使能输出缓冲if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK){Error_Handler();}
}
*//* 示例:MX_TIM6_Init() 结构概要 (CubeMX生成的一部分) */
/*
void MX_TIM6_Init(void)
{TIM_MasterConfigTypeDef sMasterConfig = {0};htim6.Instance = TIM6;htim6.Init.Prescaler = 0; // 根据系统时钟和期望频率设置htim6.Init.CounterMode = TIM_COUNTERMODE_UP;htim6.Init.Period = 100 - 1; // 周期,例如100个计数触发一次htim6.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim6) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; // 更新事件作为触发源sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK){Error_Handler();}
}
*/

DAC软件模式示例:

如果不需要复杂的波形,或者只需要输出一个固定的模拟电压,可以直接通过软件写入。

#include "main.h"extern DAC_HandleTypeDef hdac;int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DAC_Init();/* 启动DAC (非DMA模式) */if (HAL_DAC_Start(&hdac, DAC_CHANNEL_1) != HAL_OK){Error_Handler();}uint16_t dac_value = 0; // 0-4095 对应 0V-3.3V (假设Vref=3.3V)while (1){/* 设置DAC输出电压 */// 这里我们简单地让DAC输出电压在0V到3.3V之间循环变化HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, dac_value);dac_value += 100; // 每次增加100if (dac_value > 4095){dac_value = 0;}HAL_Delay(50); // 延时50ms}
}

总结:

  • CubeMX是STM32开发中非常重要的工具,它可以大大简化外设的初始化配置,并自动生成大量的HAL库代码。在实际项目中,强烈推荐首先使用CubeMX进行配置。
  • ADC和DAC的使用核心在于:
    • ADC: 启动转换 (HAL_ADC_StartHAL_ADC_Start_DMA),等待转换完成 (HAL_ADC_PollForConversion 或利用回调函数),获取结果 (HAL_ADC_GetValue)。
    • DAC: 启动输出 (HAL_DAC_StartHAL_DAC_Start_DMA),通过软件或DMA提供数据 (HAL_DAC_SetValue 或 DMA传输)。
  • DMA在处理连续数据流(如ADC采集和DAC波形生成)时非常关键,它可以显著提高系统效率,减少CPU的干预。
  • 回调函数 (HAL_ADC_ConvCpltCallback, HAL_DAC_ConvCpltCallback 等) 是HAL库中处理中断和DMA完成事件的重要机制,可以方便地在数据准备就绪时执行自定义逻辑。

相关文章:

stm32—ADC和DAC

ADC和DAC 在嵌入式系统中&#xff0c;微控制器经常需要与现实世界的模拟信号进行交互。STM32微控制器内置了模拟数字转换器&#xff08;ADC&#xff09;和数字模拟转换器&#xff08;DAC&#xff09;&#xff0c;它们是实现这种交互的关键模块。 1. 模拟数字转换器&#xff08…...

ubuntu2404 gpu 没接显示器,如何保证远程显示的分辨率

1. 使用 xserver-xorg-video-dummy 创建虚拟显示器 如果系统在无物理显示器连接时无法识别显示输出&#xff0c;可以使用 xserver-xorg-video-dummy 驱动程序创建虚拟显示器。以下是设置步骤&#xff1a; 安装虚拟显示器驱动程序&#xff1a; sudo apt install xserver-xorg-v…...

【基于阿里云搭建数据仓库(离线)】使用UDTF时出现报错“FlatEventUDTF cannot be resolved”

目录 问题&#xff1a; 可能的原因有&#xff1a; 解决方法&#xff1a; 问题&#xff1a; 已经将包含第三方依赖的jar包上传到dataworks&#xff0c;并且成功注册函数&#xff0c;但是还是报错&#xff1a;“FlatEventUDTF cannot be resolved”&#xff0c;如下&#xff1a…...

Pycharm的终端无法使用Anaconda命令行问题详细解决教程

很多初学者在Windows系统上安装了Anaconda后&#xff0c;在PyCharm终端中运行Conda命令时&#xff0c;会遇到以下错误&#xff1a; conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。 请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保…...

SAP学习笔记 - 开发24 - 前端Fiori开发 Filtering(过滤器),Sorting and Grouping(排序和分组)

上一章讲了SAP Fiori开发的表达式绑定&#xff0c;自定义格式化等内容。 SAP学习笔记 - 开发23 - 前端Fiori开发 Expression Binding&#xff08;表达式绑定&#xff09;&#xff0c;Custom Formatters&#xff08;自定义格式化&#xff09;-CSDN博客 本章继续讲SAP Fiori开发…...

【Flask】:轻量级Python Web框架详解

什么是Flask&#xff1f; Flask是一个用Python编写的轻量级Web应用框架。它被称为"微框架"(microframework)&#xff0c;因为它核心简单但可扩展性强&#xff0c;不强制使用特定的项目结构或库。Flask由Armin Ronacher开发&#xff0c;基于Werkzeug WSGI工具包和Jin…...

自建 dnslog 回显平台:渗透测试场景下的隐蔽回显利器

&#x1f50d; 背景介绍 在渗透测试与红队评估过程中&#xff0c;DNS 外带&#xff08;DNS Exfiltration&#xff09; 是一种常见且隐蔽的通信通道。由于多数目标环境默认具备外网 DNS 解析能力&#xff0c;即便在 无回显、无文件上传权限 的条件下&#xff0c;仍可通过 DNS 请…...

Digital IC Design Flow

Flow介绍 1.设计规格 架构师根据市场需求制作算法模型(Algorithm emulation)及芯片架构(Chip architecture),确定芯片设计规格书(Chip design specification) 原型验证 原型验证(Prototype Validation)通常位于产品开发流程的前期阶段,主要是在设计和开发的初步阶…...

设备健康管理的范式革命:中讯烛龙全链路智能守护系统

当工业设备的“亚健康”状态导致隐性产能损失高达23%时&#xff0c;中讯烛龙推出 ​​“感知-诊断-决策-闭环”四位一体解决方案&#xff0c;让设备全生命周期健康管理成为企业增长的隐形引擎。 一、行业痛点&#xff1a;传统运维的三大断层 1. 健康感知盲区 某风电场因无法捕…...

循环神经网络(RNN):从理论到翻译

循环神经网络&#xff08;RNN&#xff09;是一种专为处理序列数据设计的神经网络&#xff0c;如时间序列、自然语言或语音。与传统的全连接神经网络不同&#xff0c;RNN具有"记忆"功能&#xff0c;通过循环传递信息&#xff0c;使其特别适合需要考虑上下文或顺序的任…...

Redis:常用数据结构 单线程模型

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Redis &#x1f525; 常用数据结构 &#x1f433; Redis 当中常用的数据结构如下所示&#xff1a; Redis 在底层实现上述数据结构的过程中&#xff0c;会在源码的角度上对于上述的内容进行特定的…...

夏普比率(Sharpe ratio)​

具有投资常识的人都明白&#xff0c;投资光看收益是不够的&#xff0c;还要看承受的风险&#xff0c;也就是收益风险比。 夏普比率描述的正是这个概念&#xff0c;即每承受一单位的总风险&#xff0c;会产生多少超额的报酬。 用数学公式描述就是&#xff1a; 其中&#xff1…...

【优选算法】模拟 问题算法

​一&#xff1a;替换所有的问号 class Solution { public:string modifyString(string s) {int n s.size();for(int i 0; i < n; i){if(s[i] ?){for(char ch a; ch < z; ch){if((i0 && ch !s[i1]) || (in-1 && ch ! s[i-1]) || ( i>0 &&…...

Flask+LayUI开发手记(八):通用封面缩略图上传实现

前一节做了头像上传的程序&#xff0c;应该说&#xff0c;这个程序编写和操作都相当繁琐&#xff0c;实际上&#xff0c;头像这种缩略图在很多功能中都会用到&#xff0c;屏幕界面有限&#xff0c;绝不会给那么大空间摆开那么大一个界面&#xff0c;更可能的处理&#xff0c;就…...

低代码采购系统搭建:鲸采云+能源行业订单管理自动化案例

在能源行业数字化转型浪潮下&#xff0c;某大型能源集团通过鲸采云低代码平台&#xff0c;仅用3周时间就完成了采购订单管理系统的定制化搭建。本文将揭秘这一成功案例的实施路径与关键成效。 项目背景与挑战 该企业面临&#xff1a; 供应商分散&#xff1a;200供应商使用不同…...

android关于pthread的使用过程

文章目录 简介代码流程pthread使用hello_test.cppAndroid.bp 编译过程报错处理验证过程 简介 android开发经常需要使用pthread来编写代码实现相关的业务需求 代码流程 pthread使用 需要查询某个linux函数的方法使用&#xff0c;可以使用man 函数名 // $ man pthread_crea…...

Faiss vs Milvus 深度对比:向量数据库技术选型指南

Faiss vs Milvus 深度对比&#xff1a;向量数据库技术选型指南 引言&#xff1a;向量数据库的时代抉择 在AI应用爆发的今天&#xff0c;企业和开发者面临着如何存储和检索海量向量数据的重大技术选择。作为当前最受关注的两大解决方案&#xff0c;Faiss和Milvus代表了两种不同…...

慢慢欣赏linux 之 last = switch_to(prev, next)分析

last switch_to(prev, next); 为什么需要定义last作为调用switch_to之前的prev的引用 原因如下&#xff1a; struct task_struct * switch_to(struct task_struct *prev,struct task_struct *next) {... ...return cpu_switch_to(prev, next);> .global cpu_switch_tocpu_…...

如何用 HTML 展示计算机代码

原文&#xff1a;如何用 HTML 展示计算机代码 | w3cschool笔记 &#xff08;请勿将文章标记为付费&#xff01;&#xff01;&#xff01;&#xff01;&#xff09; 在编程学习和文档编写过程中&#xff0c;清晰地展示代码是一项关键技能。HTML 作为网页开发的基础语言&#x…...

2025年ESWA SCI1区TOP,自适应学习粒子群算法AEPSO+动态周期调节灰色模型,深度解析+性能实测

目录 1.摘要2.粒子群算法PSO原理3.改进策略4.结果展示5.参考文献6.代码获取7.算法辅导应用定制读者交流 1.摘要 能源数据的科学预测对于能源行业决策和国家经济发展具有重要意义&#xff0c;尤其是短期能源预测&#xff0c;其精度直接影响经济运行效率。为了更好地提高预测模型…...

LeetCode - 53. 最大子数组和

目录 题目 Kadane 算法核心思想 Kadane 算法的步骤分析 读者可能的错误写法 正确的写法 题目 53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; Kadane 算法核心思想 定义状态变量: currentSum: 表示以当前元素为结束的子数组的最大和。 maxSum: 记录全局最大…...

稻米分类和病害检测数据集(猫脸码客第237期)

稻米分类图像数据集&#xff1a;驱动农业智能化发展的核心资源 引言 在全球农业体系中&#xff0c;稻米作为最关键的粮食作物之一&#xff0c;其品种多样性为人类饮食提供了丰富选择。然而&#xff0c;传统稻米分类方法高度依赖人工经验&#xff0c;存在效率低、主观性强等缺…...

DOM(文档对象模型)深度解析

DOM(文档对象模型)深度解析 DOM 是 HTML/XML 文档的树形结构表示,提供了一套让 JavaScript 动态操作网页内容、结构和样式的接口。 一、DOM 核心概念 1. 节点(Node)类型 类型值说明示例ELEMENT_NODE1元素节点<div>, <p>TEXT_NODE3文本节点元素内的文字COMMEN…...

四、Sqoop 导入表数据子集

作者&#xff1a;IvanCodes 日期&#xff1a;2025年6月4日 专栏&#xff1a;Sqoop教程 当不需要将关系型数据库中的整个表一次性导入&#xff0c;而是只需要表中的一部分数据时&#xff0c;Sqoop 提供了多种方式来实现数据子集的导入。这通常通过过滤条件或选择特定列来完成。 …...

【读代码】从预训练到后训练:解锁语言模型推理潜能——Xiaomi MiMo项目深度解析

项目开源地址:https://github.com/XiaomiMiMo/MiMo 一、基本介绍 Xiaomi MiMo是小米公司开源的7B参数规模语言模型系列,专为复杂推理任务设计。项目包含基础模型(MiMo-7B-Base)、监督微调模型(MiMo-7B-SFT)和强化学习模型(MiMo-7B-RL)等多个版本。其核心创新在于通过…...

DROPP算法详解:专为时间序列和空间数据优化的PCA降维方案

DROPP (Dimensionality Reduction for Ordered Points via PCA) 是一种专门针对有序数据的降维方法。本文将详细介绍该算法的理论基础、实现步骤以及在降维任务中的具体应用。 在现代数据分析中&#xff0c;高维数据集普遍存在特征数量庞大的问题。这种高维特性不仅增加了计算…...

DeepSeek11-Ollama + Open WebUI 搭建本地 RAG 知识库全流程指南

&#x1f6e0;️ Ollama Open WebUI 搭建本地 RAG 知识库全流程指南 &#x1f4bb; 一、环境准备 # 1. 安装 Docker 和 Docker Compose sudo apt update && sudo apt install docker.io docker-compose -y# 2. 添加用户到 docker 组&#xff08;避免 sudo 权限&…...

【AI大模型】Transformer架构到底是什么?

引言 —— 想象一台能瞬间读懂整本《战争与和平》、精准翻译俳句中的禅意、甚至为你的设计草图生成前端代码的机器——这一切并非科幻&#xff0c;而是过去七年AI领域最震撼的技术革命&#xff1a;Transformer架构创造的奇迹。 当谷歌在2017年揭开Transformer的神秘面纱时&…...

code-server安装使用,并配置frp反射域名访问

为什么使用 code-server是VSCode网页版开发软件&#xff0c;可以在浏览器访问编程&#xff0c;可以使用vscode中的插件。如果有自己的服务器&#xff0c;使用frp透传后&#xff0c;域名访问在线编程&#xff0c;使用方便&#xff0c;打开的服务端口不需要单独配置&#xff0c;可…...

MTK-Android12-13 Camera2 设置默认视频画质功能实现

MTK-Android12-13 Camera2 设置默认视频画质功能实现 场景&#xff1a;部分客户使用自己的mipi相机安装到我们主板上&#xff0c;最大分辨率为1280720&#xff0c;但是视频画质默认的是640480。实际场景中&#xff0c;在默认视频分辨率情况下拍出来的视频比较模糊、预览也不清晰…...