从小白的视角了解并实现简单的STM32F103的CAN通信,直接上手。

一、CAN协议简介

CAN总线上传输的信息称为报文,当总线空闲时任何连接的单元都可以开始发送新的报文,有5种类型的帧:数据帧、遥控帧、错误帧、过载帧、帧间隔。数据帧有两种格式:标准格式和扩展格式主要区别在于ID长度。

二、参数含义和设置

STM32CubeIDE关于CAN的参数设置

1、位时序参数说明和设置

Prescaler:预分频系数,定义CAN单位时钟周期=APB1外设时钟频率/分频系数,取值范围:1 ~ 1024,上述APB频率 = 36MHz。

用打电话的方式,表示设置参数:

步骤CAN总线对应参数作用
1. 你说:"今~天~晚~上~7~点~"TimeSeg1(匀速发送数据)放慢语速,确保对方听清每个字(信号稳定)
2. 停顿时间TimeSeg2(等待ACK)留时间让对方回应(同步采样点)
3. 对方可能在停顿内回应:  
- ✅ "好!"(ACK)正常接收,继续通信同步成功,无需调整
- ❌ 没回应(信号延迟)SyncJumpWidth 发挥作用! 
4. 你决定最多再等一等

SyncJumpWidth

等待xTq,x个单位时间

允许对方稍晚回应(时钟容错)
- 如果多等的时间内对方回应同步成功通信继续
- 如果多等的时间内仍无回应判定不同步,重传数据自动重传或报错

参数确定:

1、优先确定Prescaler:

计算 Prescaler = CAN_CLK / (波特率 × (1 + TimeSeg1 + TimeSeg2)),取最接近的整数值。

例如:36MHz目标1Mbps,假设 1+6+2=9Tq → Prescaler = 36MHz/(1MHz×9) = 4。

2、TimeSeg1/TimeSeg2分配:

短距离:TimeSeg1可小(如5~6Tq),TimeSeg2=1~2Tq。

长距离:TimeSeg1需大(如8~12Tq),TimeSeg2=2~4Tq。

规则:TimeSeg1 ≥ TimeSeg2 + SyncJumpWidth。

3、SyncJumpWidth选择:

高速CAN(≥500kbps):1Tq(严格同步)。

低速/工业CAN(≤250kbps):2Tq(增强容错)。

4、抗干扰优化:

增大TimeSeg1和SyncJumpWidth可提升稳定性,但会降低波特率。

若通信不稳定,逐步增加TimeSeg1(每次+1Tq)并测试。

2、基本参数说明和设置

参数说明:

基本参数含义
Time Triggered Communication Mode
(时间触发通信模式)
作用:为接收帧添加时间戳(用于时间同步协议)
ENABLE:硬件记录帧的接收时间戳(存储在CAN_RDTxR寄存器)
DISABLE:不记录时间戳(默认)
Automatic Bus-Off Management
(自动总线关闭管理)
作用:节点错误计数器超限后是否自动恢复
ENABLE:节点进入"Bus-Off"状态后,自动等待128次11位隐性位后恢复通信
DISABLE:需手动调用HAL_CAN_ResetError()恢复,适合需要人工干预的调试场景
Automatic Wake-up Mode
(自动唤醒模式)
作用:CAN从休眠模式唤醒的条件
ENABLE:检测到总线活动时自动唤醒(适合低功耗设备)
DISABLE:必须通过软件或硬件信号唤醒(如按键触发)
Automatic Retransmission
(自动重传)
作用:控制发送失败时是否自动重传
ENABLE:发送失败后自动重传(默认),确保数据可靠性,适合实时性要求高的场景(如汽车ECU)
DISABLE:仅发送一次,失败不重试。用于严格时序控制(如CAN FD协议中避免报文堆积)
Receive Fifo Locked Mode
(接收FIFO锁定模式)
接收FIFO满时的处理策略
ENABLE:FIFO满时丢弃新数据(避免覆盖旧数据)
DISABLE:新数据覆盖最旧数据(默认)
Transmit Fifo Priority
(发送FIFO优先级)
作用:发送邮箱的调度策略
ENABLE:按报文ID优先级发送(低ID优先)
DISABLE:按FIFO顺序发送(默认

3、高级参数设置和说明

测试模式说明

Test Mode
测试模式
CAN工作模式:
Normal:正常模式(向总线发送或从总线接收数据)
Loopback:环回模式(自发自收,无需硬件连接,用于本地回环测试)
Silent:静默模式(监听总线,不响应,),只监听不干扰,适合诊断
Loopback combined with Silent:静默环回模式(本地回环+总线监听),混合用途,调试复杂场景

4、开启中断

可以在System Core --> NVIC中设置中断优先等级

三、实际例程

1、CAN初始化

增加接收滤波器,可以用于筛选接收数据,硬件级过滤,可以

  1. 降低CPU负担(避免处理无关报文)

  2. 提高实时性(仅处理目标数据)

  3. 必须配置(否则无法接收数据)

  4. 灵活可控(支持掩码/列表两种过滤模式)

/*** @brief CAN Initialization Function* @param None* @retval None*/
static void MX_CAN_Init(void)
{/* USER CODE BEGIN CAN_Init 0 *//* USER CODE END CAN_Init 0 *//* USER CODE BEGIN CAN_Init 1 *//* USER CODE END CAN_Init 1 */hcan.Instance = CAN1;hcan.Init.Prescaler = 4;hcan.Init.Mode = CAN_MODE_LOOPBACK;hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;hcan.Init.TimeSeg1 = CAN_BS1_5TQ;hcan.Init.TimeSeg2 = CAN_BS2_3TQ;hcan.Init.TimeTriggeredMode = DISABLE;hcan.Init.AutoBusOff = DISABLE;hcan.Init.AutoWakeUp = ENABLE;hcan.Init.AutoRetransmission = DISABLE;hcan.Init.ReceiveFifoLocked = DISABLE;hcan.Init.TransmitFifoPriority = DISABLE;if (HAL_CAN_Init(&hcan) != HAL_OK){Error_Handler();}/* USER CODE BEGIN CAN_Init 2 *//* USER CODE BEGIN CAN_Init 2 */CAN_FilterTypeDef sFilterConfig;sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;sFilterConfig.FilterIdHigh = 0x0000; // 可以保持为0接收所有IDsFilterConfig.FilterIdLow = 0x0000;sFilterConfig.FilterMaskIdHigh = 0x0000;sFilterConfig.FilterMaskIdLow = 0x0000;sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;sFilterConfig.FilterBank = 0; // 添加过滤器组号sFilterConfig.SlaveStartFilterBank = 14;sFilterConfig.FilterActivation = ENABLE;HAL_StatusTypeDef state = HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);if (state != HAL_OK){Error_Handler();}state = HAL_CAN_Start(&hcan);if (state != HAL_OK){Error_Handler();}state = HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);if (state != HAL_OK){Error_Handler();}/* USER CODE END CAN_Init 2 *//* USER CODE END CAN_Init 2 */
}

关于接收滤波器说明与设置:

参数

说明

FilterMode
(过滤模式)
可选值:
CAN_FILTERMODE_IDMASK(掩码模式)
CAN_FILTERMODE_IDLIST(列表模式)
作用:
掩码模式:通过FilterId和FilterMask组合定义ID范围(类似通配符规则)
示例:FilterId=0x100, FilterMask=0xFF00 → 接收ID范围0x100~0x1FF
列表模式:精确匹配FilterId和FilterMask中指定的ID(最多2个32位ID或4个16位ID)
示例:FilterId=0x123, FilterMask=0x456 → 仅接收ID为0x123或0x456的帧
FilterScale
(过滤器尺度)
可选值:
CAN_FILTERSCALE_32BIT(32位宽过滤器)
CAN_FILTERSCALE_16BIT(16位宽过滤器)
作用:
32位模式:单个过滤器可处理1个完整扩展帧ID(29位)或2个标准帧ID(11位)。
16位模式:单个过滤器可处理2个标准帧ID(11位)或部分扩展帧ID(需组合使用)。
选择建议:
扩展帧或复杂过滤规则 → 32位模式。
仅标准帧且需更多过滤组 → 16位模式。
FilterIdHigh
FilterIdLow
(过滤器ID值)
作用:定义待匹配的基准ID值(具体解释取决于FilterMode和FilterScale)
32位模式下的存储规则
标准帧ID(11位):
FilterIdHigh = (StdId << 5);  // 左移5位对齐到寄存器位[15:5]
FilterIdLow = 0x0000;         // 低16位未使用
扩展帧ID(29位):
FilterIdHigh = (ExtId >> 13) & 0xFFFF;  // 高16位(bit28~bit13)
FilterIdLow = ((ExtId << 3) & 0xFFF8) | 0x04; // 低13位(bit12~bit0)+ IDE=1
FilterMaskIdHigh
FilterMaskIdLow
(过滤器掩码)
作用:
掩码模式:定义ID中哪些位必须匹配(1=必须匹配,0=不关心)。
示例:FilterId=0x100, FilterMask=0xFF00 → 匹配所有0x1XX的ID。
列表模式:作为第二个ID值(与FilterId组成精确匹配列表)。
特殊值:
全0x0000:接收所有ID(关闭过滤)。
全0xFFFF:精确匹配FilterId
FilterFIFOAssignment
(FIFO分配)
可选值:
CAN_RX_FIFO0 或 CAN_RX_FIFO1
作用:
指定匹配的报文存入哪个接收FIFO(STM32 CAN控制器有2个接收FIFO)。
推荐配置:
通常使用FIFO0,FIFO1可用于优先级更高的报文
FilterBank
(过滤器组编号)
取值范围:
单CAN设备:0~13(如STM32F103)
双CAN设备:0~27(如STM32F105)
作用:
选择具体的硬件过滤器组(STM32提供多个独立过滤器组,可并行工作)
SlaveStartFilterBank
(从CAN过滤器起始组)
作用:
在双CAN模式(如CAN1+CAN2)下,定义从CAN实例(CAN2)的起始过滤器组编号。
示例:SlaveStartFilterBank=14 → CAN1用组0~13,CAN2用组14~27。
单CAN模式:此参数无效,但需保留(通常设为14)
FilterActivation
(过滤器激活)
可选值:
ENABLE:立即激活过滤器。
DISABLE:配置但不启用(需后续手动激活)。
关键点:
必须至少有一个激活的过滤器,否则CAN控制器会丢弃所有报文!

2、添加中断回调函数

STM32 HAL库中CAN接收中断的回调函数,当CAN控制器的接收FIFO0(接收缓冲区0)中有新消息到达时,会自动触发此函数。

/* USER CODE BEGIN 4 */void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *CanHandle)
{/* Get RX message */if (HAL_CAN_GetRxMessage(CanHandle, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK){/* Reception Error */Error_Handler();}// 接收到的数据:RxData[8]// 接收到的ID值:RxHeader.StdId
}/* USER CODE END 4 */

3、发送数据

将CAN报文放入发送邮箱,由硬件自动发送到总线上

  • 非阻塞式发送:函数仅将数据存入CAN控制器的发送邮箱,实际发送由硬件完成,无需CPU持续等待。

    if (HAL_CAN_AddTxMessage(&hcan, &txHeader, TxData, &TxMailbox) != HAL_OK){Error_Handler();}

4、整个例程

可以通过调试查看接收的数据是否对应发送数据。

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* 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.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */CAN_TxHeaderTypeDef txHeader ={.StdId = 0x123,.ExtId = 0x00,.IDE = CAN_ID_STD,.RTR = CAN_RTR_DATA,.DLC = 8,.TransmitGlobalTime = DISABLE};
CAN_RxHeaderTypeDef RxHeader;
uint8_t TxData[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; // 定义数据
uint8_t RxData[8];
uint32_t TxMailbox;/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_CAN_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if (HAL_CAN_AddTxMessage(&hcan, &txHeader, TxData, &TxMailbox) != HAL_OK){Error_Handler();}HAL_Delay(2000);HAL_GPIO_TogglePin(SYS_LED_GPIO_Port, SYS_LED_Pin);}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/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){Error_Handler();}
}/*** @brief CAN Initialization Function* @param None* @retval None*/
static void MX_CAN_Init(void)
{/* USER CODE BEGIN CAN_Init 0 *//* USER CODE END CAN_Init 0 *//* USER CODE BEGIN CAN_Init 1 *//* USER CODE END CAN_Init 1 */hcan.Instance = CAN1;hcan.Init.Prescaler = 4;hcan.Init.Mode = CAN_MODE_LOOPBACK;hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;hcan.Init.TimeSeg1 = CAN_BS1_5TQ;hcan.Init.TimeSeg2 = CAN_BS2_3TQ;hcan.Init.TimeTriggeredMode = DISABLE;hcan.Init.AutoBusOff = DISABLE;hcan.Init.AutoWakeUp = ENABLE;hcan.Init.AutoRetransmission = DISABLE;hcan.Init.ReceiveFifoLocked = DISABLE;hcan.Init.TransmitFifoPriority = DISABLE;if (HAL_CAN_Init(&hcan) != HAL_OK){Error_Handler();}/* USER CODE BEGIN CAN_Init 2 *//* USER CODE BEGIN CAN_Init 2 */CAN_FilterTypeDef sFilterConfig;sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;sFilterConfig.FilterIdHigh = 0x0000; // 可以保持为0接收所有IDsFilterConfig.FilterIdLow = 0x0000;sFilterConfig.FilterMaskIdHigh = 0x0000;sFilterConfig.FilterMaskIdLow = 0x0000;sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;sFilterConfig.FilterBank = 0; // 添加过滤器组号sFilterConfig.SlaveStartFilterBank = 14;sFilterConfig.FilterActivation = ENABLE;HAL_StatusTypeDef state = HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);if (state != HAL_OK){Error_Handler();}state = HAL_CAN_Start(&hcan);if (state != HAL_OK){Error_Handler();}state = HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);if (state != HAL_OK){Error_Handler();}/* USER CODE END CAN_Init 2 *//* USER CODE END CAN_Init 2 */
}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* USER CODE BEGIN MX_GPIO_Init_1 *//* USER CODE END MX_GPIO_Init_1 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(SYS_LED_GPIO_Port, SYS_LED_Pin, GPIO_PIN_SET);/*Configure GPIO pin : SYS_LED_Pin */GPIO_InitStruct.Pin = SYS_LED_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(SYS_LED_GPIO_Port, &GPIO_InitStruct);/* USER CODE BEGIN MX_GPIO_Init_2 *//* USER CODE END MX_GPIO_Init_2 */
}/* USER CODE BEGIN 4 */void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *CanHandle)
{/* Get RX message */if (HAL_CAN_GetRxMessage(CanHandle, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK){/* Reception Error */Error_Handler();}// 接收到的数据:RxData[8]// 接收到的ID值:RxHeader.StdId
}/* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

四、整个通信逻辑

CAN通信关键环节详解

1、发送端逻辑

步骤操作硬件/软件校验机制
组帧填充ID、数据、帧类型(标准/扩展)软件
CRC计算硬件自动计算15位CRC,附加到帧尾硬件CRC校验字段
发送仲裁竞争总线:低ID优先发送硬件

2. 总线传输

  • 广播特性:所有节点同时收到数据,但只有通过过滤的节点会处理。

  • 物理层校验

    • 差分信号(CAN_H/CAN_L)抗干扰

    • 显性电平(0)覆盖隐性电平(1)实现仲裁

3. 接收端逻辑

步骤操作硬件/软件校验机制
硬件过滤比较报文ID与过滤器规则硬件ID匹配
CRC校验硬件自动验证CRC,错误则丢弃硬件CRC校验
ACK响应接收节点发送ACK位(显性0)硬件ACK确认
数据存储通过校验的帧存入FIFO硬件
软件校验检查DLC、数据有效性等软件自定义校验(如和校验)

4. 硬件级校验

校验类型实现方式失败处理
CRC校验数据链路层硬件计算15位CRC自动丢弃错误帧
ACK响应数据链路层接收节点发送ACK位发送端重传
格式校验数据链路层检查帧格式(如EOF)触发错误帧

5、错误处理机制

错误类型检测方式处理动作
CRC错误硬件自动检测丢弃帧,错误计数器+1
ACK缺失发送节点未检测到ACK位自动重传(若AutoRetransmission=ENABLE)
总线离线错误计数器>255进入Bus-Off状态,需复位或等待恢复

6、应用场景建议

  • 汽车ECU:严格ID过滤 + CRC校验 + AutoRetransmission

  • 工业控制:自定义软件校验 + 长TimeSeg1抗干扰

  • 诊断工具:接收所有ID(FilterMask=0) + 软件解析

通过上述机制,CAN总线实现高可靠、实时的分布式通信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93171.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93171.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/93171.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 课程,每天解读一个简单Java之利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示, * 60分以下

package ytr250812;/*题目&#xff1a;利用条件运算符的嵌套来完成此题&#xff1a;学习成绩>90分的同学用A表示&#xff0c;60-89分之间的用B表示&#xff0c;* 60分以下*/import java.util.Scanner;public class GradeEvaluator {public static void main(String[] args) …

Word XML 批注范围克隆处理器

该类用于处理 Word 文档&#xff08;XML 结构&#xff09;中被批注标记的文本范围&#xff0c; 实现指定内容的深度克隆&#xff0c;并将其插入到目标节点之后。 适用于在生成或修改 .docx 文件时复制批注内容块。/*** Word XML 批注范围克隆处理器* * 该类用于处理 Word 文档&…

MQTT:Java集成MQTT

目录Git项目路径一、原生java架构1.1 导入POM文件1.2 编写测试用例二、SpringBoot集成MQTT2.1 导入POM文件2.2 在YML文件中增加配置2.3 新建Properties配置文件映射配置2.4 创建连接工厂2.5 增加入站规则配置2.6 增加出站规则配置2.7 创建消息发送网关2.8 测试消息发送2.9 项目…

day 16 stm32 IIC

1.IIC概述1基于对话的形式完成&#xff0c;不需要同时进行发送和接收所以删掉了一根数据线&#xff0c;变成半双工2为了安全起见添加了应答机制3可以接多个模块&#xff0c;且互不干扰4异步时序&#xff0c;要求严格&#xff0c;发送过程中不能暂停&#xff0c;所以需要同步时序…

AMD KFD的BO设计分析系列 0:开篇

开启我始终不敢碰的GPU存储系列&#xff0c;先上个图把核心关系表达下&#xff0c;以此纪念。注&#xff1a;图中kfdm_mm误写&#xff0c;应该为kfd_mm&#xff0c;不修改了&#xff0c;请大家不要介意。

EUDR的核心内容,EUDR认证的好处,EUDR意义

近年来&#xff0c;全球森林退化问题日益严峻&#xff0c;毁林行为不仅加剧气候变化&#xff0c;还威胁生物多样性和原住民权益。为应对这一挑战&#xff0c;欧盟于2023年6月正式实施《欧盟零毁林法案》&#xff08;EU Deforestation-free Regulation, EUDR&#xff09;&#x…

数据分析专栏记录之 -基础数学与统计知识

数据分析专栏记录之 -基础数学与统计知识&#xff1a; 1、描述性统计 均值 data_set [10, 20, 30, 40, 50] mean sum(data_set)/len(data_set)np 里面的函数&#xff0c;对二维进行操作时&#xff0c; 默认每一列 mean1 np.mean(data_set) print(mean, mean1)s 0 for i…

《星辰建造师:C++多重继承的奇幻史诗》

&#x1f30c;&#x1f525; 《星辰建造师&#xff1a;多重继承与this指针的终极史诗》 &#x1f525;&#x1f30c;—— 一场融合魔法、科技与哲学的C奇幻冒险&#x1f320;&#x1f30c; 序章&#xff1a;代码宇宙的诞生 &#x1f30c;&#x1f320;在无尽的代码维度中&#…

云计算-OpenStack 运维开发实战:从 Restful API 到 Python SDK 全场景实现镜像上传、用户创建、云主机部署全流程

一、python-Restful Api 简介 Restful API 是一种软件架构风格,基于 HTTP 协议设计,通过统一的接口(如 URL 路径)和标准的 HTTP 方法(GET/POST/PUT/DELETE 等)实现资源(如数据、文件等)的操作,具有无状态、可缓存、客户端 - 服务器分离等特点。方法如下 用 GET 请求获…

RxJava 在 Android 中的深入解析:使用、原理与最佳实践

前言RxJava 是一个基于观察者模式的响应式编程库&#xff0c;它通过可观察序列和函数式操作符的组合&#xff0c;简化了异步和事件驱动程序的开发。在 Android 开发中&#xff0c;RxJava 因其强大的异步处理能力和简洁的代码风格而广受欢迎。本文将深入探讨 RxJava 的使用、核心…

面试实战 问题三十 HTTP协议中TCP三次握手与四次挥手详解

HTTP协议中TCP三次握手与四次挥手详解 在HTTP协议中&#xff0c;连接建立和断开依赖于底层的TCP协议。虽然HTTP本身不定义握手过程&#xff0c;但所有HTTP通信都通过TCP三次握手建立连接&#xff0c;通过四次挥手断开连接。以下是详细解析&#xff1a;一、TCP三次握手&#xff…

读《精益数据分析》:双边市场的核心指标分析

双边市场数据分析指南&#xff1a;从指标体系到实战落地&#xff08;基于《精益数据分析》框架&#xff09;在互联网平台经济中&#xff0c;双边市场&#xff08;如电商、出行、外卖、自由职业平台等&#xff09;的核心矛盾始终是"供需平衡与效率优化"。这类平台连接…

Queue参考代码

queue.c #include "queue.h" #include "stdlib.h" // 初始化循环队列 void initializeCircularQueue(CircularQueue *cq, uint8_t *buffer, uint32_t size) {cq->front 0;cq->rear 0;cq->count 0;cq->size size;cq->data buffer; }…

通过时间计算地固系到惯性系旋转矩阵

通过时间计算地固系到惯性系旋转矩阵 1. 引言 在航天工程和卫星导航领域&#xff0c;经常需要在地固坐标系(ECEF)和惯性坐标系(ECI)之间进行转换。本文将详细介绍如何根据UTC时间计算这两个坐标系之间的旋转矩阵&#xff0c;并提供完整的C语言实现。 2. 基本概念 2.1 坐标系定义…

【Datawhale AI 夏令营】金融文档分析检索增强生成系统的架构演变与方法论进展

# **金融文档分析检索增强生成系统的架构演变与方法论进展****第一部分&#xff1a;基础原则和基线系统分析****第一部分&#xff1a;金融领域检索增强生成范式的解构****第二部分&#xff1a;基线剖析&#xff1a;流水线的二分法****同步轨迹 (SimpleRAG)****异步改进 (AsyncS…

C语言相关简单数据结构:顺序表

目录 1.顺序表的概念及结构 1.1 线性表 如何理解逻辑结构和物理结构&#xff1f; 1.2 顺序表分类 顺序表和数组的区别&#xff1a; 顺序表分类&#xff1a; 静态顺序表 动态顺序表 1.3 动态顺序表的实现 初始化 尾插 头插 尾删 头删 在指定位置之前插入数据 删…

nginx配置代理服务器

Nginx 作为代理服务器时&#xff0c;主要用于反向代理&#xff08;最常用&#xff0c;转发客户端请求到后端服务&#xff09;或正向代理&#xff08;较少用&#xff0c;为客户端提供访问外部网络的代理&#xff09;。以下是两种场景的具体配置示例&#xff1a; 一、反向代理配置…

MySQL数据库知识体系总结 20250813

一、数据库的原理 1.数据库的分类 我们可以根据数据的结构类型&#xff0c;将数据分成三类&#xff0c;分别是&#xff1a;结构化数据&#xff0c;半结构化数据&#xff0c;非结构化数据。 要点&#xff1a;对于结构化数据来讲通常是先有结构再有数据。要点&#xff1a;对于半…

C++ 中构造函数参数对父对象的影响:父子控件管理机制解析

文章目录C 中构造函数参数对父对象的影响&#xff1a;父子控件管理机制解析1. Qt 中的父对象管理机制2. 构造函数传递父对象的不同方式2.1. 父控件是 QWidget parent&#xff08;通用方式&#xff09;分析&#xff1a;2.2. 父控件是 Books_Client parent&#xff08;限制父控件…

直播美颜SDK开发实战:高性能人脸美型的架构与实现

在直播行业里&#xff0c;美颜已经不再是锦上添花&#xff0c;而是标配中的标配。无论是游戏主播、带货达人&#xff0c;还是唱歌、跳舞的才艺主播&#xff0c;直播美颜SDK往往决定了用户的第一印象和停留时长。尤其是高性能人脸美型技术&#xff0c;不仅能让主播的五官更加自然…