第十四篇,STM32的CAN总线通信

2023-05-16

1.CAN总线的概念

    CAN指的是控制器局域网网络(Controller Area Network),由德国博世汽车电子厂商开发出来。

    CAN使用差分信号,具有较强的抗干扰能力和传输稳定性

    CAN属于多主通信,网络中所有的节点都可以作为主设备进行通信

    CAN的网络扩展极其方便,CAN网络中扩展了新的通信单元,网络中旧的单元和硬件无需任何改变。

    CAN具有较强的纠错能力,可以发现传输中出现的错误,并对错误节点进行隔离;所有的单元都可以检测错误;检测出错误的单元会立即同时通知其他所有单元;正在发送消息的单元一旦检测出错误,会强制结束当前的发送。被强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止。

2.CAN的差分信号

模分信号使用电平的绝对值来表示逻辑的差别;

差分信号使用两个电平的差值来表示逻辑值。CAN传输使用两根数据线 ------------- CANH和CANL

CAN总线高速ISO11898标准:

如果CANH(3.5V)和CANL(1.5V)的电压差 = 2V,此时表示逻辑0,叫做显性电平 ;

如果CANH(2.5V)和CANL(2.5V)的电压差 = 0V,此时表示逻辑1,叫做隐性电平

//如果多个节点同时控制总线电平,由总线仲裁最终显示的是显性电平(0)

3.CAN通信协议

 CAN使用5种通信帧,下面以数据帧为例来介绍帧结构

数据帧的分析:

    数据帧分为标准数据帧扩展数据帧l两种格式。

    D --- 表示显性电平

    R --- 表示隐性电平

 数据帧由7部分组成:

数据帧七个部分的实现

标准格式中标识符(ID)有11bit,从ID28到ID18被依次发送,禁止高7位都为隐性(禁止设定:ID = 1111 111X XXX);

扩展格式的ID有29bit,基本ID从ID28到ID18,扩展ID由ID17到ID0表示,禁止高7位都为隐性(禁止设定:ID = 1111 111X XXX)。
RTR位用于标识是否是远程帧(0:数据帧;1:遥控帧);

IDE位用于标识符选择位(0:使用标准标识符;1:使用扩展标识符);

SRR位代替遥控帧请求位,为隐性位,代替了标准帧中的RTR位。

(1)帧起始

显示1位显性电平

(2)仲裁段

    用来实现帧的优先级帧的过滤

1.标准帧     

标准数据帧的仲裁段由11位ID1位RTR位组成,RTR用来区分数据帧(显性电平)和遥控帧     

2.扩展帧     

扩展数据帧由 29位ID,1位RTR,1位SRR1位IDE组成;

RTR用来区分数据帧(显性电平)遥控帧     

SRR用来代替标准帧中的RTR位,由于SRR是隐性电平,相同ID的标准帧优先级高于扩展帧   

IDE用来区分标准帧(显性电平)和扩展帧,显性电平表示标准帧,隐性电平表示扩展帧     

报文的优先级由总线通过ID仲裁来判断,当总线上同时出现显性电平和隐形电平时,最终显示为显性电平;当多个节点同时竞争总线占有权时,谁先出现隐形电平,将失去总线占有权,转为接收状态   

(3)控制段

表数据帧里数据段的字节数,r0,r1为保留位,默认是显性电平 ;

4位DLC表示数据段的长度(0~8)

(4)数据段

用户需要发送的数据内容,可一次性发送0–8个字节的数据(每个数据占用一个字节)

长度0~8字节,高位先出

(5)CRC段

CRC错误校验,由15位CRC校验码和1位CRC界定符组成, 校验出了错误信息,可利用错误帧请求重发,重发次数可设定;用于检查帧传输错误(检查范围:起始端,仲裁段,控制段,数据段)。

(6)ACK段

由1位ACK槽和1位ACK界定符组成,发送方的ACK槽是隐性电平 ,接收方确认收到正确的数据后以显性电平应答

(7)帧结束

 7位隐形电平,由7个隐形位(逻辑1)组成,因此ID仲裁断禁止出现1111111****形式的格式

4.CAN的位时序

CAN传输1位由4段组成:同步段,传播段,相位缓冲段1,相位缓冲段2

1位结束后会使用再同步补偿宽度(SJW)进行再补偿。这样设计的原因是让发送方和接收方的时序保持一致(消除误差)

(1)同步段(SS)

同步段用于实现实训的调整,完成显性/隐形电平的转换,也就是准备该位要发送的电平

(2)传播时间段(PTS)

用于吸收网络上的物理延迟,物理延迟包括发送的延迟,接收的延迟和信号传播的延迟

(3)相位缓冲段(PBS)

对于电平转换未被包含的部分进行补偿,同时和SJW一起补偿各单位的时钟误差,电平的读取在该段完成。

(4)再同步补偿宽度(SJW)

补偿前面同步的误差

    接收方的采样一定在PBS1和PBS2之间,由于SS和PTS误差的变动,PBS的补偿也会随着误差的变化而变化,实现传输1位时间的固定,SJW对PBS的补偿进行二次补偿。

1位时间 = 8 ~ 25Tq, SS = 1Tq ,PTS = 1 ~ 8Tq ,PBS = 2 ~ 8Tq ,SKW = 1 ~ 4Tq

5.stm32f407的CAN控制器

    stm32芯片带有bxCAN控制器,支持CAN协议的2.0A和2.0B,最快速度1Mbps,能够自动发送CAN报文,支持标准和扩展数据帧,控制器带有三个发送邮箱存储发送的报文,还有两个FIFO,支持ID过滤,可配置自动重发等功能。

(1)工作模式

    初始化模式:初始化CAN控制器

    正常模式:正常收发数据

    睡眠模式:低功耗

(2)测试模式

    静默模式:停止对外发送报文

    环回模式:报文不发往总线,直接发给自己

    环回和静默组合模式

    测试模式

(3)传输速率

波特率 = 42MHz/分频系数/(tbs1+tbs2+sjw)

(4)接收中断

FMPx表示收到了报文

6.原理图

 查看原理图可知

CAN总结的接口最终连接到了CPU的PD0和PD1,具有CAN的复用功能。

7.CAN总线通信的库函数实现

 添加CAN通信的库函数源码

(1)开启时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);

(2)将GPIO配置为CAN复用功能

GPIO_Init(...); GPIO_PinAFConfig(...);

(3)初始化CAN

uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct);
参数:     
CANx - 哪个CAN     
CAN_InitStruct - CAN初始化结构     

typedef struct
{   
  uint16_t CAN_Prescaler;   /*!< 预分频系数 1 to 1024. */      
  uint8_t CAN_Mode;         /*!< 工作模式 @ref CAN_operating_mode */   uint8_t CAN_SJW;          /*!< 再同步补偿宽度极限值 @ref CAN_synchronisation_jump_width */   uint8_t CAN_BS1;          /*!< 相位缓冲段1长度 @ref CAN_time_quantum_in_bit_segment_1 */   uint8_t CAN_BS2;          /*!< 相位缓冲段2长度 @ref CAN_time_quantum_in_bit_segment_2 */   FunctionalState CAN_TTCM; /*!< 时间触发使能 ENABLE or DISABLE. */      FunctionalState CAN_ABOM;  /*!< 自动离线使能 ENABLE or DISABLE. */   FunctionalState CAN_AWUM;  /*!< 自动唤醒使能 ENABLE or DISABLE. */   FunctionalState CAN_NART;  /*!< 自动重发使能 ENABLE or DISABLE. */   FunctionalState CAN_RFLM;  /*!< 接收FIFO锁定使能 ENABLE or DISABLE. */   FunctionalState CAN_TXFP;  /*!< 发送FIFO优先级使能 ENABLE or DISABLE. */ } CAN_InitTypeDef;    

(4)初始化过滤器

void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);
//参数就是过滤器初始化结构

typedef struct
{ 
  uint16_t CAN_FilterIdHigh;         /*!< 过滤器ID寄存器高16位 0x0000 and 0xFFFF */   uint16_t CAN_FilterIdLow;          /*!< 过滤器ID寄存器低16位 0x0000 and 0xFFFF */   uint16_t CAN_FilterMaskIdHigh;     /*!< 过滤器ID掩码寄存器高16位 0x0000 and 0xFFFF */   uint16_t CAN_FilterMaskIdLow;      /*!< 过滤器ID掩码寄存器低16位 0x0000 and 0xFFFF */   uint16_t CAN_FilterFIFOAssignment; /*!< 接收FIFO的选择 @ref CAN_filter_FIFO */      uint8_t CAN_FilterNumber;          /*!< 过滤器编号 0 to 13. */   
  uint8_t CAN_FilterMode;            /*!< 过滤模式 @ref CAN_filter_mode */   uint8_t CAN_FilterScale;           /*!< 过滤器长度 @ref CAN_filter_scale */   FunctionalState CAN_FilterActivation; /*!< 使能/禁止 ENABLE or DISABLE. */ } CAN_FilterInitTypeDef;

(5)配置发送/接收的结构体

//发送数据结构体

typedef struct

{   uint32_t StdId;  /*!< 标准帧ID 0 to 0x7FF. */   
    uint32_t ExtId;  /*!< 扩展帧ID 0 to 0x1FFFFFFF. */   
    uint8_t IDE;     /*!< IDE标志 标准帧/扩展帧 @ref CAN_identifier_type */   
    uint8_t RTR;     /*!< RTR标志 数据帧/遥控帧 @ref CAN_remote_transmission_request */          uint8_t DLC;     /*!< 数据段长度 0 to 8 */   
    uint8_t Data[8]; /*!< 发送的数据 0 to 0xFF. */ 
} CanTxMsg;

//接收数据结构体
 typedef struct 
{ 
  uint32_t StdId;  /*!< 标准帧ID 0 to 0x7FF. */   
  uint32_t ExtId;  /*!< 扩展帧ID 0 to 0x1FFFFFFF. */   
  uint8_t IDE;     /*!< IDE标志 标准帧/扩展帧 @ref CAN_identifier_type */   
  uint8_t RTR;     /*!< RTR标志 数据帧/遥控帧 @ref CAN_remote_transmission_request */   uint8_t DLC;     /*!< 数据段长度 0 to 8 */   uint8_t Data[8]; /*!< 接收的数据 0 to 0xFF. */   uint8_t FMI;     /*!< 过滤器放入的内容 0 to 0xFF */ 
} CanRxMsg;

(6)初始化CAN的接收中断

NVIC_Init(...); CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

(7)发送和接收数据

接收:     void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage);

发送:     

    uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);     uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox);

8.上位机的使用

    打开软件

(1)串口设置

打开后会读到当前模块的配置

(2)将CAN模块设置为环回模式,波特率500Kbps

 (4)测试模块的发送和接收

9.连接模块和开发板

下一步需要编写程序实现CAN总线的通信 ,如果没有can模块进行测试,可以在初始化can 的时候把模式设置为环回模式,把数据发送给自己进行数据收发的测试。

#include <stm32f4xx.h>
#include <can.h>
#include <stdio.h>

void can1_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	CAN_InitTypeDef CAN_InitStruct;
	CAN_FilterInitTypeDef CAN_FilterInitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	
	//1.开启GPIOD和CAN1时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
	
	//2.初始化GPIO为CAN功能
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//复用模式
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//高速
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
	GPIO_Init(GPIOD,&GPIO_InitStruct);
	
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_CAN1);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_CAN1);
	
	//3.初始化CAN 42M / 4 /(1+12+8) = 500Kbps
	CAN_InitStruct.CAN_Prescaler = 4;//4分频
	CAN_InitStruct.CAN_SJW = CAN_SJW_1tq;//SJW宽度
	CAN_InitStruct.CAN_BS1 = CAN_BS1_12tq;//PBS1宽度
	CAN_InitStruct.CAN_BS2 = CAN_BS2_8tq;//PBS2宽度
	CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack;//CAN_Mode_Normal;//正常模式
	CAN_InitStruct.CAN_ABOM = DISABLE;//自动离线
	CAN_InitStruct.CAN_AWUM = DISABLE;//自动唤醒
	CAN_InitStruct.CAN_NART = DISABLE;//自动重发
	CAN_InitStruct.CAN_RFLM = DISABLE;//锁定接收
	CAN_InitStruct.CAN_TTCM = DISABLE;//时间触发
	CAN_InitStruct.CAN_TXFP = DISABLE;//发送报文优先级
	CAN_Init(CAN1,&CAN_InitStruct);
	
	//4.初始化过滤器
	CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;//使能过滤器
	CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;//安装过滤器到FIFO0
	CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask;//过滤器模式 --- 掩码
	CAN_FilterInitStruct.CAN_FilterNumber = 0;//过滤器0
	CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_16bit;//过滤器长度
	CAN_FilterInitStruct.CAN_FilterIdHigh = 0x0000;
	CAN_FilterInitStruct.CAN_FilterIdLow = 0x0000;
	CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0x0000;
	CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0x0000;
	CAN_FilterInit(&CAN_FilterInitStruct);
	
	//5.初始化CAN接收中断
	NVIC_InitStruct.NVIC_IRQChannel = CAN1_RX0_IRQn;//CAN1 FIFO0接收中断通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x2;//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x2;//响应优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能
	NVIC_Init(&NVIC_InitStruct);
	
	CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}

CanTxMsg CAN1_TX_MSG;
CanRxMsg CAN1_RX_MSG;

//can1发送函数 0 - 成功  非0 - 失败
u8 can1_send_message(u8 *data,u8 len,u32 message_id)
{
	u8 i,mailbox;
	u32 cnt = 0;
	
	if(len>8)
		return 1;
	
	//根据id选择标准帧/扩展帧
	if(message_id>0x7ff){//扩展帧
		CAN1_TX_MSG.IDE = CAN_Id_Extended;
	}
	else{
		CAN1_TX_MSG.IDE = CAN_Id_Standard;
	}
	
	CAN1_TX_MSG.RTR = CAN_RTR_Data;//数据帧
	CAN1_TX_MSG.DLC = len;//数据长度
	CAN1_TX_MSG.ExtId = message_id;//扩展帧ID
	CAN1_TX_MSG.StdId = message_id;//标准帧ID
	//发送的数据
	for(i=0;i<len;i++){
		CAN1_TX_MSG.Data[i] = data[i];
	}
	
	//发送数据等待发送成功
	mailbox = CAN_Transmit(CAN1,&CAN1_TX_MSG);
	do{
		cnt++;
	}while(CAN_TransmitStatus(CAN1,mailbox)!=CAN_TxStatus_Ok&&cnt<1000);
	
	if(cnt<1000)
		return 0;
	else
		return 1;
}

//CAN FIFO1中断处理函数
void CAN1_RX0_IRQHandler(void)
{
	if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)==SET){//收到数据
		CAN_Receive(CAN1,CAN_FIFO0,&CAN1_RX_MSG);
		/*
		//原路发回
		if(CAN1_RX_MSG.IDE==CAN_Id_Standard){//标准帧
			can1_send_message(CAN1_RX_MSG.Data,CAN1_RX_MSG.DLC,CAN1_RX_MSG.StdId);
		}
		else if(CAN1_RX_MSG.IDE==CAN_Id_Extended){
			can1_send_message(CAN1_RX_MSG.Data,CAN1_RX_MSG.DLC,CAN1_RX_MSG.ExtId);
		}
		*/
		printf("%s\r\n",CAN1_RX_MSG.Data);
		
		//清除标志
		CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);
	}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第十四篇,STM32的CAN总线通信 的相关文章

  • LWIP_MDNS

    一 xff0e mdns1 什么是mdns xff1f mDNS协议适用于局域网内没有DNS服务器时的域名解析 xff0c 设备通过组播的方式交互DNS记录来完成域名解析 xff0c 约定的组播地址是 xff1a 224 0 0 251 x
  • 组播IGMP

    一 xff0e 什么是组播 xff1f 1 一个发送 组播源 xff0c 多个接收 xff0c 接收的有个特点就是在同一个组播组里面 xff0c 组播组有自己的IP 2 对于组播源来说 xff0c 发送命令到组播IP等于把命令发送到所有组成
  • 单片机小白学习之路(四十三)---LCD12864液晶显示

    目标 xff1a LCD12864原理的理解 1 LCD12864简介 LCD12864可以用来显示字符 数字 汉字 图形等内容 xff0c 其分辨率是128 64点 意思是横着有128个点 xff0c 竖直方向有64点 LCD12864
  • stm32---红外接受

    一个脉冲对应 560us 的连续载波 xff0c 一个逻辑 1 传输需要 2 25ms xff08 560us 脉冲 43 1680us 低电平 xff09 xff0c 一个逻辑 0 的传输需要 1 125ms xff08 560us 脉冲
  • printf重定向

    C语言中printf默认输出设备是显示器 xff0c 当开发板没有时我们就用串口来打印数据 int fputc int ch FILE p USART SendData USART1 ch 如果用串口2打印 xff0c 和换成USART2
  • SPI的CRC校验计算

    22 3 6 CRC计算 CRC校验仅用于保证全双工通信的可靠性 数据发送和数据接收分别使用单独的CRC计算器 通过对每一个接收位进行可编程的多项式运算来计算CRC CRC的计算是在由SPI CR1寄存器 中CPHA和CPOL位定义的采样时
  • 记录JPA并发save时遇到的坑

    前言 在JPA中 xff0c 使用save方法时是这样的 xff1a 如果我们save的对象指定了主键 xff0c 那么会根据主键先进行一次查询 xff0c 如果查询记录不存在则执行insert语句 xff0c 如果查询记录存在则执行upd
  • Openmv(一)OpenMV图像处理的基本方法

    一 图像处理基础知识 摄像头 xff1a 光学信号转换成电信号 计算机视觉中 xff0c 最简单的模型是小孔成像模型 小孔成像是一种理想模型 xff0c 实际镜头会存在场曲和畸变等 xff0c 但可以通过在标定过程中引入畸变参数解决 xff
  • CMakeLists详解

    CMakeLists详解 一 CMake简介 cmake 是一个跨平台 开源的构建系统 它是一个集软件构建 测试 打包于一身的软件 它使用与平台和编译器独立的配置文件来对软件编译过程进行控制 二 常用命令 1 指定cmake最小版本 cma
  • c++继承与多态总结

    不知不觉C 43 43 课程的学习已经接近尾声 xff0c 感觉自己对于c 43 43 的认知更近了一步 xff0c 粗略总结一下最近学习的继承与多态部分的知识 继承 C 43 43 的继承 继承有3种形式 xff1a 私有继承 保护继承
  • C++对象的销毁

    对象的销毁 一般来说 xff0c 需要销毁的对象都应该做清理 解决方案 1 为每个类都提供一个public的free函数 xff1b 2 对象不再需要时立即调用free函数进行清理 析构函数 1 C 43 43 的类中可以定义一个特殊的清理
  • C++中类中的函数重载

    类中的函数重载 函数重载的回顾 1 函数重载的本质就是为相互独立的不同函数 xff1b 2 C 43 43 中通过函数名和函数参数确定函数调用 xff1b 3 无法直接通过函数名得到重载函数的入口地址 xff1b 4 函数重载必然发生在同一
  • C++中的字符串类

    字符串类 历史遗留的问题 1 C语言不支持真正意义上的字符串 xff1b 2 C语言用字符数组和一组实现字符串操作 xff1b 3 C语言不支持自定义类型 xff0c 因此无法获得字符类型 xff1b 解决方案 1 从C到C 43 43 的
  • MySQL中的Block Nested Loop优化分析

    前言 一般在MySQL规范中 xff0c 都会规定如果两张表进行join查询 xff0c 那么join的字段一定要有索引 xff0c 在之前的文章中我们分析了MySQL join大小表前后顺序影响分析 xff0c 这是在有索引的情况下 xf
  • C++之类模板的概念和意义

    类模板 一些类主要用于存储和组织数据元素 类中数据组织的方式和数据元素的具体类型无关 如 xff1a 数组类 链表类 Stack Queue类 等 1 C 43 43 中将模板的思想应用于类 xff0c 使得类的实现不关注数据元素的具体类型
  • C++之单例类模板

    需求的提出 在架构设计时 xff0c 某些类在整个系统生命周期中最多只能有一个对象存在 xff08 Single Instance xff09 要控制类的对象数目 xff0c 必须对外隐藏构造函数 xff1b 思路 xff1a 1 将构造函
  • 【无标题】

    绘图控件GraphicsView 一 GraphicsView简介 1 QT有多种绘图相关的技术 xff0c 我们将在第2部分 2 4 QT绘图和图表 中比较详细系统的讲 2 本节简单讲一下GraphicsView的基本理论 xff0c 并
  • uboot源码分析之start.S解析

    1 start S引入 1 1 u boot lds中找到start S入口 1 在uboot中因为有汇编阶段参与 xff0c 因此不能直接找main c 整个程序的入口取决于链接脚本中ENTRY声明的地方 ENTRY start 因此 s
  • uboot启动第二阶段

    uboot启动第二阶段 start armboot函数简介 一个很长的函数 1 这个函数在uboot lib arm board c的第444行开始到908行结束 2 450行还不是全部 xff0c 因为里面还调用了别的函数 3 为什么这么
  • cmake设置编译类型为release命令

    cmake编译类型通常默认为debug xff0c 但是在编译软件时 xff0c 一般都需要使用release版本的 xff0c debug太慢了 设置为release版本可以在cmake文件里进行 xff0c 也可以在运行cmake命令时

随机推荐

  • 设计模式之单例模式(Singleton),以C++为例,实现日志输出。

    Hello大家好 xff0c 好久没更新了 xff0c 今天给大家补上最基础的设计模式 xff1a 单例模式 这个单例模式实在是我的心结啊 xff0c 2021年末左右面试京东算法岗 xff0c 面试官让我写一个单例 xff0c 没写出来
  • 源码分析MyBatis对数值(int、double)类型进行test判断的误区

    文章目录 问题描述问题分析验证解析表达式执行解析后表达式分别测试两个条件 查询Ognl官方文档验证问题解决 问题描述 在如下判断中 xff0c 如果type类型为int xff0c 那么对于type 61 39 39 部分判断会出现一些问题
  • Git报错:error: xxxx bytes of body are still expected.

    git一个很老的项目 xff0c 项目深度很深 xff0c 报错 xff1a error 7857 bytes of body are still expected fetch pack unexpected disconnect whil
  • 设计模式之代理模式(Proxy),以C++为例,实现远程代理、虚拟代理、保护代理等。

    兄弟姐妹们好 xff0c 又是好久没有更新了 xff0c 今天给大家简单介绍代理模式 xff0c 一个很简单的设计模式 xff0c 旨在不改变原对象的情况下通过代理对象来控制对原对象的访问 代理模式根据具体情况还可以分为远程代理 虚拟代理
  • C++ 互斥锁原理以及实际使用介绍

    兄弟姐妹们 xff0c 我又回来了 xff0c 今天带来实际开发中都需要使用的互斥锁的内容 xff0c 主要聊一聊如何使用互斥锁以及都有哪几种方式实现互斥锁 实现互斥 xff0c 可以有以下几种方式 xff1a 互斥量 xff08 Mute
  • 【C++】使用【windwos api】获取windwos计算机的基本信息

    今天来一篇获取windows计算机的基本信息的文章 xff0c 包含计算机名称 操作系统版本 处理器信息 内存信息 硬盘信息 显示器信息 网络信息 驱动程序信息 电源信息 其他硬件信息 目录 一 windwos系统包含的基本信息 二 获取信
  • C++ POCO库的基础介绍(Windwos和Linux)

    简单介绍C 43 43 POCO库能干什么 xff0c 后续有时间的话将根据其每个点详细解析 xff0c 关注我 本篇包含POCO库简单介绍 下载以及安装方式 简单代码示例 目录 一 POCO简单介绍 1 1 POCO库的基本模块 1 2
  • ROS踩坑记录

    ROS踩坑记录 问题 xff1a ubuntu 没有 dev ttyUSB0问题 xff1a 运行 launch 文件或 ROS 节点时出现 exit code 9 错误提示问题 xff1a windows使用vscode远程连接 xff0
  • STM32串口数据接收 --环形缓冲区

    STM32串口数据接收 环形缓冲区 环形缓冲区简介 在单片机中串口通信是我们使用最频繁的 xff0c 使用串口通信就会用到串口的数据接收与发送 xff0c 环形缓冲区方式接收数据可以更好的保证数据丢帧率第 在通信程序中 xff0c 经常使用
  • 如何设计安全可靠的开放接口---对请求参加密保护

    文章目录 如何设计安全可靠的开放接口 系列前言AES加解密代码实现 如何设计安全可靠的开放接口 系列 1 如何设计安全可靠的开放接口 之Token 2 如何设计安全可靠的开放接口 之AppId AppSecret 3 如何设计安全可靠的开放
  • rosdep init报错解决方法

    rosdep init报错解决方法 很多小伙伴在安装ROS的过程中都不可避免的要执行rosdep init和rosdep update这两行命令行 xff0c 这也是在安装ROS的过程中最让人头疼的两步 xff0c 一般都没法一次成功 xf
  • NVIDIA Jetson Nano/Xavier NX 扩容教程

    在售的 NVIDIA Jetson 内置 16 GB 的 eMMC xff0c 并已安装了 ubuntu 18 04 LTS 和 NVIDIA JetPack 4 6 xff0c 所以剩余的用户可用空间大约 2GB xff0c 这对将 NV
  • 深度学习框架YOLOv3的C++调用

    深度学习框架YOLOv3的C 43 43 调用 深度学习框架YOLOv3的C 43 43 调用 xff08 1 xff09 tensorflow版本的YOLOv3的C 43 43 调用 xff08 失败 xff09 xff08 2 xff0
  • 基于GPT-2实现图像文本生成

    原理 使用GPT 2模型处理文本 xff0c 做decoder 使用google的vit base patch16 224模型处理图像 xff0c 做encoder 最后通过VisionEncoderDecoderModel将这两个模型粘起
  • C语言中常见的两个比较字符串是否相等的函数strcmp和strncmp

    函数 xff1a strcmp和strncmp strcmp 使用格式 xff1a include lt string h gt int strcmp const char s1 const char s2 设这两个字符串为str1 xff
  • sprintf和printf 用法的区别

    printf 的作用是标准化输出 xff0c 默认的对象是标准输出缓冲区 xff0c 要有一定的条件才能把缓冲区里面的数据输出 sprintf 作用是格式化输出函数 xff0c 保存字符串到缓冲区中 xff0c 起到拼接字符串的作用 功能
  • 第六篇,STM32脉冲宽度调制(PWM)编程

    1 PWM概念 PWM叫脉冲宽度调制 Pulse Width Modulation xff0c 通过编程控制输出方波的频率和占空比 高低电平的比例 xff0c 广泛应用在测量 xff0c 通信 xff0c 功率控制等领域 呼吸灯 xff0c
  • 第十篇,STM32串口蓝牙编程

    1 串口蓝牙概念 串口蓝牙是一个蓝牙模块 xff0c 内部有蓝牙模块和程序 xff0c 可以进行蓝牙通信 xff0c 同时提供一个串口接口 xff0c 通过串口可以配置蓝牙模块进行数据传输 2 使用串口3连接蓝牙模块 3 手机上安装蓝牙调试
  • LeetCode岛屿问题通用解决模板

    文章目录 前言第一题 xff1a 求岛屿的周长模板整理遍历方向确定边界重复遍历问题处理 模板解第一题第二题 xff1a 求岛屿数量第三题 xff1a 岛屿的最大面积第四题 xff1a 统计子岛屿第五题 xff1a 统计封闭岛屿的数目第六题
  • 第十四篇,STM32的CAN总线通信

    1 CAN总线的概念 CAN指的是控制器局域网网络 Controller Area Network xff0c 由德国博世汽车电子厂商开发出来 CAN使用差分信号 xff0c 具有较强的抗干扰能力和传输稳定性 CAN属于多主通信 xff0c