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

普冉(PUYA)单片机开发笔记(7): ADC-轮询式多路采样

概述

应用中经常会有使用单片机进行模数转换的需求。PY32F003 具有 1 个 12 位的模拟数字转换器(ADC),今天我们一起来使用一下这个 ADC。

数据手册中对 ADC 简介如下。

SAR ADC:逐次逼近式 ADC,原理参见“参考链接:什么是SAR ADC? - 知乎”。12位采样值的最大值4095。数据手册上标明的最大可用通道数量是 8 个外部通道,但对照 PY32F003F18P 的管脚复用表,如果应用中还要使用 GPIO,LED,定时器 和 UART 的话,可使用的外部 ADC 通道数最多不超过 6 个。对比于 PY32F003F18P 的 20 脚封装和低廉的芯片价格,这样的 MCU 可以在应用中采样 6 个外部模拟量通道也是相当可观的数量了。

PY32F003 可以在不使用外部晶振的情况下完成数模转换,但其采样精度还需要验证。今天先尝试着把 ADC 的功能跑通先。

实现代码

参考在 STM32F103 上实现 ADC 的思路,在 PY32F003 上完成一下看。大致的步骤如下:

  1. 为 ADC1 指定 GPIO 管脚,并设置其复用功能
  2. 对 ADC1 进行初始化
  3. 在主循环中进行采样和打印输出

在 main.h 中增加和 ADC 相关的函数声明

/** ----------------------------------------------------------------------------
* @name   : void ADC_Init(void)
* @brief  : ADC 初始化
* @param  : [in] None
* @retval : [out] void
* @remark :
*** ----------------------------------------------------------------------------
*/
void ADC_Init(void);/** ----------------------------------------------------------------------------
* @name   : HAL_StatusTypeDef ADC_Sample(char * sampleResult)
* @brief  : 获取 ADC 的采样结果,结果存放在 sampleResult 字符串中
* @param  : [in] None
* @retval : [out] HAL_HandleTypeDef. 操作成功返回 HAL_OK, 错误返回错误码。
* @remark : sampleResult 是格式化的字符串,需要解析
*** ----------------------------------------------------------------------------
*/
HAL_StatusTypeDef ADC_Sample(char * sampleResult);

在 app_adc.c 文件中实现函数功能

在 Application/User 组增加 app_adc.c 文件,完整代码如下。

/********************************************************************************* @file    app_adc.c* @brief   Application level Analog-Digital Conveter codes.******************************************************************************* @attention** Copyright (c) 2023 CuteModem Intelligence.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/#include "main.h"ADC_HandleTypeDef hadc;
uint32_t adc_value[3];/********************************************************************************************************
* @name   : HAL_StatusTypeDef ADC_Sample(char * sampleResult)
* @brief  : 获取 ADC 的采样结果,结果存放在 sampleResult 字符串中
* @param  : [in] None
* @retval : [out] HAL_HandleTypeDef. 操作成功返回 HAL_OK, 错误返回错误码。
* @remark : sampleResult 是格式化的字符串,需要解析
********************************************************************************************************/
HAL_StatusTypeDef ADC_Sample(char * sampleResult)
{uint8_t i=0;if(HAL_ADCEx_Calibration_Start(&hadc) != HAL_OK) return HAL_ERROR;HAL_ADC_Start(&hadc);                       //开始采样for (i = 0; i < 3; i++){HAL_ADC_PollForConversion(&hadc, 10000);  //等待ADC转换adc_value[i] = HAL_ADC_GetValue(&hadc);   //获取AD值}#if(1)// excel formatsprintf(sampleResult, "%d,%d,%d",(uint16_t)adc_value[0],(uint16_t)adc_value[1],(uint16_t)adc_value[2]);
#else// JSON formatsprintf(sampleResult, "[{\"C\":0,\"D\":%d}"",{\"C\":1,\"D\":%d}"",{\"C\":5,\"D\":%d}""]",(uint16_t)adc_value[0],(uint16_t)adc_value[1],(uint16_t)adc_value[2]);
#endif    HAL_ADC_Stop(&hadc); // 停止采样return HAL_OK;
}void ADC_Init(void)
{ADC_ChannelConfTypeDef sConfig = {0};__HAL_RCC_ADC_FORCE_RESET();__HAL_RCC_ADC_RELEASE_RESET();__HAL_RCC_ADC_CLK_ENABLE();hadc.Instance = ADC1;if (HAL_ADCEx_Calibration_Start(&hadc) != HAL_OK)                 //AD校准Error_Handler();/* Configure global features of the ADC1  */hadc.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;       //ADC_CLOCK_SYNC_PCLK_DIV2/4,分频系数hadc.Init.Resolution            = ADC_RESOLUTION_12B;             //设置采样位数hadc.Init.DataAlign             = ADC_DATAALIGN_RIGHT;            //右对齐hadc.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;     //扫描方向设置hadc.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;            //ADC_EOC_SINGLE_CONV:单次采样 ; ADC_EOC_SEQ_CONV:序列采样hadc.Init.LowPowerAutoWait      = ENABLE;                         //ENABLE:读取ADC值后,开始下一次转换; DISABLE:直接转换hadc.Init.ContinuousConvMode    = DISABLE;                        //ENABLE:连续模式, DISABLE:单次模式hadc.Init.DiscontinuousConvMode = DISABLE;                        //非连续转换模式设置hadc.Init.ExternalTrigConv      = ADC_SOFTWARE_START;             //触发模式设置hadc.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;  //外部触发沿设置hadc.Init.DMAContinuousRequests = DISABLE;                        //DMA连续模式设置hadc.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;       //ADC_OVR_DATA_OVERWRITTEN:过载时覆盖,ADC_OVR_DATA_PRESERVED:保留旧值if (HAL_ADC_Init(&hadc) != HAL_OK) Error_Handler();               //初始化ADC/* Configure selected ADC channels  */sConfig.Channel      = ADC_CHANNEL_0;                             sConfig.Rank         = ADC_RANK_CHANNEL_NUMBER;                   sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;                 if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)             Error_Handler();sConfig.Channel = ADC_CHANNEL_1;                                  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;                           sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;                 if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)             Error_Handler();sConfig.Channel = ADC_CHANNEL_4;                                  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;                           sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;                 if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)             Error_Handler();
}

在 app_adc.c 中定义了业务所需的变量,功能函数也在一个 .c 文件中全部实现。这样做是参考了面向对象的编程模式,遵循代码/变量和功能解耦的原则,ADC 所需的全局变量都在 app_adc.c 中定义,main.c 中就不用再引用 ADC 相关的变量,也不用关心实现的细节了。唯一的接口就是 ADC_Sample() 函数的 sampleResult,sampleResult 定义为一个字符串具有很好的通用性,并隐藏了实现的细节。这里例子中被注释掉的 JSON 串返回结果的代码,在实际应用中,在上一层的业务逻辑处理是很方便的。当然 MCU 编程,一般不会采用 JSON 这种富文本的格式,这里只作为一种示例。

ADC_Sample() 函数中每次采样之前都对 ADC 进行了校准,校准完成后开始采样,采样完毕后停止 ADC。

在 py32f0xx_hal_msp.c 文件中指定 GPIO 及其复用功能

/*** -----------------------------------------------------------------------* @name   : void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)* @brief  : 初始化 ADC 相关 MSP* @param  : [in] *hadc, ADC handler pointer* @retval : void* @remark :* -----------------------------------------------------------------------
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/*=============PA0/1/4初始化=============*/if (hadc->Instance == ADC1){__HAL_RCC_ADC_CLK_ENABLE();   /* Peripheral clock enable */__HAL_RCC_GPIOA_CLK_ENABLE(); /*ADC GPIO ConfigurationPA0     ------> ADC_IN0PA1     ------> ADC_IN1PA4     ------> ADC_IN5*/GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4; // 指定 PA0/1/4GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;                    // 设置为模拟端口GPIO_InitStruct.Pull = GPIO_PULLDOWN;                       // 下拉:无输入时采样值接近零HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);                     // 执行初始化}
}

按照厂家例程的文件组织,所有的 HAL_xxx_MspInit() 集中在 py32_f0xx_hal_msp.c 文件中,由于在 ADC_Init() 函数中调用了 HAL_ADC_Init() 函数,要调用 HAL_ADC_MspInit(),这个函数在 HAL 库中的原型是 weak 类型的,并且是一个空函数,因此需要在实用中重写。

当然,把 HAL_ADC_MspInit() 函数在 app_adc.c 文件中实现也是可以的。

修改 DEBUG 口的管脚映射

PY32F003 ADC1 的通道 0/1/5 复用了 PA0/1/4,之前的实验中,PA1/0 被用作了 DEBUG 口 UART2,和 ADC1 的通道是冲突的,所以需要把 DEBUG 口对应的管脚挪走。查了数据手册,AF4 组的 PA2/3 可以用作 UART2,修改 UART_Config() 如下。

除了修改管脚映射以外,中断优先级等的不做修改。

HAL_StatusTypeDef USART_Config(void)
{// Using PA2/PA3 (TX/RX)HAL_StatusTypeDef conf_res = HAL_OK;GPIO_InitTypeDef GPIO_InitStruct;gUartInited = 0;    //====================// USART2初始化//====================__HAL_RCC_USART2_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();UartHandle.Instance = USART2;UartHandle.Init.BaudRate = 115200;UartHandle.Init.WordLength = UART_WORDLENGTH_8B;UartHandle.Init.StopBits = UART_STOPBITS_1;UartHandle.Init.Parity = UART_PARITY_NONE;UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;UartHandle.Init.Mode = UART_MODE_TX_RX;conf_res = HAL_UART_Init(&UartHandle);if(conf_res != HAL_OK) return conf_res;/**USART2 GPIO ConfigurationPA2     ------> USART2_TXPA3     ------> USART2_RX*/GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF4_USART2;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_NVIC_SetPriority(USART2_IRQn, 0, 3);    // 使能NVICHAL_NVIC_EnableIRQ(USART2_IRQn);            // 使能USART2中断gUartInited = 1;return conf_res;
}

在 main.c 的主循环中采样

int main(void)
{HAL_Init();             // systick初始化SystemClock_Config();   // 配置系统时钟GPIO_Config();if(USART_Config() != HAL_OK) Error_Handler();         printf("[SYS_INIT] Debug port initilaized.\r\n");ADC_Init();printf("[SYS_INIT] ADC initilaized.\r\n");printf("\r\n+---------------------------------------+""\r\n|        PY32F003 MCU is ready.         |""\r\n+---------------------------------------+""\r\n         10 digits sent to you!          ""\r\n+---------------------------------------+""\r\n");if (DBG_UART_Start() != HAL_OK) Error_Handler();char sres[64]={0};uint8_t sIndex = 0;while (1){ BSP_LED_Toggle(LED3);if(sIndex % 2 == 0){if(ADC_Sample(sres) == HAL_OK){printf("%s\r\n", sres);}else{printf("Sample error.\r\n");}}sIndex ++;}HAL_Delay(500);
}

代码中,主循环每 0.5s 翻转一次 LED,每 1s 采样一次。

实验结果

初次跑通

按照上述步骤编写好代码,编译烧录,在 XCOM 上得到的结果如图。初次运行,PA0/1/4 出于悬空状态,得到的采样值是随机的。

注意到在 HAL_ADC_MspInt() 函数中,将 PA0/1/4 这三个管脚的 PULL 属性都设置成了 PULLDOWN,本想着即使悬空的话仍可得到接近 0 的采样值。但实验结果中,PA0 的悬空状态采样值仍在 1480 多的值,折合成电压为

  1480/4096*3.3 = 1.192V

这个值挺高的,而 PA1/4 管脚换算得到的电压值分别为 0.661/0.524V,这两个值也不低。这说明 PY32F003 的内部下拉应该是“弱下拉”——或许,在 HAL_ADC_Init() 函数中又对这几个管脚做了什么配置?这个问题留着以后关注。

基于此,在实际项目中用到 PY32F003 进行 ADC 时,在信号管脚接入前,要使用一个(或一组)运放做一下电压跟随才好。

采样时长

在 HAL_ADC_ConfigChannel() 中,设置了采样周期均为 71.5,加上转换的耗费 12.5 周期,合计84 个时钟周期,计算得到采样时间为 3.5us 一次,也挺快了了。

对 GND 和 VCC 的采样值

将 PA0 接地,然后再观察其采样值,得到了全“0”的采样结果。

将 PA0 接 3.3V 管脚,50次采样得到的平均值是 4087.22,换算得到 3.293V,也还好。

PULLUP 还是 PULLDOWN,还是 NOPULL?

把 PA0/1/4 都设置为内部上拉/下拉/无上下拉状态时,PA0 接地,测得 PA1/4 的采用值分别是:

PULLUP:2.159/2.191V,PULLDOWN:0.242/0.322V,NOPULL:1.990/3.061V

PA1和PA4的特性略有不同。

PA0 得到的采样值均为0,这说明管脚的 PULL 被初始化的状态不会对采样的测量值产生影响。

在 PA0 接 VCC 时,不论其 PULL 属性如何,对采样值也没有影响。

总结

  • 根据厂家例程移植,跑通 ADC 的轮询式采样是比较简单的。如果熟悉对 STM32 的 ADC 配置,可以照搬 STM32 的步骤。
  • 分配 ADC1 的采样通道时,要把开发板默认的 UART2 管脚和 ADC1 的采样通道管脚错开。
  • 当某一管脚配置为模拟信号时,其管脚的 PULL 属性对测量结果无影响。
  • 实用中,ADC1 的采样输入管脚最好使用运放做一个电压跟随器。
  • 0~VCC 中间值的采样精度如何,尚未验证,留待后续实验完成。

后续还会继续尝试使用 DMA 的 ADC,敬请期待。

谬误之处,恳请指正。

相关文章:

普冉(PUYA)单片机开发笔记(7): ADC-轮询式多路采样

概述 应用中经常会有使用单片机进行模数转换的需求。PY32F003 具有 1 个 12 位的模拟数字转换器&#xff08;ADC&#xff09;&#xff0c;今天我们一起来使用一下这个 ADC。 数据手册中对 ADC 简介如下。 SAR ADC&#xff1a;逐次逼近式 ADC&#xff0c;原理参见“参考链接&a…...

uniapp切换页面时报错问题

我们来看如下错误&#xff1a; 该错误的意思是不能切换到 tabbar 页面。tabbar页面通常是公共页面或者底部导航栏&#xff0c;如果我们用 navigateTo 或者 redirectTo 都不能实现页面切换。 我们有两种方式&#xff1a; 第一种是用 switchTab 来进行切换&#xff0c;但注意切…...

Nginx 简单入门操作

前言:之前的文章有些过就不罗嗦了。 Nginx 基础内容 是什么? Nginx 是一个轻量级的 HTTP 服务器,采用事件驱动、异步非阻塞处理方式的服务器,它具有极好的 IO 性能,常用于 HTTP服务器(包含动静分离)、正向代理、反向代理、负载均衡 等等. Nginx 和 Node.js 在很多方…...

ChatGPT是科学还是艺术?

OpenAI最近谈到GPT4变懒的问题&#xff0c;说“它更像是多人共同参与的艺术创作”&#xff0c;那到底大模型是科学还是艺术&#xff1f;...

线程及实现方式

一、线程 线程是一个基本的CPU执行单元&#xff0c;也是程序执行流的最小单位。引入线程之后&#xff0c;不仅是进程之间可以并发&#xff0c;进程内的各线程之间也可以并发&#xff0c;从而进一步提升了系统的并发度&#xff0c;使得一个进程内也可以并发处理各种任务&#x…...

2023年11月10日 Go生态洞察:十四年Go的成长之路

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

OpenSSL 编程指南

目录 前言初始化SSL库创建SSL 上下文接口(SSL_CTX)安装证书和私钥加载证书(客户端/服务端证书)加载私钥/公钥加载CA证书设置对端证书验证例1 SSL服务端安装证书例2 客户端安装证书创建和安装SSL结构建立TCP/IP连接客户端创建socket服务端创建连接创建SSL结构中的BIOSSL握手服务…...

js优化技巧

一、使用箭头函数简化函数定义 function add(a,b){return a b; }//箭头函数 const add (a,b) > a b;二、使用解构赋值简化变量声明 const firstName person.firstName; const lastName person.lastName;//解构赋值 const {firstName,lastName} person三、使用模板字…...

深入探索 Java 反射机制

文章目录 什么是 Java 反射&#xff1f;反射的核心类和接口反射的基本用法获取 Class 对象的三种方式创建对象实例访问字段和方法调用构造方法 反射的使用场景注意事项结语 Java反射&#xff08;Reflection&#xff09;是指在运行时获取类的信息&#xff0c;特别是获取其属性、…...

【ArcGIS Pro微课1000例】0054:Pro3.0创建数据库(文件数据库、移动数据库、企业级数据库)解读

文章目录 一、三种类型数据库解读二、三种类型数据库创建1. 文件数据库2. 移动数据库3. 企业级数据库三、注意事项一、三种类型数据库解读 ArcGIS Pro中主要有三种数据库类型,它们分别是:文件地理数据库、移动地理数据库和企业级地理数据库。它们的区别如下: 存储方式:文件…...

【漏洞复现】华脉智联指挥调度平台命令执行漏洞

Nx01 产品简介 深圳市华脉智联科技有限公司&#xff0c;融合通信系统将公网集群系统、专网宽带集群系统、不同制式、不同频段的短波/超短波对讲、模拟/数字集群系统、办公电话系统、广播系统、集群单兵视频、视频监控系统、视频会议系统等融为一体&#xff0c;集成了专业的有线…...

leetcode第119场双周赛 - 2023 - 12 - 9

比赛地址 : https://leetcode.cn/contest/biweekly-contest-119/ t1 : 直接哈希表 加 暴力 统计就行了 class Solution { public:vector<int> findIntersectionValues(vector<int>& nums1, vector<int>& nums2) {unordered_map<int,int>…...

05. 函数式编程

目录 1、前言 2、什么是函数式编程 2.1、函数是一等公民 2.2、避免状态和可变数据 3、函数式编程的核心概念 3.1、高阶函数 3.2、Lambda&#xff08;匿名函数&#xff09; 3.3、递归 & 尾递归优化 3.4、functools模块 3.4.1、partial 3.4.2、reduce 3.4.3、lru_…...

Linux权限(用户角色+文件权限属性)

Linux权限 文章目录 Linux权限一.文件权限1.快速掌握修改权限的方法&#xff08;修改文件权限属性&#xff09;2.对比权限的有无&#xff0c;以及具体的体现3.修改权限的第二套方法&#xff08;修改用户角色&#xff09;4.文件类型&#xff08;Linux下一切皆文件&#xff09; 二…...

短波红外相机的原理及应用场景

短波红外 (简称SWIR&#xff0c;通常指0.9~1.7μm波长的光线) 是一种比可见光波长更长的光。这些光不能通过“肉眼”看到&#xff0c;也不能用“普通相机”检测到。由于被检测物体的材料特性&#xff0c;一些在可见光下无法看到的特性&#xff0c;却能在近红外光下呈现出来&…...

【PyTorch】softmax回归

文章目录 1.理论介绍2. 代码实现2.1. 主要代码2.2. 完整代码2.3. 输出结果 3. Q&A3.1. 运行过程中出现以下警告&#xff1a;3.2. 定义的神经网络中的nn.Flatten()的作用是什么&#xff1f;3.3. num_workers有什么作用&#xff1f;它的值怎么确定&#xff1f; 1.理论介绍 背…...

12.8 作业 C++

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否为…...

10.机器人系统仿真(urdf集成gazebo、rviz)

目录 1 机器人系统仿真的必要性与本篇学习目的 1.1 机器人系统仿真的必要性 1.2 一些概念 URDF是 Unified Robot Description Format 的首字母缩写&#xff0c;直译为统一(标准化)机器人描述格式&#xff0c;可以以一种 XML 的方式描述机器人的部分结构&#xff0c;比如底盘…...

城市基础设施智慧路灯改造的特点

智慧城市建设稳步有序推进。作为智慧城市的基础设施&#xff0c;智能照明是智慧城市的重要组成部分&#xff0c;而叁仟智慧路灯是智慧城市理念下的新产品。随着物联网和智能控制技术的飞速发展&#xff0c;路灯被赋予了新的任务和角色。除了使道路照明智能化和节能化外&#xf…...

配置BFD多跳检测示例

BFD简介 定义 双向转发检测BFD&#xff08;Bidirectional Forwarding Detection&#xff09;是一种全网统一的检测机制&#xff0c;用于快速检测、监控网络中链路或者IP路由的转发连通状况。 目的 为了减小设备故障对业务的影响&#xff0c;提高网络的可靠性&#xff0c;网…...

爬虫学习-基础库的使用(requests)

目录 一、安装以及实例引入 &#xff08;1&#xff09;requests库下载 &#xff08;2&#xff09;实例测试 二、GET请求 &#xff08;1&#xff09;基本实例 &#xff08;2&#xff09;抓取网页 &#xff08;3&#xff09;抓取二进制数据 &#xff08;4&#xff09;添…...

4.8 构建onnx结构模型-Less

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以 Less 结点进行分析 方式 方法一&a…...

Java调试技巧之垃圾回收机制解析

Java作为一种高级编程语言&#xff0c;以其跨平台、面向对象、自动内存管理等特性而广受开发者的喜爱。其中&#xff0c;自动内存管理是Java的一大亮点&#xff0c;通过垃圾回收机制实现对内存的自动分配和释放&#xff0c;极大地简化了开发者的工作。本文将深入探讨Java的垃圾…...

logstash插件简单介绍

logstash插件 输入插件(input) Input&#xff1a;输入插件。 Input plugins | Logstash Reference [8.11] | Elastic 所有输入插件都支持的配置选项 SettingInput typeRequiredDefaultDescriptionadd_fieldhashNo{}添加一个字段到一个事件codeccodecNoplain用于输入数据的…...

联邦多任务蒸馏助力多接入边缘计算下的个性化服务 | TPDS 2023

联邦多任务蒸馏助力多接入边缘计算下的个性化服务 | TPDS 2023 随着移动智能设备的普及和人工智能技术的发展,越来越多的分布式数据在终端被产生与收集&#xff0c;并以多接入边缘计算(MEC)的形式进行处理和分析。但是由于用户的行为模式与服务需求的多样,不同设备上的数据分布…...

【python爬虫】设计自己的爬虫 3. 文件数据保存封装

考虑到爬取的多媒体文件要保存到本地&#xff0c;因此封装了一个类来专门处理这样的问题&#xff0c;下面看代码&#xff1a; class FileStore:def __init__(self, file_path, read_file_moder,write_file_modewb):"""初始化 FileStore 实例Parameters:- file_…...

pta模拟题——7-34 刮刮彩票

“刮刮彩票”是一款网络游戏里面的一个小游戏。如图所示&#xff1a; 每次游戏玩家会拿到一张彩票&#xff0c;上面会有 9 个数字&#xff0c;分别为数字 1 到数字 9&#xff0c;数字各不重复&#xff0c;并以 33 的“九宫格”形式排布在彩票上。 在游戏开始时能看见一个位置上…...

【补题】 1

蓝桥杯小白赛 ​​​​​​​3.小蓝的金牌梦【算法赛】 - 蓝桥云课 (lanqiao.cn) 数组长度为质数&#xff0c;最大的子数组和 素数 前缀和 #include "bits/stdc.h" using namespace std; #define int long long #define N 100010 int ans[N];int s[N];vector&l…...

IP地址定位技术为网络安全建设提供全新方案

随着互联网的普及和数字化进程的加速&#xff0c;网络安全问题日益引人关注。网络攻击、数据泄露、欺诈行为等安全威胁层出不穷&#xff0c;对个人隐私、企业机密和社会稳定构成严重威胁。在这样的背景下&#xff0c;IP地址定位技术应运而生&#xff0c;为网络安全建设提供了一…...

Redis中HyperLogLog的使用

目录 前言 HyperLogLog 前言 在学习HyperLogLog之前&#xff0c;我们需要先学习两个概念 UV&#xff1a;全称Unique Visitor&#xff0c;也叫独立访客量&#xff0c;是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站&#xff0c;只记录1次。PV&am…...