一文读懂CAN总线协议 (超详细配34张高清图)

CAN总线通信详解 (超详细配34张高清图)

image-20240113175828702

1. CAN总线历史

CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO国际标准化的串行通信协议。

在当前的汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来。由于这些系统之间通信所用的数据类型及对可靠性的要求不尽相同,由多条总线构成的情况很多,线束的数量也随之增加。为适应“减少线束的数量”、“通过多个 LAN,进行大量数据的高速通信”的需要。

CAN 最初出现在80年代末的汽车工业中,由德国 Bosch 公司最先提出。当时,由于消费者对于汽车功能的要求越来越多,而这些功能的实现大多是基于电子操作的,这就使得电子装置之间的通讯越来越复杂,同时意味着需要更多的连接信号线。提出 CAN 总线的最初动机就是为了解决现代汽车中庞大的电子控制装置之间的通讯,减少不断增加的信号线。于是,他们设计了一个单一的网络总线,所有的外围器件可以被挂接在该总线上。1993年,CAN 已成为国际标准 ISO11898(高速应用)和 ISO11519(低速应用)。
CAN 是一种多主方式的串行通讯总线,基本设计规范要求有高的位速率,高抗电磁干扰性,而且能够检测出产生的任何错误。当信号传输距离达到10Km 时,CAN 仍可提供高达50Kbit/s 的数据传输速率。由于 CAN 总线具有很高的实时性能,现在,CAN 的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。

图 1 是车载网络的构想示意图。CAN 等通信协议的开发,使多种 LAN 通过网关进行数据交换得以实现。

image-20240108213956269

2. CAN总线结构

​ CAN总线网络的结构有闭环和开环两种形式。如下图2所示,是闭环结构的CAN总线网络,总线两端各连接一个120欧的电阻,两根信号线形成回路。这种CAN总线网络由ISO 11898标准定义,是高速、短距离的CAN网络,通信速率为125kbit/s到1Mbit/s。在1Mbit/s通讯速率时,总线长度最长达40m。

image-20240108222241782

图2.闭环结构的CAN总线网络

​ 下图3是开环结构的CAN总线网络,两根信号线独立,各自串联一个2.2k欧的电阻。这种CAN总线网络由ISO11519-2标准定义,是低速、远距离的CAN网络,通信速率最高125kbit/s。在40kbit/s速率时,总线最长距离可达1000m。

image-20240108222140342

图3.开环结构的CAN总线网络

​ CAN总线由两根信号线,即图2和图3中的CANH和CANL,没有时钟同步信号。所以CAN是一种异步通信方式,与UART的异步通信方式类似,而SPI、I2C是以时钟信号同步的同步通信方式。

​ CAN总线的两根信号线通常采用的是双绞线,如下图4所示,传输的是差分信号,通过两根信号线的电压差CANH-CANL来表示总线电平。以差分信号传输信息具有抗干扰能力强,能有效抑制外部电磁干扰等优点,这也是CAN总线在工业上应用广泛的一个原因。使用差分信号表示总线电平的还有RS485网络,也是一种常用的工业现场总线。

image-20240109230643135

图4.双绞线类型

两根信号线的电压差CANH-CANL表示CAN总线的电平,与传输的逻辑信号1或0对应。对应于逻辑1的称为隐性(Recessive)电平,对应于逻辑0成为显性(Dominant)电平。如图5所示,上半部分为实际CANH和CANL的电平,下半部分对于的逻辑电平。

image-20240110083328495

图5.根据 ISO 11898 的额定总线电平

​ 对应于逻辑1和逻辑0,开环结构和闭环结构CAN网络的CANH和CANL的电压值不一样,隐性电平和显性电平的电压值不一样。两种网络结构下的CAN总线信号典型的电压如下表1所示,在ISO11898中,隐性电平在电压差0附近,显性电平主要在电压差2V附近。在ISO11519-2中,隐性电平在电压差小于0V,显性电平电压差大于2V:

表1. ISO11898 和 11519-2 物理层的主要不同点

image-20240111202858058

​ 如图6所示的CAN总线网络中,CAN总线上的一个终端设备称为一个节点(Node),在CAN网络中,没有主设备和从设备的区别。一个CAN节点的硬件部分一般由CAN控制器和CAN收发器两个部分组成。CAN控制器负责CAN总线的逻辑控制,实现CAN传输协议;CAN收发器主要负责MCU逻辑电平与CAN总线电平之间的转换。

image-20240110084329046

图6.闭环和开环结构

​ CAN控制器一般是MCU的片上外设,例如,STM32F407由两个CAN控制器。CAN收发器一般是单独的芯片,并且根据CAN总线的结构不同,需要使用不同的CAN收发芯片,例如,STM32F407开发板上使用的CAN收发芯片是TJA1040,只能构成闭环网络结构。

3. CAN总线特点

  1. 实时性: CAN总线具有优越的实时性能,适用于需要及时传输数据的应用,如汽车控制系统、工业自动化等。仲裁机制和帧优先级的设计保证了低延迟和可预测性。

  2. 多主机系统: CAN支持多主机系统,多个节点可以同时发送和接收数据。这种分布式控制结构使得系统更加灵活,适用于复杂的嵌入式网络。CAN总线上的节点既可以发送数据又可以接收数据,没有主从之分。但是在同一个时刻,只能由一个节点发送数据,其他节点只能接收数据。

  3. 差分信号传输: CAN使用差分信号传输,通过两个线路(CAN_H和CAN_L)之间的电压差来传递信息。这种差分传输方式提供了良好的抗干扰性能,使得CAN总线适用于工业环境等有电磁干扰的场合。

  4. 仲裁机制: CAN总线采用非破坏性仲裁机制,通过比较消息标识符的优先级来决定哪个节点有权继续发送数据。这种机制确保了总线上数据传输的有序性,避免了冲突。

  5. 广播通信: CAN总线采用广播通信方式,即发送的数据帧可以被总线上的所有节点接收。这种特性有助于信息的共享和同步,同时减少了系统的复杂性。

  6. 低成本: CAN总线的硬件成本相对较低,适用于大规模的系统集成。由于CAN控制器在硬件上实现了仲裁机制,无需额外的主机处理器,减小了成本和复杂性。

  7. 灵活性: CAN协议灵活适应不同的应用场景,支持不同的波特率和通信速率。这使得CAN总线可以被广泛用于各种嵌入式系统,从低速的传感器网络到高速的汽车控制系统。

  8. 错误检测和处理: CAN总线具有强大的错误检测和处理机制。通过CRC检查和其他错误检测手段,CAN能够识别和处理传输过程中可能发生的错误,提高了通信的可靠性。

  9. **多种帧类型:**CAN总线上的节点没有地址的概念。CAN总线上的数据是以帧为单位传输的,帧又分为数据帧、遥控帧等多种帧类型,帧包含需要传输的数据或控制信息。

  10. **线与逻辑:**CAN总线具有“线与”的特性,也就是当由两个节点同时向总线发送信号时,一个是发送显性电平(逻辑0),另一个发送隐性电平(逻辑1),则总线呈现为显性电平。这个特性被用于总线总裁,也就是哪个节点优先占用总线进行发送操作。

  11. 特定标识符:每一个帧有一个标识符(Identifier,一下简称ID)。ID不是地址,它表示传输数据的类型,也可以用于总线仲裁时确定优先级。例如,在汽车的CAN总线上,假设用于碰撞检测的节点输出数据帧ID为01,车内温度检测节点发送数据帧的ID为05等。

  12. **滤波特性:**每个CAN节点都接收数据,但是可以对接收的帧根据ID进行过滤。只有节点需要的数据才会被接收并进一步处理,不需要的数据会被自动舍弃。例如,假设安全气囊控制器只接受碰撞检测节点发出的ID为01的帧,这种ID的过滤时有硬件完成的,以便安全气囊控制器在发送碰撞时能及时响应。

  13. **半双工:**CAN总线通信时半双工的,即总线不能同时发送和接收。在多个节点竞争总线进行发送时,通过ID的优先级进行仲裁,竞争胜出的节点继续发送,竞争失败的节点立刻转入接收状态。

  14. **无时钟信号:**CAN总线没有用于同步的时钟信号,所以需要规定CAN总线通信的波特率,所以节点都是用同样的波特率进行通信。

4. CAN位时序和波特率

​ 一个CAN网络需要规定一个通信的波特率,各节点都以相同的波特率进行数据通信。位时序指的是一个节点采集CAN总线上的一个为数据的时序,位时序如图7所示。通过位时序的控制,CAN总线可以进行位同步,以吸收节点时钟差异产生的波特率误差,保证接收数据的准确性。

image-20240111213142575

图7.位时序

​ 图7中的标称位事件(Nominal Bit Time,NBT)指的是传输一个位数据的时间,用于确定CNA总线的波特率。这个事件被分成了3段。

  1. 同步段(SYNC_SEG):在这个时间段内,总线上应该发送一次位信号的跳变。如果节点在同步段检测到总线上的一个跳变沿,就表示节点与总线是同步的。同步段长度固定位1个tq。

    tq(time quantum)被称为时间片,tq由CAN控制器的时钟频率fcan决定。在STM32F407中,两个CAN控制器在APB1总线上,CAN控制器有预分频器,APB1总线的时钟信号PCLK1经分频后得到fcan。

  2. 位段1(Bit Segment 1,BS1):定义了采样点的位置。在BS1结束的时间点对总线采样,得到的电平就是这个位的电平。BS1的初始长度是1到16个tq,但它的长度可以在再同步(resynchronization)的时候被自动加长,以补偿各节点频率差异导致的正相位漂移。

  3. 位段2(Bit Segment 2,BS2):定义了发送点的位置。BS2的初始长度是1到8各tq,再同步时可以被自动缩短,以补偿负相位漂移。

    ​ CAN控制器可以自动对位时序进行再同步,再同步时自动调整BS1和BS2的长度,位段加长或缩短的上线称为再同步跳转宽度(resynchronization Jump Width,SJW),SJW的取值是1到4个tq。

    ​ CAN总线的波特率就由标称位时间长度NBT决定,而NBT时位时序3个段的时间长度和,即
    N B T = ( 1 + m + n ) × t q NBT=(1+m+n)\times t_q NBT=(1+m+n)×tq

    B a u d r a t e = 1 N B T Baudrate = \frac{1}{NBT} Baudrate=NBT1

5. CAN总线协议

5.1 OSI模型

CAN 协议如表 2 所示涵盖了 ISO 规定的 OSI 基本参照模型中的传输层、数据链路层及物理层。

表2.ISO/OSI 基本参照模型

image-20240111223746585

CAN 协议中关于 ISO/OSI 基本参照模型中的传输层、数据链路层及物理层,具体有哪些定义如图8 所示:

image-20240111223934770

数据链路层分为 MAC 子层和 LLC 子层,MAC 子层是 CAN 协议的核心部分。数据链路层的功能是将物理层收到的信号组织成有意义的消息,并提供传送错误控制等传输控制的流程。具体地说,就是消息的帧化、仲裁、应答、错误的检测或报告。数据链路层的功能通常在 CAN 控制器的硬件中执行。
在物理层定义了信号实际的发送方式、位时序、位的编码方式及同步的步骤。但具体地说,信号电平、通信速度、采样点、驱动器和总线的电气特性、连接器的形态等均未定义。这些必须由用户根据系统需求自行确定。

5.2 ISO 标准化的 CAN 协议

CAN 协议经 ISO 标准化后有 ISO11898 标准和 ISO11519-2 标准两种。ISO11898 和 ISO11519-2 标准对于数据链路层的定义相同,但物理层不同。

(1) 关于 ISO11898

ISO11898 是通信速度为 125kbps-1Mbps 的 CAN 高速通信标准。
目前,ISO11898 追加新规约后,成为 ISO11898-1 新标准。

(2) 关于 ISO11519

ISO11519 是通信速度为 125kbps 以下的 CAN 低速通信标准。
ISO11519-2 是 ISO11519-1 追加新规约后的版本。
图9 表示 CAN 协议和 ISO11898 及 ISO11519-2 标准的范围。

image-20240111225109120

(3) 物理层的不同点

如图 10 所示,ISO11898 和 ISO11519-2 在 CAN 协议中物理层的标准有所不同。CAN 协议的物理层如图 7 所
示,定义了三个子层,ISO11898 和 ISO11519-2 在物理层中的 PMA 层和 MDI 层有所不同。

image-20240111225139734

在物理层(PMA 层、MDI 层),ISO11898 和 ISO11519-2 的主要不同点如表 3 所示

image-20240111225359136

5.3 CAN 和标准规格

不仅是 ISO,SAE 等其它的组织、团体、企业也对 CAN 协议进行了标准化。
基于 CAN 的各种标准规格如表 4 所示,如图 11 所示,面向汽车的通信协议以通信速度为准进行了分类。

image-20240111225508926

image-20240111225930686

6. CAN各类型帧详解

6.1 帧的种类

CAN网络通信是通过5中类型的帧(Frame)进行的,

  • 数据帧(Data frame)
  • 遥控帧(Remote frame)
  • 错误帧(Error frame)
  • 过载帧(Overload frame)
  • 帧间空间(Inter-frame space)

另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有 11 个位的标识符(Identifier: 以下称 ID),扩展格式有 29 个位的 ID。

各种帧的用途如表5所示,各种帧的结构如图12-图

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

数据帧(Data frame):用于发送单元向接收单元传送数据的帧。

image-20240112073255140

遥控帧(Remote frame):用于接收单元向具有相同 ID 的发送单元请求数据的帧。

image-20240112073957623

错误帧(Error frame):用于当检测出错误时向其它单元通知错误的帧。

image-20240112074032849

过载帧(Overload frame):用于接收单元通知其尚未做好接收准备的帧。

image-20240112074115295

帧间空间(Inter-frame space):用于将数据帧及遥控帧与前面的帧分离开来的帧

image-20240112074157163

6.2 数据帧

数据帧由 7 个段构成。数据帧的构成如图 17 所示。

  1. 帧起始:表示数据帧开始的段。
  2. 仲裁段:表示该帧优先级的段。
  3. 控制段:表示数据的字节数及保留位的段。
  4. 数据段:数据的内容,可发送 0~8 个字节的数据。
  5. CRC 段:检查帧的传输错误的段。
  6. ACK 段:表示确认正常接收的段。
  7. 帧结束:表示数据帧结束的段。
    下面对帧的构成进行说明。

image-20240112075111244

6.2.1 帧起始(标准、扩展格式相同)

​ 表示帧开始的段。1 个位的显性位。

image-20240112075413995

image-20240112075429922

6.2.2 仲裁段

表示数据的优先级的段。
标准格式和扩展格式在此的构成有所不同。

image-20240112075529887

6.2.3 控制段

控制段由 6 个位构成,表示数据段的字节数。标准格式和扩展格式的构成有所不同。

image-20240112075641124

image-20240112075705200

6.2.4 数据段(标准、扩展格式相同)

数据段可包含 0~8 个字节的数据。从 MSB(最高位)开始输出。

image-20240112080011573

6.2.5 CRC 段(标准/扩展格式相同)

CRC 段是检查帧传输错误的帧。由 15 个位的 CRC 顺序*1 和 1 个位的 CRC 界定符(用于分隔的位)构成。

image-20240112080125110

6.2.6 ACK 段

ACK 段(Acknowledge Bit)用来确认是否正常接收。由 ACK 槽(ACK Slot)和 ACK 界定符 2 个位构成。

image-20240112080223238

6.2.7 帧结束(End of Frame,EOF)

帧结束是表示该该帧的结束的段。由 7 个位的隐性位构成。

image-20240112080726385

6.3 遥控帧

接收单元向发送单元请求发送数据所用的帧。遥控帧由 6 个段组成。遥控帧没有数据帧的数据段。
遥控帧的构成如图 25 所示。

  1. 帧起始:表示帧开始的段。
  2. 仲裁段:表示该帧优先级的段。
  3. 控制段:表示数据的字节数及保留位的段。
  4. CRC 段:检查帧的传输错误的段。
  5. ACK 段:表示确认正常接收的段。
  6. 帧结束:表示遥控帧结束的段。

image-20240112081128014

image-20240112081549396

image-20240112082629200

image-20240112082726251

6.4 错误帧

用于在接收和发送消息时检测出错误通知错误的帧。错误帧由错误标志和错误界定符构成。
错误帧的构成如图 26 所示。

1. 错误标志

错误标志包括主动错误标志和被动错误标志两种。

  • 主动错误标志:6 个位的显性位。
  • 被动错误标志:6 个位的隐性位。
2. 错误界定符

错误界定符由 8 个位的隐性位构成。

image-20240112081836934

6.5 过载帧

过载帧是用于接收单元通知其尚未完成接收准备的帧。过载帧由过载标志和过载界定符构成。
过载帧的构成如图 27 所示。

1. 过载标志

6 个位的显性位。过载标志的构成与主动错误标志的构成相同。

2. 过载界定符

8 个位的隐性位。过载界定符的构成与错误界定符的构成相同。

image-20240112082000397

6.6 帧间隔

帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。

过载帧和错误帧前不能插入帧间隔

帧间隔的构成如图 28 所示。

image-20240112082145060

1. 间隔

3 个位的隐性位。

2. 总线空闲

隐性电平,无长度限制(0 亦可)。本状态下,可视为总线空闲,要发送的单元可开始访问总线。

3. 延迟传送(发送暂时停止)

8 个位的隐性位。只在处于被动错误状态的单元刚发送一个消息后的帧间隔中包含的段。

7. CAN总线优先级及同步

7.1 优先级的决定

​ 在总线空闲态,最先开始发送消息的单元获得发送权。

​ 多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。

​ 仲裁的过程如图 29 所示: 前面的单元1和单元电平都一样,到后面单元1是隐性电平,单元2是显性电平,显性优先级更高,则单元2的优先级更高,获得发送权,而单元1则变为接收状态。

image-20240113155151745

7.1.1 数据帧和遥控帧的优先级

具有相同 ID 的数据帧和遥控帧在总线上竞争时,仲裁段的最后一位(RTR)为显性位的数据帧具有优先权,可继续发送。
数据帧和遥控帧的仲裁过程如图 30 所示:

image-20240113160037817

7.1.2 标准格式和扩展格式的优先级

标准格式 ID 与具有相同 ID 的遥控帧或者扩展格式的数据帧在总线上竞争时,标准格式的 RTR 位为显性位的具有优先权,可继续发送。
标准格式和扩展格式的仲裁过程如图 31 所示。

image-20240113160135876

7.1.3 优先级法则

​ 数据帧和遥控帧的仲裁段用于多个节点竞争总线时进行仲裁,优先级高的帧获得再总线上发送数据的权利。优先级的确认总结为以下几条法则:

  • 在总线空闲时,最先开始发送消息的节点获得发送权;
  • 多个节点同时开始发送时,从仲裁段的第一位开始进行仲裁,第一次出现各节点的位电平互异时,输出显性电平的节点获得发送权;
  • 相同ID和格式的数据帧和遥控帧,数据帧具有更高优先级,因为数据中的RTR位时显性电平,而遥控帧的RTR位时显性电平;
  • 对于11位标准ID相同的标志数据帧和扩展数据帧,标准数据帧具有更高的优先级,因为标志数据帧的IDE位时显性电平,而扩展数据帧的IDE位时隐性电平。

7.2 错误的种类

错误共有 5 种。多种错误可能同时发生。

  • 位错误
  • 填充错误
  • CRC 错误
  • 格式错误
  • ACK 错误
    错误的种类、错误的内容、错误检测帧和检测单元如表 6 所示

image-20240113161109639

(1) 位错误

  • 位错误由向总线上输出数据帧、遥控帧、错误帧、过载帧的单元和输出 ACK 的单元、输出错误的单元来检测。

  • 在仲裁段输出隐性电平,但检测出显性电平时,将被视为仲裁失利,而不是位错误。

  • 在仲裁段作为填充位输出隐性电平时,但检测出显性电平时,将不视为位错误,而是填充错误。

  • 发送单元在 ACK 段输出隐性电平,但检测到显性电平时,将被判断为其它单元的 ACK 应答,而非位错误。

  • 输出被动错误标志(6 个位隐性位)但检测出显性电平时,将遵从错误标志的结束条件,等待检测出连续相同 6 个位的值(显性或隐性),并不视为位错误。

(2) 格式错误

  • 即使接收单元检测出 EOF(7 个位的隐性位)的最后一位(第 8 个位)为显性电平,也不视为格式错误。
  • 即使接收单元检测出数据长度码(DLC)中 9∼15 的值时,也不视为格式错误。

7.3 错误帧的输出

检测出满足错误条件的单元输出错误标志通报错误。
处于主动错误状态的单元输出的错误标志为主动错误标志;处于被动错误状态的单元输出的错误标志为被动错误标志。
发送单元发送完错误帧后,将再次发送数据帧或遥控帧。
错误标志输出时序如表 7 所示。

image-20240113161358511

7.4 位时序

由发送单元在非同步的情况下发送的每秒钟的位数称为位速率。一个位可分为 4 段。

  • 同步段(SS)
  • 传播时间段(PTS)
  • 相位缓冲段 1(PBS1)
  • 相位缓冲段 2(PBS2)

这些段又由可称为 Time Quantum(以下称为 Tq)的最小时间单位构成。

1 位分为 4 个段,每个段又由若干个 Tq 构成,这称为位时序。

1 位由多少个 Tq 构成、每个段又由多少个 Tq 构成等,可以任意设定位时序。通过设定位时序,多个单元可

同时采样,也可任意设定采样点。

各段的作用和 Tq 数如表7 所示。1 个位的构成如图 32 所示。

image-20240113172007625

image-20240113174056772

7.5 取得同步的方法

CAN 协议的通信方法为 NRZ(Non-Return to Zero)方式。各个位的开头或者结尾都没有附加同步信号。发送单元以与位时序同步的方式开始发送数据。另外,接收单元根据总线上电平的变化进行同步并进行接收工作。

但是,发送单元和接收单元存在的时钟频率误差及传输路径上的(电缆、驱动器等)相位延迟会引起同步偏差。因此接收单元通过硬件同步或者再同步的方法调整时序进行接收。

8.13

7.6 硬件同步

接收单元在总线空闲状态检测出帧起始时进行的同步调整。在检测出边沿的地方不考虑 SJW 的值而认为是 SS 段。
硬件同步的过程如图 33 所示。

image-20240113174219552

7.7 再同步

在接收过程中检测出总线上的电平变化时进行的同步调整。
每当检测出边沿时,根据 SJW 值通过加长 PBS1 段,或缩短 PBS2 段,以调整同步。但如果发生了超出 SJW
值的误差时,最大调整量不能超过 SJW 值。
再同步如图 34 所示。

image-20240113174248758

7.8 调整同步的规则

硬件同步和再同步遵从如下规则。

  1. 1 个位中只进行一次同步调整。
  2. 只有当上次采样点的总线值和边沿后的总线值不同时,该边沿才能用于调整同步。
  3. 在总线空闲且存在隐性电平到显性电平的边沿时,则一定要进行硬件同步。
  4. 在总线非空闲时检测到的隐性电平到显性电平的边沿如果满足条件(1)和(2),将进行再同步。但还要
    满足下面条件。
  5. 发送单元观测到自身输出的显性电平有延迟时不进行再同步。
  6. 发送单元在帧起始到仲裁段有多个单元同时发送的情况下,对延迟边沿不进行再同步。

参考文献:

[1] CAN入门书(瑞萨电子)

[2] STM32 Cube 高效开发教程. 王维波等著

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾格北峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值