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

【星云 Orbit-STM32F4】07. 用判断数据尾来接收据的串口通用程序框架

【星云 Orbit-STM32F4】用判断数据尾来接收一串数据的串口通用程序框架

摘要

本文介绍了一种基于STM32F407微控制器的串口数据接收通用程序框架。该框架通过判断数据尾来实现一串数据的完整接收,适用于需要可靠数据传输的应用场景。本文从零开始,详细讲解了STM32F407串口基础知识、配置步骤、HAL库函数详解,并提供了完整的代码示例和注释。目标读者为嵌入式开发小白,内容通俗易懂,适合快速上手。


1. 引言

在嵌入式开发中,串口通信是一种常用的通信方式。本文旨在解决一个常见问题:如何通过STM32F407的串口接收一串数据,并通过判断数据尾来确保数据的完整性。

本文将从零开始,逐步讲解以下内容:

  • 基础知识:STM32F407串口的基本概念和工作机制。
  • 配置步骤:如何手动配置STM32F407的串口(不使用STM32CubeMX)。
  • HAL库函数详解:如何使用STM32 HAL库实现串口接收功能。
  • 代码实现:提供完整的代码框架和注释。
  • 使用示例:通过实际案例展示如何使用该框架。

2. 基础知识

2.1 STM32F407的串口

STM32F407芯片集成了多个USART(Universal Synchronous Asynchronous Receiver Transmitter)模块,支持同步和异步通信模式。本文将使用USART1模块。

2.2 数据尾判断

在串口通信中,数据通常以帧的形式传输。为了确保数据的完整性,我们需要通过特定的标志(数据尾)来判断一帧数据是否传输完成。例如,可以使用固定的字节序列(如 0xEB 0x00 0x55)作为数据尾。

2.3 数据接收流程

数据接收流程如下:

  1. 初始化:配置串口参数(波特率、数据位、停止位等)。
  2. 接收数据:通过中断或轮询方式接收数据。
  3. 判断数据尾:在接收到数据后,检查是否包含数据尾标志。
  4. 处理数据:如果检测到数据尾,提取有效数据并进行后续处理。

3. 配置步骤

3.1 时钟配置

在使用串口之前,需要配置时钟系统。以下是关键配置步骤:

  1. 启用AHB1时钟:确保USART1时钟被启用。
  2. 配置系统时钟:设置系统时钟频率(本文假设为110.592 MHz)。
// 配置时钟
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;  // 启用GPIOA时钟
RCC->APB2ENR |= RCC_APB2ENR_USART1EN; // 启用USART1时钟

3.2 GPIO配置

配置GPIO引脚用于串口通信。本文使用PA9(TX)和PA10(RX)。

// 配置GPIO
GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF7_USART1;HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

3.3 USART配置

配置USART参数,包括波特率、数据位、停止位和校验位。

// 配置USART
UART_HandleTypeDef huart1;huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_RX | UART_MODE_TX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;HAL_UART_Init(&huart1);

3.4 中断配置

启用USART接收中断。

// 配置中断NVIC_EnableIRQ(USART1_IRQn);

4. HAL库函数详解

4.1 HAL_UART_Init

初始化USART模块。

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart, UART_InitTypeDef *pInitStruct)

4.2 HAL_UART_Transmit

发送数据。

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

4.3 HAL_UART_Receive_IT

启用接收中断。

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

4.4 USART1_IRQHandler

USART中断服务函数。

void USART1_IRQHandler(void)
{if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET){// 处理接收数据}
}

5. 代码实现

5.1 初始化函数

void SystemClock_Config(void)
{// 配置系统时钟
}void MX_USART1_UART_Init(void)
{// 配置USART1
}void MX_GPIO_Init(void)
{// 配置GPIO
}

5.2 数据接收函数

void USART1_IRQHandler(void)
{static uint8_t rxBuffer[RC_BUFFER_SIZE] = {0};static uint16_t rxIndex = 0;if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET){rxBuffer[rxIndex++] = HAL_UART_Read_RX(&huart1);if (rxIndex >= RC_BUFFER_SIZE){// 数据尾判断if (CheckDataTail(rxBuffer, rxIndex)){// 处理数据ProcessData(rxBuffer, rxIndex);rxIndex = 0;}}}
}

5.3 数据处理函数

bool CheckDataTail(uint8_t *data, uint16_t length)
{// 检查数据尾
}void ProcessData(uint8_t *data, uint16_t length)
{// 处理数据
}

6. 使用示例

6.1 初始化

int main(void)
{// 初始化HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();// 启用接收中断HAL_UART_Receive_IT(&huart1, rxBuffer, RC_BUFFER_SIZE);while (1){// 主循环}
}

6.2 数据接收

void USART1_IRQHandler(void)
{// 中断处理
}

7. 总结

本文提供了一种基于STM32F407的串口数据接收通用程序框架。通过判断数据尾,确保了数据的完整性。本文从零开始,详细讲解了配置步骤和代码实现,适合嵌入式开发小白快速上手。


8. 附录

8.1 完整代码

#include "stm32f4xx_hal.h"#define RC_BUFFER_SIZE 100  // 接收缓冲区大小
#define DATA_TAIL_SIZE 3    // 数据尾长度uint8_t rxBuffer[RC_BUFFER_SIZE] = {0};
uint16_t rxIndex = 0;UART_HandleTypeDef huart1;void SystemClock_Config(void)
{// 配置系统时钟RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 25;RCC_OscInitStruct.PLL.PLLN = 336;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;RCC_OscInitStruct.PLL.PLLQ = 7;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){// 配置错误while (1);}RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){// 配置错误while (1);}
}void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStructure.Pin = GPIO_PIN_9 | GPIO_PIN_10;GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStructure.Alternate = GPIO_AF7_USART1;HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
}void MX_USART1_UART_Init(void)
{huart1.Instance = USART1;huart1.Init.BaudRate = 9600;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_RX | UART_MODE_TX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK){// 配置错误while (1);}// 启用接收中断HAL_UART_Receive_IT(&huart1, rxBuffer, RC_BUFFER_SIZE);
}void USART1_IRQHandler(void)
{if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET){rxBuffer[rxIndex++] = HAL_UART_Read_RX(&huart1);if (rxIndex >= RC_BUFFER_SIZE){if (CheckDataTail(rxBuffer, rxIndex)){ProcessData(rxBuffer, rxIndex);rxIndex = 0;}}}
}bool CheckDataTail(uint8_t *data, uint16_t length)
{if (length < DATA_TAIL_SIZE){return false;}// 检查数据尾if (data[length - 3] == 0xEB && data[length - 2] == 0x00 && data[length - 1] == 0x55){return true;}return false;
}void ProcessData(uint8_t *data, uint16_t length)
{// 处理数据
}int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();while (1){// 主循环}
}

8.2 思维导图

以下是基于STM32F407的串口数据接收程序框架的思维导图:

在这里插入图片描述

流程图说明

  1. 开始:程序启动。

  2. 系统初始化:配置STM32F407的硬件和外设。
    • 配置时钟:配置系统时钟,确保外设时钟正确。
    • 配置GPIO:配置与USART相关的GPIO引脚(如TX和RX引脚)。
    • 配置USART:初始化USART外设,设置波特率、数据位、停止位和校验位。
  3. 数据接收:启用USART的接收中断,等待数据接收。
    • 启用接收中断:配置USART的中断,使能接收中断。
    • 中断服务函数:当接收到数据时,进入中断服务函数,读取接收到的数据。
  4. 数据处理:对接收到的数据进行处理。
    • 检查数据尾:检查数据是否完整,确认数据尾。
    • 处理数据:对接收到的数据进行解析或存储。
  5. 主循环:程序进入主循环,执行轮询任务。
    • 执行轮询任务:在主循环中,执行一些周期性任务(如状态监控、按键扫描等)。
  6. 结束:程序结束。

8.3 状态转换图

在这里插入图片描述

  1. 初始化:程序开始,进入初始化状态。
  2. 配置时钟:配置系统时钟,确保外设时钟正确。
  3. 配置GPIO:配置与USART相关的GPIO引脚(如TX和RX引脚)。
  4. 配置USART:初始化USART外设,设置波特率、数据位、停止位和校验位。
  5. 启用接收中断:配置USART的中断,使能接收中断。
  6. 接收数据:等待数据接收。
  7. 接收中断:当接收到数据时,触发中断服务函数。
  8. 读取数据:在中断服务函数中,读取接收到的数据。
  9. 检查数据尾:检查数据尾是否存在,以确定数据是否完整。
  10. 数据尾存在:如果检测到数据尾,处理数据。
  11. 处理数据:对接收到的数据进行解析或存储。
  12. 重置接收索引:在数据处理完成后,重置接收索引,准备接收新的数据。
  13. 数据尾不存在:如果未检测到数据尾,继续接收数据。
  14. 主循环:程序进入主循环,执行轮询任务。
  15. 执行轮询任务:在主循环中,执行一些周期性任务(如状态监控、按键扫描等)。
  16. 结束:程序结束。

相关文章:

【星云 Orbit-STM32F4】07. 用判断数据尾来接收据的串口通用程序框架

【星云 Orbit-STM32F4】用判断数据尾来接收一串数据的串口通用程序框架 摘要 本文介绍了一种基于STM32F407微控制器的串口数据接收通用程序框架。该框架通过判断数据尾来实现一串数据的完整接收&#xff0c;适用于需要可靠数据传输的应用场景。本文从零开始&#xff0c;详细讲…...

授权与认证之jwt(一)创建Jwt工具类

JWT的Token要经过加密才能返回给客户端&#xff0c;包括客户端上传的Tokn,后端项目需要验证核 实。于是我们需要一个WT工具类&#xff0c;用来加密Token和验证Token的有效性。 一、导入依赖 <dependency><groupId>com.auth0</groupId><artifactId>jav…...

Kubernetes Service服务发现dns之CoreDNS

文章目录 背景什么是Service、服务发现、Endpoint什么是CoreDNSCoreDNS 的工作原理 常用命令coredns 运行状态根据服务名&#xff0c;判断某个服务dns解析是否正常 背景 Kubernetes 集群内部的服务发现是微服务架构的核心基础&#xff0c;而 DNS 服务则是实现这一机制的关键组…...

Spring Boot 测试:单元、集成与契约测试全解析

一、Spring Boot 分层测试策略 Spring Boot 应用采用经典的分层架构&#xff0c;不同层级的功能模块对应不同的测试策略&#xff0c;以确保代码质量和系统稳定性。 Spring Boot 分层架构&#xff1a; Spring Boot分层架构 A[客户端] -->|HTTP 请求| B[Controller 层] …...

用友NC系列漏洞检测利用工具

声明&#xff01;本文章所有的工具分享仅仅只是供大家学习交流为主&#xff0c;切勿用于非法用途&#xff0c;如有任何触犯法律的行为&#xff0c;均与本人及团队无关&#xff01;&#xff01;&#xff01; 目录标题 YongYouNcTool启动及适配环境核心功能界面预览一键检测命令执…...

PostgreSQL 创建表格

PostgreSQL 创建表格 在数据库管理中&#xff0c;表格&#xff08;Table&#xff09;是数据存储的基础。PostgreSQL作为一款强大的开源对象关系型数据库管理系统&#xff08;ORDBMS&#xff09;&#xff0c;创建表格是其最基本的功能之一。本文将详细讲解如何在PostgreSQL中创…...

一周一个Unity小游戏2D反弹球游戏 - 球的死区及球重生

前言 本文将实现当球弹到球板下方的死亡区域后,球会被重置到球板上发射点,并且重置物理状态的逻辑。 创建球的死亡区 之前创建的在屏幕下方的空气墙碰撞体可以将其Is Trigger勾选上,让其成为一个触发器,用来检测球是否进入该区域,如下。 创建一个脚本名为Deadzone…...

本地部署 DeepSeek:从 Ollama 配置到 Spring Boot 集成

前言 随着人工智能技术的迅猛发展&#xff0c;越来越多的开发者希望在本地环境中部署和调用 AI 模型&#xff0c;以满足特定的业务需求。本文将详细介绍如何在本地环境中使用 Ollama 配置 DeepSeek 模型&#xff0c;并在 IntelliJ IDEA 中创建一个 Spring Boot 项目来调用该模型…...

vue3:三项目增加404页面

一、路由添加 1、官网地址 带参数的动态路由匹配 | Vue Routerhttps://router.vuejs.org/zh/guide/essentials/dynamic-matching.html 2、复制核心语句 { path: /:pathMatch(.*)*, name: NotFound, component: NotFound } 3、粘贴到路由index.js中 4、建立页面 在view文件夹…...

MCAL(Microcontroller Abstraction Layer)介绍

目录 MCAL的核心作用 MCAL的模块组成 1. 微控制器驱动&#xff08;Microcontroller Drivers&#xff09; 2. I/O驱动&#xff08;DIO, PWM, ADC等&#xff09; 3. 通信驱动&#xff08;Communication Drivers&#xff09; 4. 存储驱动&#xff08;Memory Drivers&#xf…...

爬虫:PhantomJS的详细使用和实战案例

文章目录 一、PhantomJS介绍1.1 什么是 PhantomJS1.2 PhantomJS 的特点与优势二、PhantomJS 的安装2.1 在 macOS 上安装 PhantomJS2.2 在 Linux 上安装 PhantomJS2.3 在 Windows 上安装 PhantomJS2.4 验证安装三、PhantomJS 的基本使用3.1 示例 1:打开网页并截图3.2 示例 2:获…...

目标检测——数据处理

1. Mosaic 数据增强 Mosaic 数据增强步骤: (1). 选择四个图像&#xff1a; 从数据集中随机选择四张图像。这四张图像是用来组合成一个新图像的基础。 (2) 确定拼接位置&#xff1a; 设计一个新的画布(输入size的2倍)&#xff0c;在指定范围内找出一个随机点&#xff08;如…...

深度学习工程师的技术图谱和学习路径

在构建一个深度学习工程师的技术图谱时,按照“技能树与能力模型”的结构可以帮助清晰地展示出技术体系的层次化关系,帮助学习者更好地理解每个技术点的依赖与顺序。 深度学习工程师的技术图谱和学习路径 以下是深度学习工程师的技能树,包括从基础到进阶的学习路径,以及对…...

Qt 文件操作+多线程+网络

文章目录 1. 文件操作1.1 API1.2 例子1&#xff0c;简单记事本1.3 例子2&#xff0c;输出文件的属性 2. Qt 多线程2.1 常用API2.2 例子1&#xff0c;自定义定时器 3. 线程安全3.1 互斥锁3.2 条件变量 4. 网络编程4.1 UDP Socket4.2 UDP Server4.3 UDP Client4.4 TCP Socket4.5 …...

如何使用ArcGIS Pro制作横向图例:详细步骤与实践指南

ArcGIS Pro&#xff0c;作为Esri公司推出的新一代地理信息系统&#xff08;GIS&#xff09;平台&#xff0c;以其强大的功能和灵活的操作界面&#xff0c;在地理数据处理、地图制作和空间分析等领域发挥着重要作用。 在地图制作过程中&#xff0c;图例作为地图的重要组成部分&…...

Kotlin 嵌套类和内部类

在Kotlin中&#xff0c;嵌套类&#xff08;Nested Class&#xff09;和内部类&#xff08;Inner Class&#xff09;是两种不同的类&#xff0c;它们在定义和使用上有一些区别。 1.嵌套类&#xff08;Nested Classes&#xff09;默认是静态的&#xff08;即等同于Java中的stati…...

蓝蝶(BlueStacks)模拟器Root、Magisk、LSPosed及Shamiko框架安装与过应用检测指南

蓝蝶&#xff08;BlueStacks&#xff09;模拟器Root、Magisk、LSPosed及Shamiko框架安装与过应用检测指南 蓝蝶bluestacks模拟器root和magisk以及Lsposed和shamiko框架的安装过应用检测 一、引言 蓝蝶&#xff08;BlueStacks&#xff09;模拟器是一款广受欢迎的安卓模拟器&…...

OpenCV计算摄影学(6)高动态范围成像(HDR imaging)

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 高动态范围成像&#xff08;HDR imaging&#xff09;是一种图像处理技术&#xff0c;旨在通过增加图像的动态范围来更准确地表示真实世界的亮度差…...

[ComfyUI][AI生图]如何在Comfyui中安装插件管理器

如何在ComfyUI便携版中安装插件管理器 在现代软件环境中,图形用户界面(GUI)提供了一种直观的方式来与应用程序交互。ComfyUI是一个出色的GUI框架,它使用户能够通过图形化方式配置和管理他们的应用程序。特别是ComfyUI的便携版,它允许用户在没有安装的情况下使用这一工具,…...

初探Ollama与deepseek

什么是Ollama&#xff1f;它与大模型有什么联系&#xff1f; 简单说&#xff0c;Ollama就像是你电脑上的一个 “大模型小助手”。 以前&#xff0c;很多强大的大语言模型&#xff0c;比如能回答各种问题、写文章、翻译等的那些模型&#xff0c;要么只能在网上的服务器上用&am…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...