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

【STM32-学习笔记-7-】USART串口通信

文章目录

  • USART串口通信
    • Ⅰ、硬件电路
    • Ⅱ、常见的电平标准
    • Ⅲ、串口参数及时序
    • Ⅳ、STM32的USART简介
      • 数据帧
      • 起始位侦测
      • 数据采样
      • 波特率发生器
    • Ⅴ、USART函数介绍
    • Ⅵ、USART_InitTypeDef结构体参数
      • 1、USART_BaudRate
      • 2、USART_WordLength
      • 3、USART_StopBits
      • 4、USART_Parity
      • 5、USART_Mode
      • 6、USART_HardwareFlowControl
    • Ⅶ、串口发送数据
      • 可变参数函数,模拟实现printf
    • Ⅷ、串口接收数据(包含发送)
    • Ⅸ、USART收发数据包
      • 1、收发HEX数据包
      • 2、收发文本数据包

USART串口通信

USARTUniversal Synchronous/Asynchronous Receiver/Transmitter,通用同步/异步收发器)是一种用于串行通信的硬件模块,它支持同步(需要SCL时钟线)和异步两种通信模式

Ⅰ、硬件电路

image-20241228154308723

  • TX 为发送端, RX 为接收端
  • 若是设备之间的电平标准不一致时,则需要加上电平转换芯片

Ⅱ、常见的电平标准

  1. TTL电平
    • 供电范围在0~5V
    • 输出:
      • 高电平1大于2.7V
      • 低电平0小于0.5V
    • 输入:
      • 高电平1大于2.0V
      • 低电平0小于0.8V
    • TTL电平输入脚悬空时内部认为是高电平,且TTL电平输出不能驱动CMOS电平输入
  2. CMOS电平
    • 供电范围在3~15V
    • 输出:
      • 高电平1大于4.6V
      • 低电平0小于0.05V
    • 输入:
      • 高电平1大于3.5V
      • 低电平0小于1.5V
  3. LVTTL电平
    • 是TTL的一种低功耗变种,供电电压通常小于等于3.3V
    • 输出:
      • 高电平1大于2.4V
      • 低电平0小于0.4V
    • 输入:
      • 高电平1大于2.0V
      • 低电平0小于0.8V
  4. RS232电平
    • 输出:
      • -5~-15V 输出1
      • +5~+15V 输出0
    • 输入:
      • -3~-15V 输入1
      • +3~+15V 输入0
  5. LVDS电平
    • 低电压差分信号,驱动器由驱动差分线对的电流源组成,电流通常为3.5mA
    • 接收器具有很高的输入阻抗,输入端允许信号上携带的直流偏置电平范围为0.227~2.173V
  6. RS485电平
    • 采用差分传输方式,输出A、B之间的电压差:高电平+2~+6V低电平-2~-6V
  • STM32使用的是TTL电平

Ⅲ、串口参数及时序

  1. 波特率(Baud Rate)
    • 波特率是串口通信中每秒传输的符号数,通常以bps(位/秒)为单位
    • 波特率必须在通信双方之间匹配,否则会导致数据传输错误
  2. 数据位(Data Bits)
    • 数据位是指每个字符中用于传输实际数据的位数
    • 常见的数据位设置有8位
  3. 停止位(Stop Bits)
    • 停止位是在每个字符传输结束后,用于标识字符结束的位数
    • 可以是1位、1.5位或2位停止位
  4. 奇偶校验(Parity)
    • 奇偶校验是一种错误检测机制,通过在数据位后面添加一个校验位来实现
    • 可以设置为无校验(None)、奇校验(Odd)、偶校验(Even)或标记/空格校验(Mark/Space)
  • 波特率:串口通信的速率

  • 起始位:标志一个数据帧的开始,固定为低电平

  • 数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行

  • 校验位:用于数据验证,根据数据位计算得来

  • 停止位:用于数据帧间隔,固定为高电平

  • 一个数据帧10位
    • 起始位:1bit
    • 数据位:8bit(1byte)
    • 停止位:1bit

image-20241228160015933

  • 一个数据帧11位
    • 起始位:1bit
    • 数据位:8bit
    • 校验位:1bit
    • 停止位:1bit

image-20241228160032152

  • 实测串口时序

image-20241228160155805

Ⅳ、STM32的USART简介

  • USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里

  • 自带波特率发生器,最高达4.5Mbits/s(可据此配置通讯的波特率

  • 可配置数据位长度(无校验位8bit,有校验位9bit)、停止位长度(0.5/1/1.5/2 确定了帧的间隔

  • 可选校验位(无校验/奇校验/偶校验)

  • 支持同步模式(有时钟CLK输出)、硬件流控制(可控的发送和接收数据)、DMA(串口支持DMA转运数据)、智能卡、IrDA、LIN

  • STM32F103C8T6 USART资源: USART1(挂载在上APB2总线上)、 USART(APB1)、 USART3(APB1

image-20241229145512719

  • 流控:
    • nCTS: 清除发送,若是高电平,在当前数据传输结束时阻断下一次的数据发送(判断对方是否准备好接收数据
    • nRTS: 发送请求,若是低电平,表明USART准备好接收数据(告诉对方自己是否准备好接收数据

image-20241229152925780

  • TXERXNE 是判断发送状态和接收状态的重要标志位

image-20241229165609863

  • TDRRDR都是通过DR寄存器来实现其功能

数据帧

image-20241229170041255

image-20241229172307272

起始位侦测

image-20241229172941339

数据采样

image-20241229173342805

  • 进行三次数据采样,增加容错
  • 采样时钟是波特率的16倍

波特率发生器

  • 发送器和接收器的波特率由波特率寄存器BRR里的DIV确定

  • 计算公式:

    • 波特率 = f P C L K 2 / 1 16 ∗ D I V 波特率 = \frac{f_{PCLK2/1} }{16 * DIV} 波特率=16DIVfPCLK2/1

    • 解释:PCLK1或PLCK2的时钟频率除以16倍的DIV

image-20241229174442754

  • DIV分为整数部分(12bit)和小数部分(4bit),整数部分高位补0,小数部分低位补0

Ⅴ、USART函数介绍

// 重置指定的USART为默认值
void USART_DeInit(USART_TypeDef* USARTx);// 初始化指定的USART,根据初始化结构体配置参数
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
// 初始化USART初始化结构体的默认值
void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
// 初始化指定的USART时钟,根据时钟初始化结构体配置参数
void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
// 初始化USART时钟初始化结构体的默认值
void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);// 开启或关闭指定的USART
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);// 开启或关闭USART的中断
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);// 开启或关闭USART的DMA请求
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);// 设置USART地址
void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address);// 配置USART唤醒模式
void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp);// 开启或关闭USART接收器唤醒功能
void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState);// 配置USART LIN断裂检测长度
void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength);// 开启或关闭USART LIN模式
void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState);// 通过USART发送数据
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
// 通过USART接收数据
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);// 发送USART断点信号
void USART_SendBreak(USART_TypeDef* USARTx);// 设置USART保护时间
void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime);// 设置USART预分频器
void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler);// 开启或关闭USART智能卡模式
void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState);
// 开启或关闭USART智能卡NACK应答
void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState);
// 开启或关闭USART半双工模式
void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState);// 开启或关闭USART 8位过采样模式
void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState);// 开启或关闭USART单线方法
void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState);// 配置USART IrDA模式
void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode);// 开启或关闭USART IrDA模式
void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);// 获取USART标志状态
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
// 清除USART标志
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);// 获取USART中断状态
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
// 清除USART中断待处理位
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);

Ⅵ、USART_InitTypeDef结构体参数

成员名称描述
uint32_t USART_BaudRateUSART通信波特率,使用公式计算:IntegerDivider = ((PCLKx) / (16 * USART_BaudRate))
uint16_t USART_WordLength指定每帧传输或接收的数据位数量,可以是8位、9位等,取决于@ref USART_Word_Length
uint16_t USART_StopBits指定传输的停止位数量,可以是1位或2位,取决于@ref USART_Stop_Bits
uint16_t USART_Parity指定奇偶校验模式,包括奇校验、偶校验或无校验,取决于@ref USART_Parity
uint16_t USART_Mode指定是否启用接收或发送模式,取决于@ref USART_Mode
uint16_t USART_HardwareFlowControl指定是否启用硬件流控制模式,如RTS/CTS,取决于@ref USART_Hardware_Flow_Control成员名称

1、USART_BaudRate

  • 类型uint32_t(无符号32位整数)
  • 用途配置USART通信的波特率
  • 说明:通过设置这个成员,可以定义USART通信的速率,即每秒传输的比特数。波特率的计算涉及到外设时钟频率(PCLKx)和这个成员的值。计算公式如前所述,用于确定整数除数和分数除数,以设置USART的时钟分频,确保正确的波特率

2、USART_WordLength

  • 类型uint16_t(无符号16位整数)

  • 用途指定每帧传输或接收的数据位数量

  • 说明:这个参数决定了数据帧中数据位的长度。它可以是8位、9位等,具体值取决于@ref USART_Word_Length枚举

    • @ref USART_Word_Length:

    • 配置USART(通用同步/异步收发传输器)的数据位长度

      宏定义

      1. USART_WordLength_8b
        • ((uint16_t)0x0000)
        • 描述:定义了一个8位数据长度的宏。当USART配置为8位数据长度时,每个数据帧包含8个数据位
      2. USART_WordLength_9b
        • ((uint16_t)0x1000)
        • 描述:定义了一个9位数据长度的宏。当USART配置为9位数据长度时,每个数据帧包含9个数据位

      宏函数

      1. IS_USART_WORD_LENGTH(LENGTH)
        • 描述:这是一个宏函数,用于检查给定的数据位长度是否有效
        • 参数LENGTH,代表USART的数据位长度
        • 功能:检查LENGTH是否等于USART_WordLength_8bUSART_WordLength_9b
        • 返回值:如果LENGTH有效,返回1(真),否则返回0(假)

      表格:

      宏定义描述
      USART_WordLength_8b0x00008位数据长度
      USART_WordLength_9b0x10009位数据长度
      宏函数描述
      IS_USART_WORD_LENGTH(LENGTH)检查LENGTH是否为有效的USART数据位长度

3、USART_StopBits

  • 类型uint16_t(无符号16位整数)

  • 用途指定传输的停止位数量

  • 说明:这个参数定义了在数据帧结束后传输的停止位的数量,可以是1位或2位,具体值取决于@ref USART_Stop_Bits枚举

    • @ref USART_Stop_Bits:

    • 定义了USART(通用同步/异步收发传输器)的停止位配置

      宏定义

      1. USART_StopBits_1
        • ((uint16_t)0x0000)
        • 描述:定义了一个1个停止位的宏。在USART通信中,1个停止位是最常见的配置
      2. USART_StopBits_0_5
        • ((uint16_t)0x1000)
        • 描述:定义了0.5个停止位的宏。这种配置不常见,主要用于某些特定的通信协议
      3. USART_StopBits_2
        • ((uint16_t)0x2000)
        • 描述:定义了2个停止位的宏。这种配置用于提高数据传输的可靠性,特别是在噪声较大的通信环境中
      4. USART_StopBits_1_5
        • ((uint16_t)0x3000)
        • 描述:定义了1.5个停止位的宏。这种配置同样不常见,主要用于某些特定的通信协议

      宏函数

      1. IS_USART_STOPBITS(STOPBITS)
        • 描述:这是一个宏函数,用于检查给定的停止位设置是否有效
        • 参数STOPBITS,代表USART的停止位设置
        • 功能:检查STOPBITS是否等于USART_StopBits_1USART_StopBits_0_5USART_StopBits_2USART_StopBits_1_5中的任一个
        • 返回值:如果STOPBITS有效,返回1(真),否则返回0(假)

      表格:

      宏定义描述
      USART_StopBits_10x00001个停止位
      USART_StopBits_0_50x10000.5个停止位
      USART_StopBits_20x20002个停止位
      USART_StopBits_1_50x30001.5个停止位
      宏函数描述
      IS_USART_STOPBITS(STOPBITS)检查STOPBITS是否为有效的USART停止位设置

4、USART_Parity

  • 类型uint16_t(无符号16位整数)

  • 用途指定奇偶校验模式

  • 说明:这个参数决定了是否启用奇偶校验,以及使用哪种类型的校验(奇校验、偶校验或无校验)。当启用校验时,计算出的校验位会被插入到传输数据的最高有效位(MSB)位置。具体值取决于@ref USART_Parity枚举

    • @ref USART_Parity:

    • 定义了USART(通用同步/异步收发传输器)的奇偶校验配置

      宏定义

      1. USART_Parity_No
        • ((uint16_t)0x0000)
        • 描述:定义了一个无奇偶校验的宏。当设置为无奇偶校验时,USART通信不包含校验位
      2. USART_Parity_Even
        • ((uint16_t)0x0400)
        • 描述:定义了一个偶校验的宏。当设置为偶校验时,USART通信中的数据帧会包含一个校验位,使得数据位加上校验位的总和为偶数
      3. USART_Parity_Odd
        • ((uint16_t)0x0600)
        • 描述:定义了一个奇校验的宏。当设置为奇校验时,USART通信中的数据帧会包含一个校验位,使得数据位加上校验位的总和为奇数

      宏函数

      1. IS_USART_PARITY(PARITY)
        • 描述:这是一个宏函数,用于检查给定的奇偶校验设置是否有效
        • 参数PARITY,代表USART的奇偶校验设置
        • 功能:检查PARITY是否等于USART_Parity_NoUSART_Parity_EvenUSART_Parity_Odd中的任一个
        • 返回值:如果PARITY有效,返回1(真),否则返回0(假)

      表格:

      宏定义描述
      USART_Parity_No0x0000无奇偶校验
      USART_Parity_Even0x0400偶校验
      USART_Parity_Odd0x0600奇校验
      宏函数描述
      IS_USART_PARITY(PARITY)检查PARITY是否为有效的USART奇偶校验设置

5、USART_Mode

  • 类型uint16_t(无符号16位整数)

  • 用途指定是否启用接收或发送模式

  • 说明:这个参数决定了USART是处于接收模式、发送模式,还是两者都启用。具体值取决于@ref USART_Mode枚举

    • @ref USART_Mode:

    • 定义了USART(通用同步/异步收发传输器)的工作模式

      宏定义

      1. USART_Mode_Rx
        • ((uint16_t)0x0004)
        • 描述:定义了一个仅接收模式的宏。当设置为仅接收模式时,USART仅用于接收数据
      2. USART_Mode_Tx
        • ((uint16_t)0x0008)
        • 描述:定义了一个仅发送模式的宏。当设置为仅发送模式时,USART仅用于发送数据

      宏函数

      1. IS_USART_MODE(MODE)
        • 描述:这是一个宏函数,用于检查给定的工作模式设置是否有效
        • 参数MODE,代表USART的工作模式设置
        • 功能:检查MODE是否为有效的接收模式、发送模式或两者的组合(即接收和发送模式)。它通过与0xFFF3进行按位与操作来确保只有接收和发送模式位被设置,其他位应为0。同时,也检查MODE不为0,因为0表示没有启用任何模式
        • 返回值:如果MODE有效,返回1(真),否则返回0(假)

      表格:

      宏定义描述
      USART_Mode_Rx0x0004仅接收模式
      USART_Mode_Tx0x0008仅发送模式
      宏函数描述
      IS_USART_MODE(MODE)检查MODE是否为有效的USART工作模式设置

6、USART_HardwareFlowControl

  • 类型uint16_t(无符号16位整数)

  • 用途指定是否启用硬件流控制模式

  • 说明:硬件流控制用于控制数据的传输速率,以防止接收器溢出。这个参数决定了是否启用硬件流控制,如RTS/CTS(请求发送/清除发送)。具体值取决于@ref USART_Hardware_Flow_Control枚举

    • @ref USART_Hardware_Flow_Control:

    • 定义了USART(通用同步/异步收发传输器)的硬件流控制配置

      宏定义解释

      1. USART_HardwareFlowControl_None
        • ((uint16_t)0x0000)
        • 描述:定义了一个无硬件流控制的宏。当设置为无硬件流控制时,USART通信不使用任何硬件流控制信号
      2. USART_HardwareFlowControl_RTS
        • ((uint16_t)0x0100)
        • 描述:定义了一个仅使用请求发送(RTS)信号的硬件流控制宏。RTS信号用于通知接收设备是否准备好接收数据
      3. USART_HardwareFlowControl_CTS
        • ((uint16_t)0x0200)
        • 描述:定义了一个仅使用清除发送(CTS)信号的硬件流控制宏。CTS信号用于通知发送设备是否应该开始发送数据
      4. USART_HardwareFlowControl_RTS_CTS
        • ((uint16_t)0x0300)
        • 描述:定义了一个同时使用RTS和CTS信号的硬件流控制宏。这种配置提供了双向的硬件流控制,以确保数据传输的同步和可靠性

      宏函数

      1. IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)
        • 描述:这是一个宏函数,用于检查给定的硬件流控制设置是否有效
        • 参数CONTROL,代表USART的硬件流控制设置
        • 功能:检查CONTROL是否等于USART_HardwareFlowControl_NoneUSART_HardwareFlowControl_RTSUSART_HardwareFlowControl_CTSUSART_HardwareFlowControl_RTS_CTS中的任一个
        • 返回值:如果CONTROL有效,返回1(真),否则返回0(假)

      表格:

      宏定义描述
      USART_HardwareFlowControl_None0x0000无硬件流控制
      USART_HardwareFlowControl_RTS0x0100使用RTS硬件流控制
      USART_HardwareFlowControl_CTS0x0200使用CTS硬件流控制
      USART_HardwareFlowControl_RTS_CTS0x0300同时使用RTS和CTS硬件流控制
      宏函数描述
      IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)检查CONTROL是否为有效的USART硬件流控制设置

Ⅶ、串口发送数据

#include "stm32f10x.h"                  // Device header
#include <stdio.h>	//为了移植printf
//USART串口
//TX-->PA9void Serial_Init(void)
{//使能GPIO和USART时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//初始化GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_Init(GPIOA, &GPIO_InitStruct);//配置USARTUSART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate = 9600;//配置波特率USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//是否选择硬件流控USART_InitStruct.USART_Mode = USART_Mode_Tx;//仅发送模式USART_InitStruct.USART_Parity = USART_Parity_No;//无校验USART_InitStruct.USART_StopBits = USART_StopBits_1;//1个停止位USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据帧包含8个数据位USART_Init(USART1, &USART_InitStruct);//初始化USATR1USART_Cmd(USART1, ENABLE);//开启USART串口通信
}//发送一个字节
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);//发送一个字节//获取USART标志状态(等待)传输数据寄存器空标志while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}/*************************************************************************************** 名称		Serial_SendArray* 功能		通过串口发送数组* 参数		uint16_t* Arr数组指针* 参数		uint16_t Length数组长度* 返回值	无*****************************/
void Serial_SendArray(uint8_t* Arr, uint16_t Length)
{uint16_t i = 0;for(i = 0;i<Length;i++){Serial_SendByte(Arr[i]);}
}/*************************************************************************************** 名称		Serial_SendString* 功能		通过串口发送字符串* 参数		char* String("xxxxxxx")* 返回值	无*****************************/
void Serial_SendString(char* String)
{while(*String != '\0'){Serial_SendByte(*String);String++;}
}//返回num的SQ次方(内部函数)
static uint32_t Serial_GetSquare(const int num, int SQ)
{uint32_t ret = 1;while(SQ--)ret *= num;return ret;
}
/*************************************************************************************** 名称		Serial_SendNum* 功能		通过串口发送数字* 参数		数字,及数字长* 返回值	无*****************************/
void Serial_SendNum(uint32_t Num, uint8_t Length)
{uint8_t i = 0;for(i = 0; i < Length; i++){Serial_SendByte((Num / Serial_GetSquare(10, Length - i - 1) % 10) + '0');//'\0'是为了偏移,可将数字转换为其对应的ASCII字符}
}//重定向printf,须勾选魔法棒中的Use MicroLlB
int fputc(int ch, FILE *stream)
{Serial_SendByte(ch);return ch;
}

可变参数函数,模拟实现printf

#include <stdarg.h>void Serial_Printf(char* format, ...)
{char String[200];va_list arg;va_start(arg, format);vsprintf(String, format, arg);va_end(arg);Serial_SendString(String);
}

Ⅷ、串口接收数据(包含发送)

#include "stm32f10x.h"                  // Device header
#include <stdio.h>	//为了移植printf
//USART串口
//TX-->PA9
//RX-->PA10uint8_t Serial_RxData = 0;//接收的数据
uint8_t Serial_RxFlag = 0;//标志位void Serial_Init(void)
{//使能GPIO和USART时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//初始化发送GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_Init(GPIOA, &GPIO_InitStruct);//初始化接收GPIOGPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOA, &GPIO_InitStruct);//配置USARTUSART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate = 9600;//配置波特率USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//是否选择硬件流控USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//发送+接收模式USART_InitStruct.USART_Parity = USART_Parity_No;//无校验USART_InitStruct.USART_StopBits = USART_StopBits_1;//1个停止位USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据帧包含8个数据位USART_Init(USART1, &USART_InitStruct);//初始化USATR1//开启USART的中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//设置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置嵌套向量中断控制器(NVIC)的优先级分组NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//选择IRQ通道NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//启用这个IRQ通道NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//设置抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 1;//设置响应优先级为1NVIC_Init(&NVIC_InitStruct);	USART_Cmd(USART1, ENABLE);//开启USART串口通信
}//发送一个字节
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);//发送一个字节//获取USART标志状态(等待)传输数据寄存器空标志while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}/*************************************************************************************** 名称		Serial_SendArray* 功能		通过串口发送数组* 参数		uint16_t* Arr数组指针* 参数		uint16_t Length数组长度* 返回值	无*****************************/
void Serial_SendArray(uint8_t* Arr, uint16_t Length)
{uint16_t i = 0;for(i = 0;i<Length;i++){Serial_SendByte(Arr[i]);}
}/*************************************************************************************** 名称		Serial_SendString* 功能		通过串口发送字符串* 参数		char* String("xxxxxxx")* 返回值	无*****************************/
void Serial_SendString(char* String)
{while(*String != '\0'){Serial_SendByte(*String);String++;}
}//返回num的SQ次方(内部函数)
static uint32_t Serial_GetSquare(const int num, int SQ)
{uint32_t ret = 1;while(SQ--)ret *= num;return ret;
}
/*************************************************************************************** 名称		Serial_SendNum* 功能		通过串口发送数字* 参数		数字,及数字长* 返回值	无*****************************/
void Serial_SendNum(uint32_t Num, uint8_t Length)
{uint8_t i = 0;for(i = 0; i < Length; i++){Serial_SendByte((Num / Serial_GetSquare(10, Length - i - 1) % 10) + '0');//'\0'是为了偏移,可将数字转换为其对应的ASCII字符}
}//重定向printf,须勾选魔法棒中的Use MicroLlB
int fputc(int ch, FILE *stream)
{Serial_SendByte(ch);return ch;
}
//**********************************************************************************
uint8_t Serial_GetFlag(void)//获取标志
{if(Serial_RxFlag == 1){Serial_RxFlag = 0;return 1;}return 0;
}uint8_t Serial_GetData(void)//获取数据
{return Serial_RxData;
}//中断函数
void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)//判断中断标志位{Serial_RxData = USART_ReceiveData(USART1);Serial_RxFlag = 1;USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}

Ⅸ、USART收发数据包

1、收发HEX数据包

包头:FF

包尾:FE

image-20250102193414382

image-20250102193525005

含包头包尾固定包长的数据包
uint8_t Serial_RxPacketFlag = 0;//数据包标志位uint8_t Serial_RxPacket[4] = { 0 };//接收数据包的缓冲数组...
...
//**********************************************************************************
uint8_t Serial_GetPacketFlag(void)//获取数据包标志
{if(Serial_RxPacketFlag == 1){Serial_RxPacketFlag = 0;return 1;}return 0;
}/*************************************************************************************** 名称		Serial_SendPacket* 功能		发送数据量为4字节的HEX数据包* 参数		Serial_RxPacket_4bt* 返回值	无*****************************/
void Serial_SendPacket(uint8_t* Serial_RxPacket_4bt)
{Serial_SendByte(0xFF);//发送包头Serial_SendArray(Serial_RxPacket_4bt, 4);//发送数据Serial_SendByte(0xFE);//发送包尾
}//中断函数
void USART1_IRQHandler(void)
{static uint8_t RxState = 0;//初始化状态static uint8_t Count = 0;//记录接收数据的个数if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)//判断中断标志位{uint8_t RxData = USART_ReceiveData(USART1);//获取数据if(RxState == 0)//等待包头{if(RxData == 0xFF)//接收到包头{RxState = 1;//转移至状态1Count = 0;}}else if(RxState == 1)//接收数据{Serial_RxPacket[Count] = RxData;Count++;if(Count >= 4){RxState = 2;//转移至状态2Count = 0;//状态清零}}else if(RxState == 2)//等待包尾{if(RxData == 0xFE)//接收到包尾{RxState = 0;//转移至状态0Serial_RxPacketFlag = 1;//接收到数据包表标志位}			}USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}

2、收发文本数据包

包头:@

包尾:换行符

image-20250103161415797

image-20250103161500805

含包头包尾固定包长的数据包
#include "stm32f10x.h"                  // Device header
#include <stdio.h>	//为了移植printf
//USART串口
//TX-->PA9
//RX-->PA10#define RxPacket_Length_MAX 200	//接收文本数据包的最大长度
uint8_t Serial_RxPacketFlag = 0;//数据包标志位//需要手动清零char Serial_RxPacket[RxPacket_Length_MAX] = { 0 };//接收文本数据包的缓冲数组void Serial_Init(void)
{//使能GPIO和USART时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//初始化发送GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_Init(GPIOA, &GPIO_InitStruct);//初始化接收GPIOGPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOA, &GPIO_InitStruct);//配置USARTUSART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate = 9600;//配置波特率USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//是否选择硬件流控USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//发送+接收模式USART_InitStruct.USART_Parity = USART_Parity_No;//无校验USART_InitStruct.USART_StopBits = USART_StopBits_1;//1个停止位USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据帧包含8个数据位USART_Init(USART1, &USART_InitStruct);//初始化USATR1//开启USART的中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//设置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置嵌套向量中断控制器(NVIC)的优先级分组NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//选择IRQ通道NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//启用这个IRQ通道NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//设置抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 1;//设置响应优先级为1NVIC_Init(&NVIC_InitStruct);	USART_Cmd(USART1, ENABLE);//开启USART串口通信
}//发送一个字节
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);//发送一个字节//获取USART标志状态(等待)传输数据寄存器空标志while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}/*************************************************************************************** 名称		Serial_SendArray* 功能		通过串口发送数组* 参数		uint16_t* Arr数组指针* 参数		uint16_t Length数组长度* 返回值	无*****************************/
void Serial_SendArray(uint8_t* Arr, uint16_t Length)
{uint16_t i = 0;for(i = 0;i<Length;i++){Serial_SendByte(Arr[i]);}
}/*************************************************************************************** 名称		Serial_SendString* 功能		通过串口发送字符串* 参数		char* String("xxxxxxx")* 返回值	无*****************************/
void Serial_SendString(char* String)
{while(*String != '\0'){Serial_SendByte(*String);String++;}
}//返回num的SQ次方(内部函数)
static uint32_t Serial_GetSquare(const int num, int SQ)
{uint32_t ret = 1;while(SQ--)ret *= num;return ret;
}
/*************************************************************************************** 名称		Serial_SendNum* 功能		通过串口发送数字* 参数		数字,及数字长* 返回值	无*****************************/
void Serial_SendNum(uint32_t Num, uint8_t Length)
{uint8_t i = 0;for(i = 0; i < Length; i++){Serial_SendByte((Num / Serial_GetSquare(10, Length - i - 1) % 10) + '0');//'\0'是为了偏移,可将数字转换为其对应的ASCII字符}
}//重定向printf,须勾选魔法棒中的Use MicroLlB
int fputc(int ch, FILE *stream)
{Serial_SendByte(ch);return ch;
}/*************************************************************************************** 名称		Serial_SendHEXPacket* 功能		发送数据量为4字节的HEX数据包* 参数		Serial_RxPacket_4bt* 返回值	无*****************************/
void Serial_SendHEXPacket(uint8_t* Serial_RxPacket_4bt)
{Serial_SendByte(0xFF);//发送包头Serial_SendArray(Serial_RxPacket_4bt, 4);//发送数据Serial_SendByte(0xFE);//发送包尾
}//中断函数
void USART1_IRQHandler(void)
{static uint8_t RxState = 0;//初始化状态static uint8_t Count = 0;//记录接收数据的个数if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)//判断中断标志位{uint8_t RxData = USART_ReceiveData(USART1);//获取数据if(RxState == 0)//等待包头{if(RxData == '@' && Serial_RxPacketFlag == 0)//接收到包头(且防止传输过快导致数据错位){RxState = 1;//转移至状态1Count = 0;}}else if(RxState == 1)//接收数据{if(RxData == '\r')//判断是否是包尾1{RxState = 2;//转移至状态2}else{Serial_RxPacket[Count] = RxData;Count++;}}else if(RxState == 2)//等待包尾{if(RxData == '\n')//接收到包尾2{RxState = 0;//转移至状态0Serial_RxPacket[Count] = '\0';//添加结束标志位				Serial_RxPacketFlag = 1;//接收到数据包标志位}}USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}

.h头文件

#ifndef __SERIAL_H__
#define __SERIAL_H__
#include "stdint.h"extern char Serial_RxPacket[];//接收文本数据包的缓冲数组
extern uint8_t Serial_RxPacketFlag;//数据包标志位//需要手动清零void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t* Arr, uint16_t Length);
void Serial_SendString(char* String);
void Serial_SendNum(uint32_t Num, uint8_t Length);void Serial_SendHEXPacket(uint8_t* Serial_RxPacket_4bt);//发送数据量为4字节的数据包#endif

相关文章:

【STM32-学习笔记-7-】USART串口通信

文章目录 USART串口通信Ⅰ、硬件电路Ⅱ、常见的电平标准Ⅲ、串口参数及时序Ⅳ、STM32的USART简介数据帧起始位侦测数据采样波特率发生器 Ⅴ、USART函数介绍Ⅵ、USART_InitTypeDef结构体参数1、USART_BaudRate2、USART_WordLength3、USART_StopBits4、USART_Parity5、USART_Mode…...

高可用虚拟IP-keepalived

个人觉得华为云这个文档十分详细&#xff1a;使用虚拟IP和Keepalived搭建高可用Web集群_弹性云服务器 ECS_华为云 应用场景&#xff1a;虚拟IP技术。虚拟IP&#xff0c;就是一个未分配给真实主机的IP&#xff0c;也就是说对外提供数据库服务器的主机除了有一个真实IP外还有一个…...

AI多模态技术介绍:视觉语言模型(VLMs)指南

本文作者&#xff1a;AIGCmagic社区 刘一手 AI多模态全栈学习路线 在本文中&#xff0c;我们将探讨用于开发视觉语言模型&#xff08;Vision Language Models&#xff0c;以下简称VLMs&#xff09;的架构、评估策略和主流数据集&#xff0c;以及该领域的关键挑战和未来趋势。通…...

高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图

目录 高效工作流&#xff1a;用Mermaid绘制你的专属流程图 一、流程图的使用场景 1.1、流程图flowChart 1.2、使用场景 二、如何使用mermaid画出优雅的流程图 2.1、流程图添加图名 2.2、定义图类型与方向 2.3、节点形状定义 2.3.1、规定语法 2.3.2、不同节点案例 2.…...

uniApp通过xgplayer(西瓜播放器)接入视频实时监控

&#x1f680; 个人简介&#xff1a;某大型国企资深软件开发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…...

ws 配置 IngressRoute 和 http一样

ws 配置 IngressRoute 和 http一样 apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata:name: web-ws-ingressroutenamespace: starp spec:entryPoints:- webroutes:- match: Host(webws.we…...

IMX6ULL的IOMUXC寄存器和SNVS复用寄存器似乎都是对引脚指定复用功能的,那二者有何区别?

IMX6ULL 的 IOMUXC 和 SNVS&#xff08;Secure Non-Volatile Storage&#xff09;复用寄存器都是用于配置引脚功能的&#xff0c;但它们的作用范围、目的和使用场景存在明显区别。以下是它们的差异分析&#xff1a; 1. IOMUXC&#xff08;I/O Multiplexer Control&#xff09;寄…...

LabVIEW实现动态水球图的方法

水球图是一种直观展示百分比数据的图表&#xff0c;常用于数据监测与展示。LabVIEW 虽不直接支持水球图绘制&#xff0c;但可通过图片控件动态绘制波形&#xff0c;或借助 HTMLCSS 的 Web 控件实现。此外&#xff0c;还可以结合 Python 等第三方工具生成水球图&#xff0c;LabV…...

【江协STM32】11-2/3 W25Q64简介、软件SPI读写W25Q64

1. W25Q64简介 W25Qxx系列是一种低成本、小型化、使用简单的非易失性存储器&#xff0c;常应用于数据存储、字库存储、固件程序存储等场景存储介质&#xff1a;Nor Flash&#xff08;闪存&#xff09;时钟频率&#xff1a;80MHz / 160MHz (Dual SPI) / 320MHz (Quad SPI)存储容…...

《自动驾驶与机器人中的SLAM技术》ch2:基础数学知识

目录 2.1 几何学 向量的内积和外积 旋转矩阵 旋转向量 四元数 李群和李代数 SO(3)上的 BCH 线性近似式 2.2 运动学 李群视角下的运动学 SO(3) t 上的运动学 线速度和加速度 扰动模型和雅可比矩阵 典型算例&#xff1a;对向量进行旋转 典型算例&#xff1a;旋转的复合 2.3 …...

算法日记2:洛谷p3853路标设置(二分答案)

一、题目&#xff1a; 二、解题思路&#xff1a; 2.1&#xff1a;首先&#xff0c;我们二分空旷指数 1、因为题目中要求我们求解最大值最小应该是属于第二类模型2.也就是说&#xff0c;当check()函数为true时候&#xff0c;说明这个空旷指数是成立的&#xff0c;对应的路标数…...

浅谈云计算06 | 云管理系统架构

云管理系统架构 一、云管理系统架构&#xff08;一&#xff09;远程管理系统&#xff08;二&#xff09;资源管理系统&#xff08;三&#xff09;SLA 管理系统&#xff08;四&#xff09;计费管理系统 二、安全与可靠性保障&#xff08;一&#xff09;数据安全防线&#xff08;…...

Blender常规设置

移动&#xff1a;Shift鼠标中键 旋转&#xff1a;鼠标中键 缩放&#xff1a;Ctrl鼠标中键...

c++ 中的容器 vector、deque 和 list 的区别

表格汇总&#xff1a; 容器存储结构随机访问性能中间插入/删除性能两端插入/删除性能内存管理特点迭代器类型适用场景vector连续存储的动态数组 O ( 1 ) O(1) O(1) O ( n ) O(n) O(n)&#xff08;需要移动元素&#xff09;末尾&#xff1a; O ( 1 ) O(1) O(1)&#xff0c;头部…...

【物流管理系统 - IDEAJavaSwingMySQL】基于Java实现的物流管理系统导入IDEA教程

有问题请留言或私信 步骤 下载项目源码&#xff1a;项目源码 解压项目源码到本地 打开IDEA 左上角&#xff1a;文件 → 新建 → 来自现有源代码的项目 找到解压在本地的项目源代码文件&#xff0c;点击确定&#xff0c;根据图示步骤继续导入项目 查看项目目录&#xff…...

数据集-目标检测系列- 电话 测数据集 call_phone >> DataBall

数据集-目标检测系列- 电话 测数据集 call DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” 贵在坚持&#xff01; …...

VUE3 自定义指令的介绍

自定义指令的概述 在 Vue 中&#xff0c;自定义指令是一种机制&#xff0c;允许开发者在模板中直接操作 DOM 元素&#xff0c;执行一些低级别的操作。Vue 提供了几个内置指令&#xff08;如 v-if、v-for、v-model 等&#xff09;&#xff0c;但当我们需要一些特定功能时&#…...

HTML学习笔记记录---速预CSS(2) 复合属性、盒子模型、边框线、浮动、定位

复合属性写法&#xff1a; {font: font-style font-weitght font-size/line-height font-family} {font: 样式 粗细 字号 字体} (书写瞬间为固定的不可更改) block 块级元素 div inline 行内元素 span inline-block 行内块元素 …...

二 RK3568 固件中打开 ADB 调试

一 usb adb Android 系统,设置->开发者选项->已连接到计算机 打开,usb调试开关打开 通过 usb otg 口连接 开发上位机 (windows/linux) 上位机安装 adb 服务之后 , 通过 cmd/shell: #1 枚举设备 adb devices #2 进入 android shell adb shell # 3 验证上传下载…...

centos9设置静态ip

CentOS 9 默认使用 NetworkManager 管理网络&#xff0c;而nmcli是 NetworkManager 命令行接口的缩写&#xff0c;是一个用来进行网络配置、管理网络连接的命令工具&#xff0c;可以简化网络设置&#xff0c;尤其是在无头&#xff08;没有图形界面&#xff09;环境下。 1、 cd…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...