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

【STM32】HAL库 之 CAN 开发指南

基于stm32 f407vet6芯片 使用hal库开发 can
简单讲解一下can的基础使用

CubeMX配置

在这里插入图片描述
这里打开CAN1 并且设置好波特率和NVIC相关的配置
波特率使用波特率计算器软件

在这里插入图片描述
使用采样率最高的这段 填入

在这里插入图片描述
得到波特率1M bit/s

然后编写代码
环形缓冲区

#include "driver_buffer.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"RingBuffer USERRxDataBuffer1; //定义用户缓冲区
RingBuffer USERRxDataBuffer2;/* 初始化环形缓冲区 */
int Driver_Buffer_Init(ptRingBuffer buffer, uint16_t size)
{if (buffer == NULL || size == 0)return -1;            /* 判断合法性 */if (buffer->fifo == NULL) /* 判断是否为内存大小空*/{buffer->fifo = (uint8_t *)malloc(size); /* 动态分配内存 */if (buffer->fifo == NULL){//printf("Malloc %d bytes failed.\r\n", size);return -1;}}buffer->pw = buffer->pr = 0;buffer->buf_size = size;return 0;
}/* 环形缓冲区写一个字节 */
int Driver_Buffer_Write(ptRingBuffer buffer, const uint8_t data)
{if (buffer == NULL || buffer->fifo == NULL)return -1; /* 判断合法性 */int i = (buffer->pw + 1) % buffer->buf_size;if (i != buffer->pr) /* 判断是否写满 */{buffer->fifo[buffer->pw] = data; /* */buffer->pw = i;                  /* 重置写指针 */return 0;}return -1;
}/* 环形缓冲区写多个字节 */
int Driver_Buffer_WriteBytes(ptRingBuffer buffer, const uint8_t *data_stream, uint8_t len)
{int i;if (buffer == NULL || buffer->fifo == NULL)return -1; /* 判断合法性 */if (data_stream == NULL || len == 0)return -1;for (i = 0; i < len; i++){if (Driver_Buffer_Write(buffer, data_stream[i]) != 0)break;}return i;
}/* 环形缓冲区 读一个字节 */
int Driver_Buffer_Read(ptRingBuffer buffer, uint8_t *data)
{if (buffer == NULL || buffer->fifo == NULL)return -1; /* 判断合法性 */if (data == NULL)return -1;if (buffer->pr == buffer->pw)return -1; /* 满 */*data = buffer->fifo[buffer->pr];buffer->pr = (buffer->pr + 1) % buffer->buf_size; /* 自增 */return 0;
}/* 环形缓冲区 读多个字节 */
int Driver_Buffer_ReadBytes(ptRingBuffer buffer, uint8_t *data_stream, uint8_t len)
{int i = 0;if (buffer == NULL || buffer->fifo == NULL)return -1; /* 判断合法性 */if (data_stream == NULL || len == 0)return -1;for (i = 0; i < len; i++){if (Driver_Buffer_Read(buffer, &data_stream[i]) != 0)break;}return i;
}/*  清空环形缓冲区 */
int Driver_Buffer_Clean(ptRingBuffer buffer)
{if (buffer == NULL || buffer->fifo == NULL)return -1;                             /* 判断合法性 */memset(buffer->fifo, 0, buffer->buf_size); /* 清空 */buffer->pr = buffer->pw = 0;               /* 归零 */return 0;
}
/*** @brief 更新数据到数组* @param buffer* @param data_stream* @return 返回更新的数据长度*/
int Driver_Buffer_RefreshData(ptRingBuffer buffer, uint8_t *data_stream)
{uint16_t len = 0;if (buffer->pw == buffer->buf_size)buffer->pw = 0;while (buffer->pw != buffer->pr){data_stream[len++] = buffer->fifo[buffer->pr];buffer->fifo[buffer->pr] = 0;buffer->pr++;if (buffer->pr >= buffer->buf_size)buffer->pr = 0;if (len >= buffer->buf_size)break;}return len;
}
#ifndef __DRIVER_BUFFER_H
#define __DRIVER_BUFFER_H#include "stdint.h"
typedef struct{uint8_t *fifo;uint16_t pw; /*写地址*/uint16_t pr;uint16_t buf_size;}RingBuffer,*ptRingBuffer;extern RingBuffer USERRxDataBuffer1;
extern RingBuffer USERRxDataBuffer2;int Driver_Buffer_Init(ptRingBuffer buffer, uint16_t size);int Driver_Buffer_Write(ptRingBuffer buffer, const uint8_t data);int Driver_Buffer_WriteBytes(ptRingBuffer buffer, const uint8_t *data_stream, uint8_t len);int Driver_Buffer_Read(ptRingBuffer buffer, uint8_t *data);int Driver_Buffer_ReadBytes(ptRingBuffer buffer, uint8_t *data_stream, uint8_t len);int Driver_Buffer_Clean(ptRingBuffer buffer);int Driver_Buffer_RefreshData(ptRingBuffer buffer, uint8_t *data_stream);#endif
#include "driver_can.h"
#include "can.h"
#include "driver_buffer.h"#include <stdio.h> //使用printf函数
#include <stdint.h>HAL_StatusTypeDef CAN_Init(void)
{HAL_StatusTypeDef result = HAL_OK;Driver_Buffer_Init(&USERRxDataBuffer1, 256);                       /* 开辟环形缓冲区空间 */result = CAN_Filter_Config_Scale32_IdMask(&hcan1, 0x100, 0x100); // 过滤器设置return result;
}HAL_StatusTypeDef CAN_Filter_Config_Scale32_IdMask(CAN_HandleTypeDef *hcan, uint32_t id, uint32_t mask)
{HAL_CAN_Stop(hcan); // 停止canHAL_StatusTypeDef result = HAL_OK;CAN_FilterTypeDef sFilterConfig;/* 配置过滤器参数 */sFilterConfig.FilterBank = 0;                      // 过滤器组编号(0-27)sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  // 掩码模式(或列表模式)sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 32位位宽// ID分解(右移13位取高16位,左移3位处理IDE/RTR位)sFilterConfig.FilterIdHigh = (id >> 13) & 0xFFFF;sFilterConfig.FilterIdLow = (id << 3) & 0xFFF8| CAN_ID_EXT|CAN_RTR_DATA; /*只接受拓展帧 和数据帧*/// 掩码设置为0xFFFF0000(匹配前16位)sFilterConfig.FilterMaskIdHigh = (mask >> 13) & 0xFFFF;sFilterConfig.FilterMaskIdLow = (mask << 3) & 0xFFF8| CAN_ID_EXT|CAN_RTR_DATA; /*只接受拓展帧 和数据帧*/sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 接收FIFO选择sFilterConfig.FilterActivation = ENABLE;           // 启用过滤器sFilterConfig.SlaveStartFilterBank = 14;            // 双CAN时从过滤器组起始编号  单can无意义/* 应用过滤器配置 */if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK){Error_Handler();}result = HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // FIFO0消息挂起中断result = HAL_CAN_Start(hcan);                                             // 启动CAN外设return result;
}/* 32位列表模式 */
HAL_StatusTypeDef CAN_Filter_Config_Scale32_IdList(CAN_HandleTypeDef *hcan, uint32_t id1, uint32_t id2)
{HAL_CAN_Stop(hcan); // 停止canHAL_StatusTypeDef result = HAL_OK;CAN_FilterTypeDef sFilterConfig;/* 基础参数配置 */sFilterConfig.FilterBank = 0;                      // 使用过滤器组0(CAN1默认组0-13)sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;  // 列表模式,需精确匹配IDsFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 32位位宽,支持标准帧和扩展帧sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 接收报文存入FIFO0sFilterConfig.FilterActivation = ENABLE;           // 启用过滤器sFilterConfig.SlaveStartFilterBank =14;            // CAN2使用过滤器组14-27/* 设置两个目标扩展ID(0x18F60000和0x18F60001) */uint32_t target_id1 = id1 | CAN_ID_EXT; // 扩展帧需设置IDE位uint32_t target_id2 = id2 | CAN_ID_EXT;// 扩展ID分解:高16位右移13位,低16位左移3位(IDE/RTR位对齐)sFilterConfig.FilterIdHigh = (target_id1 >> 13) & 0xFFFF;sFilterConfig.FilterIdLow = (target_id1 << 3) & 0xFFF8| CAN_ID_EXT|CAN_RTR_DATA; /*只接受拓展帧 和数据帧*/sFilterConfig.FilterMaskIdHigh = (target_id2 >> 13) & 0xFFFF; // 第二个ID的高16位sFilterConfig.FilterMaskIdLow = (target_id2 << 3) & 0xFFF8| CAN_ID_EXT|CAN_RTR_DATA; /*只接受拓展帧 和数据帧*//* 应用过滤器配置 */if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK){Error_Handler();}HAL_CAN_Start(hcan);   HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // FIFO0消息挂起中断// 启动CAN外设return result;
}HAL_StatusTypeDef CAN_Filter_Config_Scale16_IdMask(CAN_HandleTypeDef *hcan, uint16_t id, uint16_t mask)
{HAL_CAN_Stop(hcan); // 停止canHAL_StatusTypeDef result = HAL_OK;CAN_FilterTypeDef sFilterConfig;/* 配置过滤器参数 */sFilterConfig.FilterBank = 0;                      // 过滤器组编号(0-27)sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  // 掩码模式(或列表模式)sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT; // 32位位宽sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 接收报文存入FIFO0sFilterConfig.FilterActivation = ENABLE;           // 启用过滤器sFilterConfig.SlaveStartFilterBank = 0;            // CAN2使用过滤器组14-27// 标准帧ID左移5位对齐(STID[10:0]占高11位)sFilterConfig.FilterIdHigh = (id << 5);       // ID高16位寄存器(实际存储前11位)sFilterConfig.FilterIdLow = 0x0000;           // ID低16位寄存器(未使用)sFilterConfig.FilterMaskIdHigh = (mask << 5); // 掩码高16位寄存器sFilterConfig.FilterMaskIdLow = 0x0000;       // 掩码低16位寄存器(未使用)/* 应用过滤器配置 */if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK){Error_Handler();}// 启动CAN外设HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // FIFO0消息挂起中断HAL_CAN_Start(hcan);      return result;
}/* 16位列表模式 */
HAL_StatusTypeDef CAN_Filter_Config_Scale16_IdList(CAN_HandleTypeDef *hcan, uint16_t id1, uint16_t id2, uint16_t id3, uint16_t id4)
{HAL_CAN_Stop(hcan); // 停止canHAL_StatusTypeDef result = HAL_OK;CAN_FilterTypeDef sFilterConfig;/* 基础参数配置 */sFilterConfig.FilterBank = 0;                     // 使用过滤器组0(CAN1默认组0-13)sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST; // 列表模式,需精确匹配IDsFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 接收报文存入FIFO0sFilterConfig.FilterActivation = ENABLE;           // 启用过滤器sFilterConfig.SlaveStartFilterBank = 0;            // CAN2使用过滤器组14-27sFilterConfig.FilterIdHigh = id1 << 5;             // 标准ID 0x100sFilterConfig.FilterIdLow = id2 << 5;              // 标准ID 0x101sFilterConfig.FilterMaskIdHigh = id3 << 5;         // 标准ID 0x102sFilterConfig.FilterMaskIdLow = id4 << 5;          // 标准ID 0x103/* 应用过滤器配置 */if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK){Error_Handler();}HAL_CAN_Start(hcan);                                             // 启动CAN外设HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // FIFO0消息挂起中断return result;
}/** @brief  发送一帧CAN数据* @param  hcan: CAN句柄指针* @param  id: 报文标识符(标准ID或扩展ID)* @param  data: 数据缓冲区指针(最大8字节)* @param  len: 数据长度(0-8)* @param  isExtId: 是否为扩展ID(1=扩展帧,0=标准帧)* @retval HAL状态:HAL_OK=成功,其他=失败*/
HAL_StatusTypeDef CAN_Send_Frame(CAN_HandleTypeDef *hcan, uint32_t id, uint8_t *data, uint8_t len, uint8_t isExtId)
{CAN_TxHeaderTypeDef txHeader;uint32_t mailbox;HAL_StatusTypeDef result = HAL_OK;/* 校验参数合法性 */if (len > 8 || data == NULL)return HAL_ERROR;/* 配置报文头部 */if (isExtId){txHeader.ExtId = id;       // 扩展IDtxHeader.IDE = CAN_ID_EXT; // 扩展帧标识}else{txHeader.StdId = id;       // 标准IDtxHeader.IDE = CAN_ID_STD; // 标准帧标识}txHeader.RTR = CAN_RTR_DATA;           // 数据帧(非远程请求)txHeader.DLC = len;                    // 数据长度码txHeader.TransmitGlobalTime = DISABLE; // 不记录全局时间戳/* 提交发送请求 */result = HAL_CAN_AddTxMessage(hcan, &txHeader, data, &mailbox);while (HAL_CAN_GetTxMailboxesFreeLevel(hcan) != 3) // 3 个邮箱都为空;                                                  /*等待发送完成 防止丢包*/return result;
}/* CAN发送多帧数据 */
void CAN_Send_Data(CAN_HandleTypeDef *hcan, uint32_t id, uint8_t *buf, uint32_t len, uint8_t isExtId)
{uint32_t transmission_times = 0; /* 发送次数 */uint32_t remian_bytes = 0;       /* 剩余字节 */uint32_t frame_length = 0;       /* 帧长度 */frame_length = 8;                /* 标准can最大8 */transmission_times = len / frame_length;remian_bytes = len % frame_length;int i = 0;while (i < transmission_times){CAN_Send_Frame(hcan, id, buf + i * frame_length, frame_length, isExtId);i++;}if (remian_bytes > 0) // 尾帧{CAN_Send_Frame(hcan, id, buf + transmission_times * frame_length, remian_bytes, isExtId);}
}/* CAN 接收数据 */
uint32_t CAN_Receive_Message(CAN_HandleTypeDef *hcan, uint32_t RxFifo, uint8_t *buf)
{CAN_RxHeaderTypeDef RxHeader;if (HAL_CAN_GetRxFifoFillLevel(hcan, RxFifo) == 0) // 检查邮箱{return 0; // 没有数据}HAL_CAN_GetRxMessage(hcan, RxFifo, &RxHeader, buf);return RxHeader.DLC; // 返回接收长度
}/*** @brief 接收FIFO0的回调函数 (中断方式)* @param hcan*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{uint8_t can_rec_data[8];uint32_t len = 0;len = CAN_Receive_Message(hcan, CAN_RX_FIFO0, can_rec_data);Driver_Buffer_WriteBytes(&USERRxDataBuffer1, can_rec_data, len); /*将收到的数据写到缓冲区*/char buffer[10] = "";char *ptr = buffer;for (size_t i = 0; i < 8; i++){ptr += sprintf(ptr, "%02X ", can_rec_data[i]); // 将元素转为十六进制字符串}//usb_printf("%s\n", buffer); // 一次性输出整个字符串
}//void MX_CAN_Init(void)
//{
//  CAN_FilterTypeDef    sFilterConfig;
//  
//  /*CANµ¥Ԫ³õʼ»¯*/
//  
//  hCAN.Instance = CANx;                     /* CAN͢ɨ */
//  hCAN.Init.Prescaler = 3;                  /* BTR-BRP ²¨̘Š·ֆµƷ  ¶¨ҥÁˊ±¼䵥ԪµĊ±¼䳤¶Ƞ42/(1+10+3)/3=1Mbps */
//  hCAN.Init.Mode = CAN_MODE_NORMAL;         /* ս³£¹¤׷ģʽ */
//  hCAN.Init.SyncJumpWidth = CAN_SJW_1TQ;    /* BTR-SJW ֘Ђͬ²½̸Ծ¿񲀠2¸öʱ¼䵥Ԫ */
//  hCAN.Init.TimeSeg1 = CAN_BS1_10TQ;         /* BTR-TS1 ʱ¼䶎1 ռӃÁ˶¸öʱ¼䵥Ԫ */
//  hCAN.Init.TimeSeg2 = CAN_BS2_3TQ;         /* BTR-TS1 ʱ¼䶎2 ռӃÁ˳¸öʱ¼䵥Ԫ */
//  hCAN.Init.TimeTriggeredMode = DISABLE;    /* MCR-TTCM  ¹رՊ±¼䴥·¢ͨЅģʽʹĜ */
//  hCAN.Init.AutoBusOff = ENABLE;            /* MCR-ABOM  ה¶¯À돟¹܀𚠯
//  hCAN.Init.AutoWakeUp = ENABLE;            /* MCR-AWUM  ʹӃה¶¯»½Бģʽ */
//  hCAN.Init.AutoRetransmission = DISABLE;   /* MCR-NART  ½ûֹ±¨΄ה¶¯֘´«	  DISABLE-ה¶¯֘´« */
//  hCAN.Init.ReceiveFifoLocked = DISABLE;    /* MCR-RFLM  ½ӊՆIFO ˸¶¨ģʽ  DISABLE-ҧ³öʱЂ±¨΄»Ḳ¸ǔ­Ӑ±¨΄ */
//  hCAN.Init.TransmitFifoPriority = DISABLE; /* MCR-TXFP  ·¢ˍFIFOӅψ¼¶ DISABLE-Ӆψ¼¶ȡ¾öӚ±¨΄±ꊾ·û */
//  HAL_CAN_Init(&hCAN);
//  
//  /*CAN¹ý‹Ʒ³õʼ»¯*/                  
//  sFilterConfig.FilterBank = 0;                      /* ¹ý‹Ʒש0 */
//  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  /* ¹¤׷Ԛ±ꊶ·ûƁ±Ύ»ģʽ */
//  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; /* ¹ý‹Ʒλ¿펪µ¥¸ö32λ¡£*/
//  sFilterConfig.FilterIdHigh = (((uint32_t)0x1314<<3)&0xFFFF0000)>>16;;               /* Ҫ¹ý‹µĉD¸ߎ» */
//  sFilterConfig.FilterIdLow = (((uint32_t)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;; /* Ҫ¹ý‹µĉDµ͎» */
//  sFilterConfig.FilterMaskIdHigh = 0xFFFF;           /* ¹ý‹Ʒ¸߱6λÿλ±ؐ놥Ť */
//  sFilterConfig.FilterMaskIdLow = 0xFFFF;            /* ¹ý‹Ʒµͱ6λÿλ±ؐ놥Ť */
//  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;  /* ¹ý‹Ʒ±»¹؁ªµ½FIFO 0 */
//  sFilterConfig.FilterActivation = ENABLE;            /* ʹĜ¹ý‹Ʒ */ 
//  sFilterConfig.SlaveStartFilterBank = 0;             /* ӃÀ´ѡԱ´ӹý‹ƷµļĴ憷±຅ */   
//  
//  HAL_CAN_ConfigFilter(&hCAN, &sFilterConfig);
//  
//  
//}
#ifndef __DRIVER_CAN_H__
#define __DRIVER_CAN_H__#include "main.h"HAL_StatusTypeDef CAN_Init(void);HAL_StatusTypeDef CAN_Filter_Config_Scale32_IdMask(CAN_HandleTypeDef *hcan, uint32_t id, uint32_t mask);HAL_StatusTypeDef CAN_Filter_Config_Scale32_IdList(CAN_HandleTypeDef *hcan, uint32_t id1, uint32_t id2);HAL_StatusTypeDef CAN_Filter_Config_Scale16_IdMask(CAN_HandleTypeDef *hcan, uint16_t id, uint16_t mask);HAL_StatusTypeDef CAN_Filter_Config_Scale16_IdList(CAN_HandleTypeDef *hcan, uint16_t id1, uint16_t id2, uint16_t id3, uint16_t id4);HAL_StatusTypeDef CAN_Send_Frame(CAN_HandleTypeDef *hcan, uint32_t id, uint8_t *data, uint8_t len, uint8_t isExtId);void CAN_Send_Data(CAN_HandleTypeDef *hcan, uint32_t id, uint8_t *buf, uint32_t len, uint8_t isExtId);uint32_t CAN_Receive_Message(CAN_HandleTypeDef *hcan, uint32_t RxFifo, uint8_t *buf);#endif

提供了32位掩码和列表 16位掩码和列表的过滤器

编写应用层代码

void  APP_User_Task(void)
{for(int i =0 ;i<8;i++){buf[i] = i;}/*发送丢包测试*/	for(int i =0 ;i<1024;i++){tx_Pathping[i] = i%256;}CAN_Send_Data(&hcan1,0x100,tx_Pathping,1024,1);for(;;){/*接收丢包测试*/if(Driver_Buffer_RefreshData(&USERRxDataBuffer1,tx_buf)){tx_buf[7] = 0xa5;CAN_Send_Data(&hcan1,0x5A,tx_buf,8,1);}}
}	

实验效果

在这里插入图片描述
一开机就输出了128帧数据 可以看到数据都是连续的没有丢包

然后发送1024帧数据 可以看到也没有丢包

在这里插入图片描述
发送的数据接收到环形缓冲区 然后读出数据打印

此工程代码已经在STM32F407VET6 和STM32F103CBT6芯片上都验证过了 没有太大问题

相关文章:

【STM32】HAL库 之 CAN 开发指南

基于stm32 f407vet6芯片 使用hal库开发 can 简单讲解一下can的基础使用 CubeMX配置 这里打开CAN1 并且设置好波特率和NVIC相关的配置 波特率使用波特率计算器软件 使用采样率最高的这段 填入 得到波特率1M bit/s 然后编写代码 环形缓冲区 #include "driver_buffer.h&qu…...

WPF的基础设施:XAML基础语法

XAML基础语法 1 控件声明与属性设置1.1 特性语法&#xff08;Attribute Syntax&#xff09;1.2 属性元素语法&#xff08;Property Element Syntax&#xff09;1.3 特殊值标记扩展 2 x:Name与Name的区别3 注释与代码折叠4 实用技巧集合5 常见错误排查 XAML( Extensible Applic…...

DeepSeek R1-0528 新开源推理模型(免费且快速)

DeepSeek推出了新模型,但这不是R2! R1-0528是DeepSeek的最新模型,在发布仅数小时后就在开源社区获得了巨大关注。 这个悄然发布的模型DeepSeek R1-0528,已经开始与OpenAI的o3一较高下。 让我来详细介绍这次更新的新内容。 DeepSeek R1-0528 发布 DeepSeek在这次发布中采…...

Go 语言的 GC 垃圾回收

序言 垃圾回收&#xff08;Garbage Collection&#xff0c;简称 GC&#xff09;机制 是一种自动内存管理技术&#xff0c;主要用于在程序运行时自动识别并释放不再使用的内存空间&#xff0c;防止内存泄漏和不必要的资源浪费。这篇文章让我们来看一下 Go 语言的垃圾回收机制是如…...

[git每日一句]your branch is behind ‘origin/master‘

当 Git 提示 "your branch is behind origin/master" 时&#xff0c;意思是&#xff1a; 你的本地分支落后于远程仓库&#xff08;origin&#xff09;的 master 分支 即&#xff1a;远程仓库有新的提交&#xff0c;而你的本地分支尚未同步这些更新。 如何解决&…...

【QT】在QT6中读取文件的方法

在QT6中读取文件的方法 QT6提供了多种读取文件的方式&#xff0c;下面我将介绍几种常用的方法&#xff0c;包括处理文本文件和二进制文件。 1. 使用QFile和QTextStream读取文本文件 这是读取文本文件最常用的方法&#xff1a; #include <QFile> #include <QTextSt…...

安全帽目标检测

安全帽数据集 这里我们使用的安全帽数据集是HelmentDetection&#xff0c;这是一个公开数据集&#xff0c;里面包含5000张voc标注格式的图像&#xff0c;分为三个类别&#xff0c;分别是 0: head 1: helmet 2: person 安全帽数据集下载地址、 我们将数据集下载后&#xff0c…...

Java工厂方法模式详解

工厂方法模式&#xff08;Factory Method Pattern&#xff09;是一种创建型设计模式&#xff0c;它将对象的创建和使用分离&#xff0c;通过定义一个创建对象的接口&#xff0c;让子类决定实例化哪个类。这种模式提高了代码的可扩展性和可维护性&#xff0c;尤其适用于需要根据…...

【pytorch学习】土堆pytorch学习笔记2

说明 主要以https://www.morinha.cc/posts/courses/pytorch-%E5%B0%8F%E5%9C%9F%E5%A0%86的内容为基础&#xff0c;没有的或者自己不是很清楚的再补充上内容&#xff0c;该贴有的内容大部分不再加入进来 新增的更全的参考&#xff1a; https://2048.csdn.net/6801fc28e9858151…...

Eclipse 插件开发 5.3 编辑器 监听输入

Eclipse 插件开发 5.3 编辑器监 听输入 1 插件配置2 添加监听3 查看效果 Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Click1 Bundle-SymbolicName: com.xu.click1;singleton:true Bundle-Version: 1.0.0 Bundle-Activator: com.xu.click1.Activator Bundle…...

iOS 集成网易云信IM

云信官方文档在这 看官方文档的时候&#xff0c;版本选择最新的V10。 1、CocoPods集成 pod NIMSDK_LITE 2、AppDelegate.m添加头文件 #import <NIMSDK/NIMSDK.h> 3、初始化 NIMSDKOption *mrnn_option [NIMSDKOption optionWithAppKey:"6f6568e354026d2d658a…...

Parasoft C++Test软件单元测试_实例讲解(对多次调用的函数打桩)

系列文章目录 Parasoft C++Test软件静态分析:操作指南(编码规范、质量度量)、常见问题及处理 Parasoft C++Test软件单元测试:操作指南、实例讲解、常见问题及处理 Parasoft C++Test软件集成测试:操作指南、实例讲解、常见问题及处理 进阶扩展:自动生成静态分析文档、自动…...

azure web app创建分步指南系列之二

为注册表授权托管标识 你创建的托管标识尚未获得从容器注册表中提取数据的授权。在此步骤中,你将启用授权。 返回容器注册表的管理页面: 在左侧导航菜单中,选择“访问控制 (IAM)”。选择“添加角色分配”。此屏幕截图显示了如何为容器注册表启用添加角色分配。在角色列表中…...

题海拾贝:P8598 [蓝桥杯 2013 省 AB] 错误票据

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…...

MySQL 8.0:解析

引言 MySQL 8.0 作为里程碑版本&#xff0c;在功能、性能、安全性等维度进行了全面革新。以下从技术实现、应用场景和实践挑战三个层面&#xff0c;深度解析其核心特性变化&#xff1a; 一、架构级重构&#xff1a;数据字典与原子 DDL 1. 事务性数据字典 技术实现…...

Python量化交易12——Tushare全面获取各种经济金融数据

两年前写过Tushare的简单使用&#xff1a; Python量化交易08——利用Tushare获取日K数据_skshare- 现在更新一下吧&#xff0c;这两年用过不少的金融数据库&#xff0c;akshare&#xff0c;baostock&#xff0c;雅虎的&#xff0c;pd自带的......发现还是Tushare最稳定最好用&…...

封装一个小程序选择器(可多选、单选、搜索)

组件 <template><view class"popup" v-show"show"><view class"bg" tap"cancelMultiple"></view><view class"selectMultiple"><view class"multipleBody"><view class&…...

Dest建筑能耗模拟仿真功能简介

Dest建筑能耗模拟仿真功能简介 全球建筑能耗占终端能源消费的30%以上&#xff0c;掌握建筑能耗模拟是参与绿色建筑认证&#xff08;如LEED、WELL&#xff09;、超低能耗设计、既有建筑节能改造的必备能力。DEST作为国内主流建筑能耗模拟工具&#xff0c;广泛应用于设计院、咨询…...

【Hot 100】121. 买卖股票的最佳时机

目录 引言买卖股票的最佳时机我的解题 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;【Hot 100】121. 买卖股票的最佳时机❣️ 寄语&#xff1a;书到用时方恨少&#xff0c;事非经过不知难&#xff01; 引…...

【机器学习基础】机器学习入门核心算法:XGBoost 和 LightGBM

机器学习入门核心算法&#xff1a;XGBoost 和 LightGBM 一、算法逻辑XGBoost (eXtreme Gradient Boosting)LightGBM (Light Gradient Boosting Machine) 二、算法原理与数学推导目标函数&#xff08;二者通用&#xff09;二阶泰勒展开&#xff1a;XGBoost 分裂点增益计算&#…...

Linux | Shell脚本的常用命令

一. 常用字符处理命令 1.1 连续打印字符seq seq打印数字&#xff1b;且只能正向打印&#xff0c;不可反向连续打印 设置打印步长 指定打印格式 1.2 反向打印字符tac cat 正向&#xff0c;tac 反向 1.3 打印字符printf printf "打印的内容"指定格式打印内容 换行…...

跑步的强度等级分类

概述 最大心率简化计算公式是【220-年龄】&#xff0c;具体值建议通过实际测试校准。在跑步训练中&#xff0c;以最大心率&#xff08;Heart Rate Maximum&#xff09;为指标对强度分类&#xff0c;常见分类对应的心率区间如下&#xff1a; 强度等级心率区间&#xff08;% HR…...

【JUC】深入解析 JUC 并发编程:单例模式、懒汉模式、饿汉模式、及懒汉模式线程安全问题解析和使用 volatile 解决内存可见性问题与指令重排序问题

单例模式 单例模式确保某个类在程序中只有一个实例&#xff0c;避免多次创建实例&#xff08;禁止多次使用new&#xff09;。 要实现这一点&#xff0c;关键在于将类的所有构造方法声明为private。 这样&#xff0c;在类外部无法直接访问构造方法&#xff0c;new操作会在编译…...

2025年全国青少年信息素养大赛复赛C++算法创意实践挑战赛真题模拟强化训练(试卷3:共计6题带解析)

2025年全国青少年信息素养大赛复赛C++算法创意实践挑战赛真题模拟强化训练(试卷3:共计6题带解析) 第1题:四位数密码 【题目描述】 情报员使用4位数字来传递信息,同时为了防止信息泄露,需要将数字进行加密。数据加密的规则是: 每个数字都进行如下处理:该数字加上5之后除…...

Mongodb | 基于Springboot开发综合社交网络应用的项目案例(中英)

目录 Project background Development time Project questions Create Project create springboot project project framework create folder Create Models user post Comment Like Message Serive tier user login and register Dynamic Publishing and Bro…...

飞腾D2000与FPGA结合的主板

UD VPX-404是基于高速模拟/数字采集回放、FPGA信号实时处理、CPU主控、高速SSD实时存储架构开发的一款高度集成的信号处理组合模块&#xff0c;采用6U VPX架构&#xff0c;模块装上外壳即为独立整机&#xff0c;方便用户二次开发。 UD VPX-404模块的国产率可达到100%&#xff0…...

百度量子蜘蛛3.0横空出世,搜索引擎迎来“量子跃迁“级革命

一、量子蜘蛛3.0的三大颠覆性升级 1. 动态抓取&#xff1a;让内容实时"量子纠缠" - 智能频率调节&#xff1a;根据网站更新频率自动调整抓取节奏&#xff0c;新闻类站点日抓取量达3-5次&#xff0c;静态页面抓取间隔延长至72小时。某财经媒体通过"热点事件15分钟…...

GitHub开源|AI顶会论文中文翻译PDF合集(gpt-translated-pdf-zh)

项目核心特点 该项目专注于提供计算机科学与人工智能领域的高质量中文翻译资源&#xff0c;以下为关键特性&#xff1a; 主题覆盖广泛&#xff1a;包含算法、数据结构、概率统计等基础内容&#xff0c;以及深度学习、强化学习等前沿研究方向。格式统一便捷&#xff1a;所有文…...

JSR 303(即 Bean Validation)是一个通过​​注解在 Java Bean 上定义和执行验证规则​​的规范

&#x1f6e0;️ 一、JSR 303是什么&#xff1f; JSR 303&#xff08;Java Specification Requests 303&#xff09;是Java EE 6的子规范&#xff0c;全称​​Bean Validation​​。它通过注解方式对JavaBean的属性值进行标准化校验&#xff0c;例如检查非空、长度、格式等规则…...

5G 网络中的双向认证机制解析

一、5G 网络中的双向认证机制解析 在 5G 核心网中,双向认证是指UE(用户设备)与网络互相验证对方身份的过程。这一机制通过多层次的安全协议和密钥交换,确保通信双方的合法性,防止中间人攻击和身份伪造。 1. UE 存储的关键信息 UE 作为用户终端,存储以下核心安全信息:…...