CAN通信学习笔记

1. CAN简介

CAN(Controller Area Network) 总线是一种串行通信协议,用于汽车和工业控制领域,CAN 总线广泛用于汽车的发动机控制、底盘控制、车身控制等系统。

CAN总线协议物理层只有一对差分线,在一个时刻下只能表示一个信号。所以CAN 是半双工的通讯协议

差分信号:

差分信号优点

  • 抗干扰能力强

  • 能有效抑制它对外部的电磁干扰

  • 时序定位精确

为什么差分信号抗干扰能力强、时序定位精确?

抗干扰能力强:差分信号利用两个相邻信号的差值,从而消除它们之间的共模部分。共模干扰是同时影响两个信号的干扰,而差分信号只关心差异,可以更有效地抵消这些共模干扰

时序定位精确:由于差分信号关注信号之间的差异,它对于时序误差更为敏感。这使得在时序定位方面具有更高的精确度。通过比较相邻信号的变化,可以更准确地测量时间差或时间序列中的变化

共模:信号之间的共模部分指的是两个或多个信号中具有相同或相似特性的部分。这种相同或相似的部分被称为共模信号,而与之相对的是差模信号,即两个信号之间的差异部分

具体来说,如果有两个信号A和B,它们的共模部分是指两者同时发生相同的变化或波动的部分。这可能是由于外部环境的影响、干扰源、或系统内部的共同因素引起的。共模信号在信号处理和通信系统中通常被视为干扰源,因为它们不携带有用信息,而是引入了额外的噪音或失真。对于抗干扰设计,特别是在差分信号处理中,差分信号关注的是两个信号之间的差异,即差模部分,而忽略了它们的共模部分。通过消除或抵消共模部分,系统可以更有效地抗干扰,提高信号质量和系统性能。这是为什么差分信号在一些应用中具有较强抗干扰能力的原因之一

实现CAN通信需要满足以下条件

  1. 设置 CAN 工作模式和波特率。

  2. 配置消息 ID 和数据字段。

  3. 实现发送和接收 FIFO 队列。

  4. 中断服务程序处理各种事件。

2. CAN物理层

CAN 物理层通讯,不是以时钟信号来同步的,其是一种异步通讯,只有 CAN_HighCAN_Low 两条信号,共同构成差分信号线,以差分信号的形式进行通讯

CAN物理层连接形式有两种

  • 闭环总线通讯网络:是一种遵循ISO11898 标准的高速、短距离“闭环网络”,它的总线最大长度为 40m,通信速度最高为 1Mbps,总线的两端各要求有一个“120 欧”的电阻

  • 开环总线通讯网络:是遵循 ISO11519-2 标准的低速、远距离“开环网络”,它的最大传输距离为 1km,最高通讯速率为 125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2 千欧”的电阻

闭环总线通讯网络使用120欧姆的电阻,作用是用来进行阻抗匹配,减小信号的反射和提高信号的稳定性

开环总线通讯网络使用2.2K欧姆的电阻,作用是减小功耗,并简化连接

CAN通讯节点

CAN总线上可以挂载多个通讯节点,节点之间通过总线传输信号,实现节点间通讯。

由于CAN通信协议不对节点进行地址编码,而是对数据内容进行编码,所以网络中的节点个数理论上不受限制,只要总线负载足够

CAN通讯节点组成

  • CAN 通讯节点由 CAN 控制器及 CAN 收发器组成

  • 控制器与收发器之间通过CAN_TxCAN_Rx信号线相连

  • 收发器与 CAN 总线之间使用 CAN_HighCAN_Low 信号线相连

  • CAN_TxCAN_Rx 使用的是TTL逻辑信号(即+5V等价于逻辑“1”,0V等价于逻辑“0”(采用二进制来表示数据时))

  • CAN_HighCAN_Low 使用的是一对差分信号

在CAN总线通信中,控制器(Controller)和收发器(Transceiver)各自具有以下功能:

  1. 控制器(Controller): (1) 支持CAN协议,实现消息的发送和接收; (2) 位时序、同步、仲裁管理; (3) 消息缓存、过滤和仲裁判断; (4) 错误检测、报文重传等功能。

  2. 收发器(Transceiver): (1) 电气隔离,在控制器和总线物理层间实现电平转换; (2) 总线电压生成,以实现差分信号发送; (3) 总线端接处理,提供保护电阻和端接电容; (4) 滤波、放大收发信号实现物理层传输。

总结为: 控制器主要是CAN协议功能、消息处理; 收发器主要是电气隔离转换,实现物理层收发。 它们各司其职,配合实现从逻辑到电气的CAN通信。

CAN协议中的差分信号:

CAN 协议中对它使用的 CAN_HighCAN_Low 表示的差分信号做了规定

在高速CAN协议中

  • 表示逻辑1时:CAN_HighCAN_Low 线上电压均为2.5V,即它们电压差为0V

  • 表示逻辑0时:CAN_High 电平为3.5V,CAN_Low 电平为1.5V,电压差为2V

在低速CAN协议中

  • 表示逻辑1时:CAN_High 电平为1.75V,CAN_Low 电平为3.25V,即电压差为-1.5V

  • 表示逻辑0时:CAN_High 电平为4.0V,CAN_Low 电平为1.0V,即电压差为3V

3. CAN协议层

CAN 协议层规定了 CAN 通讯的具体逻辑

CAN总线传输特点:

  • CAN总线上的节点既可以发送数据又可以接收数据,没有主从之分。但是在同一个时刻只能一个节点发送数据,其他节点只能接收数据

  • CAN总线节点没有地址概念,都是以帧为单位传输的,帧包含所要传输的数据和控制信息

  • CAN总线具有“线与”的特性,也就是当有两个节点同时向总线发送信号时,一个发送显性电平,一个发送隐形,则总线呈现显性电平。这个特性被用于总线仲裁

  • 每个帧都有一个标识符。ID不是地址,他表示传输数据的类型,也可以用于总线仲裁时确定优先级

  • 每个CAN节点都接收数据,但是可以对接收的帧根据ID进行过滤

  • CAN总线通信是半双工的,即总线不能同时发送和接收

  • CAN总线没有用于同步的时钟信号,因此要规定CAN总线通信的波特率,所有节点使用相同的波特率进行通信

CAN的波特率及位时序:

  • 波特率:CAN属于异步通讯,没有时钟信号线,因此节点之间需要约定好 波特率 进行通信。

  • 位时序:指的是一个节点采集CAN总线上一个位数据的时序,通过位时序的控制,CAN总线可以进行位同步,以吸收节点时钟产生的波特率误差,保证接受数据的准确性

标称位时间:指传输一位数据的时间,用于确定CAN总线的波特率,这个时间被切分为三段

  • 同步段(SYNC_SEG):同步段长度固定为一个tq,如果节点在同步段检测到总线上有一个跳变沿,就表示节点与总线是同步的

  • 位段1(Bit Segment1):定义了采样点的位置

  • 位段2(Bit Segment2):定义了发送点的位置

CAN总线的波特率就可以由标称位时间决定:


NBT = (1+m+n)*tq

Baudrate = 1/NBT

这一个标称位的时间就是指传输一位数据所需要的时间 ,即上面所有段加上的时间

帧的种类:

CAN网络通信是通过5种类型的帧进行的。具体说明如下:

帧类型帧用途
数据帧(Data frame)节点发送的包含ID和数据的帧
遥控帧(Remote frame)节点向网络上其他节点发出的某个ID的数据请求,发送节点在接收到遥控帧之后可以发送对应ID的数据帧
错误帧(Error frame)节点检测出错误时,向其他节点发送的通知错误的帧
过载帧(Overload frame)接收单元未做好接收数据的准备时发送的帧,发送节点收到过载帧后可以暂缓发送数据帧
帧间空间(Inter-frame space)用于将数据帧、遥控帧和前后的帧分隔开的帧

其中,只有数据帧和遥控帧有ID,并且具有标准格式和扩展格式两种格式。标准格式的ID是11位的扩展格式的ID是29位的

标准数据帧和标准遥控帧:

数据帧和遥控帧都有11位的ID,但是数据帧带有数据,而遥控帧没有数据,只用于请求

数据帧可以分为如下7段

  • 帧起始(Start of Frame SOF):帧起始只有一个位,是一个显性电平(逻辑0),表示一个帧的开始

  • 仲裁段(Arbitration Field):仲裁段包括11位的ID和RTR位,一共12位。多个节点竞争总线的时候,根据仲裁段的数据来决定那个节点优先占用总线,哪个ID先出现显性电平,对应的节点就占用总线,所以,ID数值越小优先级越高,如果数据帧ID相同,再通过RTR位裁决

    • RTR(Remote Transmit Request)位:远程传输请求,RTR位用于区分数据帧和遥控帧,因为遥控帧的RTR位是隐形电平,因此具有相同ID的数据帧和遥控帧竞争总线时,数据帧的优先级更高

  • 控制段:控制段包括IDE位、RB0位和4位的DLC,共6位

    • IDE位:是标识符扩展位,用于表示帧时标准格式还是扩展格式,标准帧IDE为显性电平

    • RB0位:是保留位,默认显性

    • DLC位:是4个位的数据长度编码,编码数值为0到8,表示后面数据段的字节数

  • 数据段:数据段这里是数据帧需要传输的数据,可以是0到8字节,数据的字节个数由DLC编码确定

  • CRC段:CRC段共16位,其中前15位是CRC校验码,最后一位总是隐性电平,是CRC段的界定符

  • ACK段:ACK段包括一个ACK位和一个ACK界定符,发送节点发送的ACK位是隐性电平,接收节点接收的ACK位为显性电平

  • 帧结束:连续7个隐性位表示EOF,表示结束

扩展数据帧和扩展遥控帧:

扩展帧格式的ID总共是29位,其与标准帧的差距主要在仲裁段和控制段

  • 仲裁段:扩展帧的仲裁段总共32位,包括11位的标准ID,SRR位、IDE位、18位扩展ID、RTR位。

    SRR位只存在于扩展格式帧中,用于替代标准格式帧中的RTR位,其总是隐性电平,相当于占位符,真正的RTR位在仲裁段的最后一位

    扩展格式帧的IDE位总是隐性电平,用于表示该帧为扩展帧

  • 控制段:控制段由RB1位,RB0位和4位DLC组成,RB1位,RB0位是保留位

CAN之所以有标准数据帧之后,还添加了扩展数据帧,是因为要扩展更多CAN节点

优先级法则:

  • 总线空闲时,最先开始发送消息的节点获得发送权

  • 多个节点同时开始发送时,从仲裁短第一位开始进行仲裁

  • 相同ID和格式的数据帧和遥控帧,数据帧优先级更高,因为数据帧RTR位是显性电平

  • 对于标准ID相同的标准数据帧与扩展数据帧,标准帧优先级更高,因为IDE位标准数据帧为显性电平

4. CAN通信过程

CAN总线通信的基本过程可以概括为以下几个步骤:

  • 消息发送

    • CAN节点的应用层根据需要,向CAN控制器发送请求,要求发送一帧消息。

    • 消息包含标识符(ID)、数据长度代码、数据本身等。

  • 比特流发送

    • CAN控制器收到请求后,将消息打包成数据帧的位流。

    • 添加起始位、仲裁场、控制场、数据字段、CRC序列、ACK场等。

  • 仲裁和发送

    • CAN节点检测总线 idle 后开始发送位流,同时进行仲裁。

    • 仲裁胜出的节点继续发送,失败的节点停止发送。

  • 接收和过滤

    • 其他CAN节点接收位流,硬件过滤后决定是否接收。

    • 接收到的帧传给CAN控制器。

  • 校验和ACK

    • 接收节点在CRC正确的前提下,返回ACK位。

    • 发送节点检测到ACK表示发送成功。

  • 消息接收

    • CAN控制器解析帧,发送给应用层。

    • 应用层获得并处理这个接收到的消息。

以上过程完成一次CAN总线消息的发送和接收。CAN通信的可靠性在于其差错检测机制和仲裁机制。

5. CAN工作流程

CAN发送流程:

  1. 写入发送邮箱:先由MCU的应用程序将待发送的数据组装成CAN报文格式,然后写入CAN控制器的发送邮箱内部缓冲区

  2. 仲裁位和标识符相位:当检测到总线空闲时,发送节点进行总线仲裁,通过标识符和仲裁位决定CAN节点的传输优先级

  3. 发送报文和ACK位:仲裁成功后,赢得仲裁的节点开始通过序列化数据构造成CAN报文帧格式后按位顺序发送到总线上,并在最后一位发送"recessive"作为ACK位

  4. 应答监听:其他节点在接收完最后一位后,会将自己的ACK位发送回去与刚才的ACK位做对比,如果相同则表示接收成功

  5. 错误处理:如果acks不一致或者检测到其他错误,会进入CAN通信的错误处理流程,通过错误帧、错误标志等处理和通知

  6. 发送完成:发送端完成发送后,通过释放总线来结束此次发送,传输进入空闲状态后等待下一个发送节点

CAN接收流程:

  1. 监听总线:CAN节点配置为接收模式后,会持续监听CAN总线的电平状态

  2. 接收位序:当检测到启动位后,节点会进入接收状态,按位接收构成CAN报文的ID、控制位、数据位等

  3. CRC校验:节点会实时按照CRC算法对接收的报文进行校验,验证数据完整性

  4. ACK位确认:最后接收到ACK位后,接收节点会在ACK槽发送自己的应答信号,如果与接收到的ACK值不匹配则进入错误处理

  5. 接收邮箱过滤和存储:根据接收过滤器的设置,判断是否需要接收并存储该报文,如果需要则写入接收邮箱的缓冲区

  6. 数据解析:最终应用程序会从接收邮箱读取报文,解析CAN报文,提取数据等达到报文处理的目的

  7. 释放总线:一帧报文接收完成后释放总线,使能进入下一帧的接收

6. CAN控制器

(以STM32F407讲解)

CAN控制器模块:

  1. CAN控制内核:CAN 控制内核包含了各种控制寄存器及状态寄存器 ,以及筛选器配置寄存器。配置对应的寄存器,我们可以控制CAN设备工作参数

  2. CAN发送邮箱:发送邮箱是用于CAN总线发送的,如上图,总共CAN1有三个发送邮箱,这三个邮箱存在优先级关系,优先级越高表示其里面的数据会被优先发送

    发送邮箱有三个,但是每个邮箱只能装一个报文

  3. CAN接收邮箱:接收邮箱是用于CAN总线接收数据用的,在接收数据端会有一个过滤器处于接收邮箱前面,过滤器用于筛选标识符,只有标识符符合的报文才能放入接收邮箱

    接收邮箱有两个FIFO,每个FIFO有三层,每层能够存放一个报文,即每个接收邮箱可以接收三个报文,但是知恩阁读到最先接收的报文,这个读完之后,才能读取下一个报文

  4. 接收筛选器:F407又28个筛选器组,每个组包含2个32位寄存器,用来存储要筛选的ID或者掩码。

7. CAN标识符筛选原理

筛选器是由两个32位的寄存器组成,这两个寄存器可以被配置为 两个32位长度筛选器 或者 4个16位筛选器,筛选器还能选择 掩码模式 还是 列表模式。因此总共筛选器可以配置为4种模式

掩码模式:只有符合与寄存器ID中 对应的位 相符的才接收

列表模式:只有符合寄存器对应ID(所有位)的报文才能接收

  • 1个32位筛选器——标识符掩码模式:在这个模式下,寄存器1存储一个32位ID,这个32位的ID与11位标准ID[STID[10:0]]、18位扩展ID[EXID[17:0]]、IDE位、RTR位的位置对应关系如上图。寄存器2存储一个32位的掩码,如果掩码为1,则表示接收的报文ID必须与寄存器1中ID的对应位一致

  • 2个32位筛选器——标识符列表模式:在这种模式下,两个寄存器各存储一个ID,只有跟这两个ID一致的帧才能够通过筛选

  • 2个16位筛选器——标识符掩码模式:这个模式下,寄存器1的高16位组成ID,低16位组成掩码,寄存器2同样,这种只能筛选标准ID部分的标识符

  • 4个16位筛选器——标识符列表模式:这个模式下,寄存器1与2一共表示4个ID

用户可以为一个FIFO设置多个筛选器组,但是一个筛选器组只能配置给一个FIFO,如果为FIFO设置了筛选器,并且接受到的帧与所有筛选器都不相符,那么该帧就会被丢弃,只要通过一个筛选器,该帧就会被存入接收邮箱

8. CAN工作模式与测试模式

CAN模块三大工作模式

  • 初始化模式

    • 如何进入初始化模式:当CAN控制器默认上电就会进入初始化模式,当硬件处于初始化模式时,可以进行软件初始化。为了进入该模式,软件将CAN_MCR寄存器的INRQ位置1,并等待硬件通过将CAN_MSR寄存器INAK位置1来确认请求

    • 如何退出初始化模式:软件将INQR位清零,一旦硬件将INAK位清零,bxCAN即退出初始化模式

    • 初始化模式作用:用于配置CAN通信相关初始化参数

    • 初始化模式表现:在初始化模式下,所有从CAN总线传入和传出的消息都将停止,并且CAN总线输出CANTX的状态为隐性(高)

  • 正常模式:一旦初始化完成,软件必须向硬件请求进入正常模式,这样才能在 CAN 总线上进行同步, 并开始接收和发送

    • 如何进入正常模式:进入正常模式的请求可通过将 CAN_MCR 寄存器的 INRQ 位清零来发出,硬件通过将CAN_MSR寄存器的INAK位清零来确认切换到正常模式

    • 正常模式作用:用与CAN正常通信

  • 睡眠模式:为降低能耗功耗,bxCAN 具有低功耗模式,称为睡眠模式

    • 如何进入睡眠模式:软件可以通过将CAN_MCR寄存器的SLEEP位置1,即可进入该模式

    • 睡眠模式作用:用于降低功耗

CAN模块的三大测试模式

测试模式可以通过CAN_BTR寄存器中的SILM和LBKM位来选择测试模式,这些位必须在bxCAN处于初始化模式的时候才能够进行配置,选择测试模式后,必须复位 CAN_MCR 寄存器中的 INRQ 位才能进入正常模式

  • 正常模式

    • 此时,CAN总线能够正常工作,从总线接收或者发送数据

  • 静默模式

    • 静默模式怎么进入:可以通过将CAN_BTR寄存器的SILM位置1,将bxCAN置于静默模式

    • 静默模式的作用:无法启动发送,但是能够正常接收有效数据帧和有效遥控帧,用于分析CAN总线上的流量

  • 环回模式

    • 环回模式怎么进入:可以通过将CAN_BTR寄存器的LBKM位置1,将bxCAN置于环回模式

    • 环回模式作用:在环回模式下,bxCAN 将其自身发送的消息作为接收的消息来处理并存储,用于测试CAN模块的收发功能

  • 静默环回模式

    • 静默回环模式怎么进入:可以通过将 CAN_BTR 寄存器的 LBKM 和 SILM 位置 1,将环回模式和静默模式组合起来

    • 静默回环模式作用:该模式可用于“热自检”,也就是说,bxCAN 可以像在环回模式下一样进行检测,同时又不会影响与 CANTX 和 CANRX 引脚相连接的运行中的 CAN 系统。在此模式下,CANRX 引脚与 bxCAN 断开连接,CANTX 引脚则保持隐性

9. CANFD简介

为什么会出现CAN FD?

随着总线技术在汽车电子领域越来越广泛和深入的应用,汽车电子对总线宽度和数据传输速率的要求也越来也高,传统CAN(1MBit/s,8Bytes Payload)已难以满足日益增加的需求。

Bosch发布了新的CAN FD标准 (CAN with Flexible Data Rate) ,CAN FD继承了CAN的绝大多数特性,如同样的物理层,双线串行通信协议,基于非破坏性仲裁技术,分布式实时控制,可靠的错误处理和检测机制等,同时CAN FD弥补了CAN在总线带宽和数据长度方面的不足。

10. CAN与CANFD比较

CANFD具有如下4个主要的优点

  • 增加了数据的长度

    • CAN FD每个数据帧最多支持64个数据字节,而传统CAN最多支持8个数据字节。这减少了协议部分开销,并提高了协议效率。

      主要方式就是在帧结构中加大数据段的比例,增加每帧报文数据占比

  • 增加了传输的速率

    • CAN FD支持双比特率:与传统CAN一样,标称(仲裁)比特率限制为1 Mbit/s,而数据比特率则取决于网络拓扑/收发器。实际上,可以实现高达5 Mbit/s的数据比特率

      主要方式就是:1.缩短位时间提高位速率,另一种方式就是加长数据场长度减少报文数量

  • 更好的可靠性

    • CAN FD使用改进的循环冗余校验(CRC)和“受保护的填充位计数器”,从而降低了未被检测到的错误的风险。这在汽车和工业自动化等安全攸关的应用中至关重要。

      CANFD相对于普通CAN采用CRC15,升级到了CRC17~CRC21

  • 平滑过渡

    • 在一些特定的情况下CAN FD能用在仅使用传统CAN的ECU上,这样就可以逐步引入CAN FD节点,从而为OEM简化程序和降低成本

标准CAN与CANFD不同之处:

CAN-FD:可以理解成CAN协议的升级版,只升级了协议,物理层未改变。CAN与CAN-FD主要区别:传输速率不同、数据长度不同、帧格式不同、ID长度不同。

  • 传输速率不同:速率可变,仲裁比特率最高1Mbps(与CAN相同),数据比特率最高8Mbps

    从控制段中的BRS位到ACK段之间(含 CRC 分界符)为可变速率,其余部分为原 CAN 总线用的速率。两种速率各有一套位时间定义寄存器,它们除了采用不同的位时间单位 TQ 外,位时间各段的分配比例也可不同

  • 数据长度不同

    • CAN:一帧数据最长8字节

    • CAN-FD:一帧数据最长64字节

  • 帧格式不同:如上图

    • CAN-FD新增了FDF、BRS、ESI位

      • FDF位:表示CAN报文还是CAN-FD报文

      • BRS位:表示位速率转换,该位隐性时,速率可变(即BSR到CRC使用转换速率传输),该位为显性时,以正常的CAN-FD总线速率传输(恒定速率)。CAN FD采用了两种位速率:从控制场中的BRS位到ACK场之前(含CRC分界符)为可变速率,其余部分为原CAN总线用的速率,即仲裁段和数据控制段使用标准的通信波特率,而数据传输段时就会切换到更高的通信波特率,数据传输速率可大于

      • ESI位:表示发送节点状态。发送节点错误状态指示,主动错误时发送显性位(0),被动错误时发送隐性位(1)

  • ID长度不同

    • CAN:11位ID

    • CAN-FD:可扩展为12位

11. CANFD帧结构

CANFD帧结构跟CAN一样,可划分为7个段:

  1. 帧起始(SOF):CAN与CANFD使用相同的SOF标志位来标志报文的起始,是一个显性电平(逻辑0),表示一个帧的开始

  2. 仲裁段:与CAN不同,CAN FD取消了对远程帧的支持,用RRS位替换了RTR位,为常显性。

  3. 控制段:CAN FD与CAN有着相同的IDE、res和DLC位,同时增加了FDF、BRS、ESI三个bit位。

    • IDE位:是标识符扩展位,用于表示帧时标准格式还是扩展格式,标准帧IDE为显性电平

    • Res位:是保留位,默认显性

    • DLC位:是4个位的数据长度编码,编码数值为0到8,12,,表示后面数据段的字

    • FDF位:表示CAN报文还是CAN-FD报文

    • BRS位:表示位速率转换,该位隐性时,速率可变(即BSR到CRC使用转换速率传输),该位为显性时,以正常的CAN-FD总线速率传输(恒定速率)。CAN FD采用了两种位速率:从控制场中的BRS位到ACK场之前(含CRC分界符)为可变速率,其余部分为原CAN总线用的速率,即仲裁段和数据控制段使用标准的通信波特率,而数据传输段时就会切换到更高的通信波特率,数据传输速率可大于

    • ESI位:表示发送节点状态。发送节点错误状态指示,主动错误时发送显性位(0),被动错误时发送隐性位(1)

  4. 数据段:CAN FD兼容CAN的数据格式,同时最大还能支持:12、16、 20、 24、 32、 48和64byte。

  5. CRC段:传统CAN中的循环冗余校验(CRC)为15位,而在CAN FD中为17位(最多16个数据字节)或21位(20-64个数据字节)。 在传统CAN中,CRC中可以包含0到3个填充位,而在CAN FD中,总是有四个固定填充位以提高通信可靠性。

  6. ACK段:ACK紧跟着CRC结束标识位。不同的是,CAN FD支持2bits的ACK的识别

  7. EOF段:与CAN一样,CAN FD的帧结尾也为连续7位的隐性位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值