AIR32F103(九) CAN总线的通信和ID过滤机制及实例

news2024/11/15 21:37:03

目录

  • AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告
  • AIR32F103(二) Linux环境和LibOpenCM3项目模板
  • AIR32F103(三) Linux环境基于标准外设库的项目模板
  • AIR32F103(四) 27倍频216MHz,CoreMark跑分测试
  • AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码
  • AIR32F103(六) ADC,I2S,DMA和ADPCM实现的录音播放功能
  • AIR32F103(七) AIR32F103CBT6/CCT6启用96K内存
  • AIR32F103(八) 集成Helix MP3解码库播放MP3
  • AIR32F103(九) CAN总线的通信和ID过滤机制及实例

CAN 总线

CAN是 Controller Area Network 的简称, 最初由BOSCH公司开发, 后来成为国际标准(ISO 11898), 是当前应用最广泛的现场总线之一, 是汽车控制系统和嵌入式工业控制局域网事实上的标准.

CAN 总线的物理连接

相对于近距离传输的I2C, SPI协议, 以及RS485总线, CAN 总线定义了更先进的物理层和链路层, 以及种类丰富的上层协议. 与I2C, SPI等基于时钟信号同步的通讯方式不同, CAN通讯不使用时钟信号进行同步, 它是一种异步通讯, 只有 CAN_High 和 CAN_Low 两条信号线, 共同构成一组差分信号线, 以差分信号的形式进行通讯.

CAN 物理层主要分为闭环总线及开环总线网络两种形式, 一个适合于高速通讯, 一个适合于远距离通讯.

  • CAN闭环通讯网络是一种遵循 ISO11898 标准的高速, 短距离网络, 总线最大长度为40m, 通信速度最高为1Mbps, 总线的两端各要求有一个120欧的电阻做阻抗匹配, 减少回波反射.
  • CAN开环总线网络是遵循 ISO11519-2 标准的低速, 远距离网络, 最大传输距离为1km, 最高通讯速率为125kbps, 两根总线互相独立, 不形成闭环, 要求每根总线上各串联有一个 2.2KR 的电阻.

关于共地

CAN 在多个收发器之间的连接, 可以不共地, 只需要 CANH 和 CANL 两线连接.

CAN 总线的通信机制

CAN总线上可以挂载多个通讯节点, 节点之间的信号经过总线传输, 实现节点间通讯. CAN通讯协议不对节点进行地址编码, 而是对数据内容进行编码, 所以网络中的节点个数理论上不受限制, 只要总线的负载足够即可, 可以通过中继器增强负载.

CAN通讯节点由一个CAN控制器及CAN收发器组成, 控制器与收发器之间通过 CAN_Tx及 CAN_Rx 信号线相连, 收发器与CAN总线之间使用 CAN_High 及 CAN_Low 信号线相连. 其中 CAN_Tx 及 CAN_Rx 使用普通的类似TTL逻辑信号, 而 CAN_High 及 CAN_Low 是一对差分信号线, 当CAN节点需要发送数据时, 控制器把要发送的二进制编码通过 CAN_Tx 线发送到收发器, 然后由收发器把这个普通的逻辑电平信号转化成差分信号, 通过差分线 CAN_High 和 CAN_Low 输出到CAN总线网络. 收发器接收总线上的数据时则是相反的过程, 收发器把总线上收到的 CAN_High 及 CAN_Low 信号转化成普通的逻辑电平信号, 再通过 CAN_Rx 输出到控制器中.

差分信号

差分信号又称差模信号, 与传统使用单根信号线电压表示逻辑的方式有区别, 使用差分信号传输时, 需要两根信号线, 这两个信号线的振幅相等, 相位相反, 通过两根信号线的电压差值来表示逻辑0和逻辑1. 相对于单信号线传输的方式, 使用差分信号传输具有如下优点

  • 抗干扰能力强, 当外界存在噪声干扰时, 几乎会同时耦合到两条信号线上, 而差分信号只关心两个信号的差值, 所以外界的共模噪声可以被抑制
  • 能有效抑制它对外部的电磁干扰, 由于两根信号的极性相反, 对外辐射的电磁场可以相互抵消, 耦合的越紧密, 泄放到外界的电磁能量越少
  • 时序定位精确, 由于差分信号的开关变化是位于两个信号的交点, 而不像普通单端信号依靠高低两个阈值电压判断, 因而受工艺, 温度的影响小, 能降低时序上的误差, 同时也更适合于低幅度信号的电路

由于差分信号的这些优点, 在USB协议, 485协议, 以太网协议及CAN协议的物理层中, 都使用了差分信号传输.

CAN协议中的差分信号

CAN协议中对它使用的 CAN_High 及 CAN_Low 表示的差分信号做了规定. 以高速CAN协议为例, 当表示逻辑1时(隐性电平), CAN_High 和 CAN_Low 线上的电压均为2.5V, 即它们的电压差为 0, 而表示逻辑0时(显性电平), CAN_High的电平为 3.5V, CAN_Low线的电平为1.5V, 电压差为 2V.

CAN 总线的特点

CAN 总线网络是一种多主网络, 在总线处于空闲状态时, 任何一个节点单元都可以申请成为主机, 向总线发送消息. 其原则是: 最先访问总线的节点单元可以获得总线的控制权, 多个节点单元同时尝试获取总线的控制权时, 将发生仲裁事件, 具有高优先级的节点单元将获得总线控制权.

CAN 协议中, 所有的消息都以固定的数据格式打包发送. 两个以上的节点单元同时发送信息时, 根据节点标识符(常称为 ID, 打包在固定的数据格式中)决定各自优先级关系, CAN 总线没有其他总线的地址概念, 在总线上增加节点单元时, 连接在总线的其他节点单元的软硬件都不需要改变.

CAN 总线的通信速率和总线长度有关, 在总线长度小于 40m 的场合中, 数据传输速率可以达到 1Mbps, 而即便总线长度上升至 1000m, 数据的传输速率仍可达到 50Kbps, 无论在速率还是传输距离都明显优于常见的 RS232, RS485 和 I2C 总线.

对于总线错误, CAN 总线有错误检测功能, 错误通知功能, 错误恢复功能三种应对措施, CAN 总线上的每个节点都可以通过判断得出, 当前总线上的错误是暂时错误(如瞬间的强干扰)还是持续错误(如总线断裂). 当总线上发生持续错误时, 引起故障的节点单元会自动脱离总线.

CAN 总线上的节点数量在理论上没有上限, 但在实际上收到总线上的时间延时及电气负载的限制. 降低最大通信速率可以增加节点单元的连接数, 反之减少节点单元的连接数则最大通信速率可以提高.

CAN 总线通信

CAN 数据位传输时间

为了实现位同步, CAN协议把每一个数据位(bit)的时序分解成SS段, PTS段, PBS1段, PBS2段, 这四段的长度加起来即为一个CAN数据位的长度.

CAN传输的最小的时间单位是Tq(即CAN外设的时钟周期), 一个完整的位由8~25个Tq组成.

CAN 的数据帧

CAN 总线的数据通信是以数据帧的格式进行的, 了解CAN的数据帧, 可以帮助了解CAN的过滤机制. 下面是一个完整的CAN数据帧的结构

CAN Data Frame

  • SOF 应该是 start of frame, 一个bit位拉低总线用于开始传输
  • Identifier 就是数据的 ID, 11个bit
  • RTR (Remote Transmission Request) 用于声明这是一个数据帧还是一个远程帧
  • IDE 用于声明使用的标准ID还是扩展ID
  • r 是一个保留 bit
  • DLC 用于声明后面携带的数据字节数量
  • Data Field 包含的是发送的数据, 最多不超过8个字节
  • Checksum 和 DEL 是校验码和对应的分隔符
  • ACK 和 DEL 是响应位和对应的分隔符

CAN 数据帧对应的代码

用C语言描述的CAN帧整体结构为

CAN_TxHeaderTypeDef   TxHeader;
uint8_t               TxData[8];
uint32_t              TxMailbox;
  • TxHeader 用于存储头信息, 包含了 RTR, DLC 等, 在SPL中对应的类型为 CAN_TxHeaderTypeDef
  • TxData 用于存储传输的数据
  • TxMailbox 用于发送此消息的 mailbox

帧头的结构和帧数据

TxHeader.StdId = 0x446;
TxHeader.RTR = CAN_RTR_DATA;  // Remote or data frame
TxHeader.IDE = CAN_ID_STD;    // Standard or extended
// reserved bit
TxHeader.DLC = 2;             // Data length in bytes
  • CAN_ID_STD 表示使用了标准ID模式(非扩展ID)
  • 0x446 就是发送的ID, 位宽最大为 11-bit
  • CAN_RTR_DATA 表示这个帧为数据帧
  • DLC 标识后面数据的字节长度, 因为发送两个字节, 所以这里是2
  • 随后在 TxData 中存储两个字节
TxData[0] = 50;  
TxData[1] = 0xAA;

AIR32F103 / STM32 的 CAN 外设

以下的描述适用于AIR32F103和STM32.

bxCAN 控制器 (Basic Extended CAN) 支持CAN协议2.0A和2.0B标准. 该CAN控制器支持最高的通讯速率为1Mbps, 可以自动地接收和发送CAN报文, 支持使用标准ID和扩展ID的报文. 外设中具有3个发送邮箱, 发送报文的优先级可以使用软件控制, 还可以记录发送的时间;具有2个3级深度的接收FIFO, 可使用过滤功能只接收或不接收某些ID号的报文; 可配置成自动重发; 不支持使用DMA进行数据收发.

CAN波特率的计算

通过配置位时序寄存器CAN_BTR的TS1[3:0]及TS2[2:0]寄存器位设定BS1及BS2段的长度后, 可以确定每个CAN数据位的时间

BS1段时间

Tbs1 =Tq x (TS1[3:0] + 1)

BS2段时间

Tbs2 = Tq x (TS2[2:0] + 1)

整个数据位的时间

Tbit = 1Tq + Tbs1 +Tbs2 = 1 + (TS1[3:0] + 1)+ (TS2[2:0] + 1)

Tq 是 CAN 通信的最小时间单元, 与 CAN 时钟总线及分频器配置有关, CAN1和CAN2外设都是挂载在APB1总线上的, 而位时序寄存器 CAN_BTR 中的 BRP[9:0] 寄存器位可以设置CAN外设时钟的分频值 , 所以

Tq = brp * Tpclk = (BRP[9:0]+1) * Tpclk

其中的PCLK指APB1时钟, 默认值为36MHz. 可以计算出 CAN 的波特率:

BaudRate = 1 / Tbit = Fpclk / ((Tbs1 + Tbs2 + 1) * brp)

CAN 波特率的设置

CAN_InitStructure.CAN_TTCM = DISABLE; // time triggered communication mode off
CAN_InitStructure.CAN_ABOM = DISABLE; // automatic bus-off management off
CAN_InitStructure.CAN_AWUM = DISABLE; // automatic wake-up mode off, wakeup by software cleaar CAN->MCR SLEEP bit
CAN_InitStructure.CAN_NART = ENABLE;  // no-automatic retransmission mode on
CAN_InitStructure.CAN_RFLM = DISABLE; // rx FIFO Locked mode off
CAN_InitStructure.CAN_TXFP = DISABLE; // transmit FIFO priority off
CAN_InitStructure.CAN_Mode = mode;
// Set baud rate
CAN_InitStructure.CAN_SJW = tsjw;      // synchronisation_jump_width, CAN_SJW_1tq ~ CAN_SJW_4tq
CAN_InitStructure.CAN_BS1 = tbs1;      // number of time quanta in Bit Segment 1, CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_BS2 = tbs2;      // number of time quanta in Bit Segment 2, CAN_BS1_1tq ~ CAN_BS1_16tq
CAN_InitStructure.CAN_Prescaler = brp; // clock prescaler, 1~1024
CAN_Init(CAN1, &CAN_InitStructure);

CAN 的ID过滤机制

CAN 是一种典型的广播式网络, 在实际应用中, 如果只希望接收到特定类型的数据, 就要借助过滤器来实现. AIR32/STM32的CAN控制器包含14个过滤器, 可以设置为 屏蔽模式列表模式 对CAN总线上的报文进行过滤. 当节点希望接收到一种报文时, 可以用屏蔽位模式进行过滤, 当节点希望接受到单一类型报文时, 应该配置为列表模式.

CAN控制器的每个过滤器都具备一个寄存器, 称为屏蔽寄存器。其中标识符寄存器的每一位都有屏蔽寄存器的每一位所对应.

AIR32/STM32 使用 CAN 外设内建的过滤器, 初始化代码为

  CAN_FilterTypeDef canfilterconfig;

  canfilterconfig.FilterActivation = CAN_FILTER_ENABLE;
  canfilterconfig.FilterBank = 18;  // 指定使用哪个过滤器
  canfilterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  canfilterconfig.FilterIdHigh = 0x103<<5;
  canfilterconfig.FilterIdLow = 0;
  canfilterconfig.FilterMaskIdHigh = 0x103<<5;
  canfilterconfig.FilterMaskIdLow = 0x0000;
  canfilterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
  canfilterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
  canfilterconfig.SlaveStartFilterBank = 20;  // how many filters to assign to the CAN1 (master can)

  HAL_CAN_ConfigFilter(&hcan1, &canfilterconfig);

FilterMode 用于设置过滤模式, 在STM32中有两种过滤模式, 这里使用的是掩码模式

  • MASK MODE, 掩码模式, 使用寄存器中设置的掩码对接收到的ID中特定的位进行比较.
  • LIST MODE, 列表模式, 对于接收到的ID, 直接使用寄存器中的ID进行比较.

FilterScale 用于指定是 1)一个32bit的过滤寄存器, 还是 2)两个16bit的过滤寄存器. 这里使用的是一个 32 Bit 寄存器.

FilterIdHigh 用于设置 ID 寄存器的高16 Bits, 这里的值会被用于与输入的ID进行比较. 这里只比较接收到的消息的标准ID, 因此将值左移5位, STD ID 从 ID HIGH Register 的第5位开始.

FilterMaskIdHigh 是掩码寄存器的高16 Bits, 在对接收到的消息的ID进行比较时, 会忽略这个寄存器中bit=0的位, 仅对会对bit=1对应的位, 与ID寄存器中对应的位进行比较.

掩码模式过滤的图例说明

上图中, CAN_FxR1 和 CAN_FxR2 都是32bit寄存器, 用于存储过滤器的 ID 和 Mask 设置, 红色框和绿色框分别对应代码中的 FilterIdHigh + FilterIdLow 和 FilterMaskIdHigh + FilterMaskIdLow.

  1. 这个例子中仅使用标准ID, 不使用扩展ID时, 低5位可以忽略
  2. 设置ID和Mask时, 都要将需要设置的ID值(0x103)左移5位, 因为低5位用于extId
  3. 与接收的ID对比时, 会根据Mask中bit值为1的位, 与ID中的对应bit进行比较, Mask中bit为0的位都会忽略. 这个例子中需要比较的位是0, 1 和 8
  4. 接收到的ID, 与ID寄存器中对应bit的值进行比较, 当这几个bit的值都一致时, ID就是匹配的, 消息就会被接收, 否则会被过滤

根据上面的设置

  • 如果输入的是0x102, 根据Mask设置, 第0,1,8位会用于比较, 而ID的第0位为1, 所以这个输入会被忽略
  • 如果输入的是0x107, 根据Mask设置, 第0,1,8位会用于比较, ID设置的这三位都是1和输入的一致, 所以这个输入会被接收

带扩展ID的例子

根据手册 standard frames with 11-bit identifiers as well as extended frames with 29-bit identifiers, 扩展帧除了原有的 11 bits 标准ID外, 还带 18 bits 的扩展ID. 为什么是29 bits? 因为后面还有3个bit的功能标志位

如果

  • 将 stdId 和 extId 合并为一个29位的 filterId, 其结构为 EXTID[17:0] | STDID[10:0] (从高bit位到低bit位)
  • 将对应的 mask 也合并为一个29位的 filterMask, 其结构为 EXTMASK[17:0] | STDMASK[10:0]

过滤条件的设置代码为

// 取值 STID[10:0] & EXTID[17:13], 因为 CAN_FilterIdHigh 是 16bit, 所以 filterId << 5 的高16bit会被忽略.
filter.CAN_FilterIdHigh = ((filterId << 5)  | (filterId >> (32 - 5))) & 0xFFFF;
// 取值 EXID[12:5] & 3 Reserved bits, 这里同样, filterId 移位后的高16bit会被忽略
filter.CAN_FilterIdLow = (filterId >> (11 - 3)) & 0xFFF8;
// 与上面同理
filter.CAN_FilterMaskIdHigh = ((filterMask << 5)  | (filterMask >> (32 - 5))) & 0xFFFF;
filter.CAN_FilterMaskIdLow = (filterMask >> (11 - 3)) & 0xFFF8;

测试示例

硬件准备

  • TJA1050 或 MCP2551 的 CAN 收发模块 x 2, 可以混合使用, TJA1050 与 MCP2551 可以互相通信
  • 带 AIR32F103 的开发板

因为 TJA1050 和 MCP2551 都是5V供电, 因此开发板上要有5V输出, 否则需要单独供电

示例代码

代码仓库目录 https://github.com/IOsetting/air32f103-template/tree/master/Examples/NonFreeRTOS/CAN

这个目录下包含两个模式的例子, 一个是 Loopback, 一个是 Normal, 从合宙官方仓库的例子参考(抄)的.

Loopback 模式

Loopback 是测试模式, 发送的数据不进入总线直接进入接收队列, 用于检查 MCU 与 CAN 收发器之间通信是否正常, 以及 CAN 收发器是否正常工作. 运行后在串口输入’s’, 会发送8个字节并将接收到的数据通过串口回显.

Normal 模式

正常的通信模式, 需要两套 MCU + CAN 收发器. CAN 收发器之间通过 CANH 和 CANL 连接. 代码中设置过滤器时, 使用的是相同的 ID 和 Mask 值, 对两个MCU编译烧录时需要将 ID_TARGET 和 ID_RECEIV 的值互换一下.

运行后, 在一侧串口输入’s’, 在另一侧会通过串口显示接收到的数据.

问题

在测试中, 一开始给 TJA1050 错误使用了 3.3V 电压, 在 Loopback 模式工作正常, 但是在 Normal 模式工作不正常, 只有将两边收发器共地才能正常通信, 如果换成 MCP2551 则完全不能通信.

这些问题在将电压换成 5V 后就正常了.

参考

  • CAN Protocol in STM32 https://controllerstech.com/can-protocol-in-stm32/
  • Does The CAN Bus Need a Common Ground? https://www.edn.com/does-the-can-bus-need-a-common-ground/
  • STM32 CAN Communication || NORMAL Mode https://www.youtube.com/watch?v=KHNRftBa1Vc&t=104s

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zookeeper完全分布式集群服务

准备好3台服务器:[x]A-> centos7s:192.168.19.1[x]B-> centos7_1:192.168.19.2[x]C-> centos7_2:192.168.19.3配置Zookeeper安装目录在3台宿主机配置zookeeper安装目录&#xff1a;/docker/develop/zookeeper并且在文件夹创建 data 和logs 目录&#xff1a;mkdir -p /…

STM32Cube串口USART发送接收数据

本文代码使用 HAL 库。 文章目录前言一、USART 同步/异步串行接收/发送器二、USART 原理图三、CubeMX 创建工程四、usart.c 文件解析五&#xff0c;设计实验&#xff1a;在 串口输入字符点亮led实验现象&#xff1a;总结前言 这篇文章介绍 实现 USART 异步模式下 通过 串口助手…

去了字节跳动,才知道年薪40W的测试居然有这么多?

今年大环境不好&#xff0c;内卷的厉害&#xff0c;薪资待遇好的工作机会更是难得。最近脉脉职言区有一条讨论火了&#xff1a; 哪家互联网公司薪资最‘厉害’&#xff1f; 下面的评论多为字节跳动&#xff0c;还炸出了很多年薪40W的测试工程师 我只想问一句&#xff0c;现在的…

【设计模式】 观察者模式介绍及C代码实现

【设计模式】 观察者模式介绍及C代码实现 背景 在软件构建过程中&#xff0c;我们需要为某些对象建立一种“通知依赖关系”&#xff0c;即一个对象&#xff08;目标对象&#xff09;的状态发生改变&#xff0c;所有的依赖对象&#xff08;观察者对象&#xff09;都将得到通知。…

连续隐身四天、被传退出德云社,于谦未参加相声大会的原因找到了

欲戴皇冠&#xff0c;必受其重。意思就是一个人拥有一定的地位和声望&#xff0c;就会承担由此带来的责任和压力。 就拿德云社郭德纲搭档于谦来说&#xff0c;虽然他是一个谦虚低调的人&#xff0c;但是因为郭德纲老师名气太大&#xff0c;也让于谦伴随着一起名声鹊起。于谦老师…

chatgpt的原理 第三部分

对话 我们是如何学会中文的&#xff1f;从0岁开始&#xff0c;听、说&#xff0c;也就是对话。 我们是如何学外语的&#xff1f;看教材&#xff0c;听广播&#xff0c;背单词。唯独缺少了对话&#xff01;正是因为缺少了对话这个高效的语言学习方式&#xff0c;所以我们的英语…

8个小程序开源项目助你快速搭建小程序

今天和大家分享几个小程序开源项目, 帮助我们轻松搭建自己的小程序应用. 我会从大家最熟悉的小程序UI组件, 到可视化库, 再到完整项目, 一一和大家介绍.小程序UI组件库小程序多端开发框架小程序可视化图表库经典小程序开源项目小程序UI组件库1. vant-weappVant Weapp 是移动端 …

MXNet中使用卷积神经网络textCNN对文本进行情感分类

在图像识别领域&#xff0c;卷积神经网络是非常常见和有用的&#xff0c;我们试图将它应用到文本的情感分类上&#xff0c;如何处理呢&#xff1f;其实思路也是一样的&#xff0c;图片是二维的&#xff0c;文本是一维的&#xff0c;同样的&#xff0c;我们使用一维的卷积核去处…

LLVM程序分析与编译转换框架论文分享

LLVM 2004年论文原文 概述 本文描述了 LLVM&#xff08;低级虚拟机&#xff09;&#xff0c;一种编译器框架&#xff0c;旨在通过在编译时、链接时、运行时&#xff0c;以及运行之间的空闲时间。 LLVM 以静态单一赋值 (SSA) 形式定义了一种通用的低级代码表示&#xff0c;具有…

多区域的OSPF实战配置

多区域的OSPF实战配置 需求 如图配置设备的接口IP地址如图规划OSPF网络的区域要求每个设备的 router-id 都是 x.x.x.x&#xff08;x是每个路由器的名字&#xff09;确保不同的PC之间可以互通 拓扑图 配置命令 PC1&#xff1a; 192.168.1.1 255.255.255.0 192.168.1.254PC2:…

【手把手一起学习】(六) Altium Designer 20 STM32核心板Demo----PCB设计

1 PCB设计 PCB设计是制作STM32核心板的关键步骤&#xff0c;其关系到最终生产厂家制作的电路板能否正常使用&#xff0c;PCB设计包括布局&#xff0c;裁板&#xff0c;布线&#xff0c;覆铜&#xff0c;DRC检查等&#xff0c;其中要求、细节、技巧比较多&#xff0c;以后会更详…

redis(7)哈希Hash

哈希Hash Redis hash 是一个键值对集合。 Redis hash 是一个 string 类型的 field 和 value 的映射表&#xff0c;hash 特别适合用于存储对象。 类似 Java 里面的 Map<String,Object>。 用户 ID 为查找的 key&#xff0c;存储的 value 用户对象包含姓名&#xff0c;年…

西北工业大学大学物理(II)选填解析2019-2020期末

2 又是考查“一个电子和一个光子具有相同的波长&#xff0c;则二者动量相等。”4 斯特恩盖拉赫实验&#xff0c;原子的自旋磁矩取向量子化。7 通常我们感受不到电子的波动性。因为其波长短&#xff0c;其实也就是粒子运动速率高。10 考查无限长直导线周围B分布。常见的模型要记…

【035】基于Vue的电商推荐管理系统(含源码数据库、超详细论文)

摘 要&#xff1a;基于Vue&#xff0b;Nodejs&#xff0b;mysql的电商推荐管理系统&#xff0c;这个项目论文超详细&#xff0c;er图、接口文档、功能展示、技术栈等说明特别全&#xff01;&#xff01;&#xff01; &#xff08;文末附源码数据库、课设论文获取方式&#xff0…

xgboost学习-原理

文章目录一、xgboost库与XGB的sklearn APIXGBoost的三大板块二、梯度提升树提升集成算法&#xff1a;重要参数n_estimators三、有放回随机抽样&#xff1a;重要参数subsample四、迭代决策树&#xff1a;重要参数eta总结一、xgboost库与XGB的sklearn API 现在&#xff0c;我们有…

【ROS学习笔记4】话题通信

【ROS学习笔记4】话题通信 文章目录【ROS学习笔记4】话题通信零、话题通信概述一、话题通信的理论模型二、话题通信基本操作的Cpp实现三、话题通信基本操作的Python实现四、话题通信自定义msg五、话题通信自定义msg调用的Cpp实现六、话题通信自定义msg的Python实现七、Referenc…

《MySQL学习》 Order by 工作原理

《MySQL学习》 Order by 工作原理 一.排序缓存 sort_buffer 当我们使用explain 分析一条带有排序操作的SQL语句时&#xff0c;会看到Extra中有使用 Using filesort explain select * from t order by k descMySQL 会为每个线程分配固定大小的 sort buffer 用作排序。 sort b…

SAP 怎么冲销已冲销的凭证?

假如有这么一种场景&#xff1a;你做了一张凭证A&#xff0c;你第一次发现账务做错了。你用fb08来冲销A&#xff0c;生成了冲销凭证B&#xff0c;然后第二次检查的时候你发现&#xff0c;凭证A其实没错&#xff0c;这时候能不能把冲销凭证B撤销掉&#xff1f; 然后凭证A就恢复了…

【C语言每日一题】猜名次

【C语言每日一题】—— 猜名次&#x1f60e;&#x1f60e;&#x1f60e; &#x1f4a1;前言&#x1f31e;&#xff1a; &#x1f49b;猜名次题目&#x1f49b; &#x1f4aa; 解题思路的分享&#x1f4aa; &#x1f60a;题目源码的分享&#x1f60a; &#x1f449; 本菜鸡…

【MySQL】增删改操作(基础篇)

目录 1、新增操作(Create) 1.1 单行数据 全列插入 1.2 多行数据 全列插入 1.3 单行数据 指定列插入 2、修改操作(Update) 3、删除操作(Delete) 1、新增操作(Create) 如何给一张表新增数据呢&#xff1f; 新增(Create)&#xff0c;在我们数据库中&#xff0c;用 ins…