【物联网】深入理解CAN通信:原理、应用和实现(超详细,万字警告)

这篇具有很好参考价值的文章主要介绍了【物联网】深入理解CAN通信:原理、应用和实现(超详细,万字警告)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

CAN(Controller Area Network)是一种广泛应用于汽车和工业领域的多节点通信协议。它具有高可靠性、高实时性和抗干扰能力强等特点,能够满足复杂系统中节点之间的数据传输需求。本文将全面介绍CAN通信的原理、应用和实现,并提供实际开发中常用的方法和技巧,帮助读者更好地理解和应用CAN通信技术。

1. 什么是CAN通信?

CAN通信是一种多节点通信协议,最早由Bosch公司开发并在1986年首次推出。它被广泛应用于汽车电子控制系统、工业自动化领域以及其他需求多节点通信的应用场景中。

CAN通信的特点之一是支持多节点之间的高速数据传输,适用于需要高实时性和高可靠性的系统。CAN总线由两根线组成,分别是CAN_H(CAN High)和CAN_L(CAN Low)。CAN总线使用不同的电压电平来表示0和1,并通过差分信号传输来抗干扰。

2. CAN通信原理

CAN通信采用CSMA/CD(Carrier Sense Multiple Access with Collision Detection)的工作原理。简单来说,这意味着每个节点都可以在总线上发送消息,但在发送之前需要先监听总线上的通信情况。

当一个节点要发送消息时,首先会监听总线,如果没有其他节点正在发送消息,它就可以开始发送。如果同时有多个节点尝试发送消息,就会发生冲突。在CAN总线上使用的是非毁坏性冲突检测机制,冲突的节点会立即停止发送,并在发送完自己的消息后再次来检测冲突。

CAN通信中还使用了位定时传输方式,即总线上的每个位都有固定的时间段。发送节点将每个位的电平保持一段时间,接收节点则在相应的时间段内检测位的电平。这种位定时传输方式确保了数据的同步和准确性。

此外,CAN通信还通过帧的优先级来管理消息的传输。较低优先级的帧会在总线上等待较高优先级的帧发送完毕后再发送,确保重要消息的及时传输。

3. CAN通信的应用领域

CAN通信被广泛应用于各种领域,特别是在汽车和工业控制系统中。

在汽车领域,CAN通信用于连接汽车的各个控制单元,如发动机控制单元(ECU)、刹车系统、仪表盘等。CAN总线提供了高速、实时的数据传输,使得这些控制单元能够相互通信和协调工作,实现车辆的高效控制和监测。

在工业控制系统中,CAN通信被用于连接各种设备和传感器,例如机器人、PLC(可编程逻辑控制器)、传感器网络等。通过CAN总线,这些设备可以实现实时数据交换和远程控制,从而提高生产效率和系统的可靠性。

除了汽车和工业控制,CAN通信还应用于其他领域,包括航空航天、医疗设备、能源管理等。CAN通信的高可靠性和抗干扰能力使其成为处理实时数据和多节点通信的理想选择。

4. CAN帧格式与标识符

CAN通信使用帧格式来传输数据。CAN帧分为标准帧扩展帧两种格式。

标准帧由11位标识符、数据域、控制域和CRC(循环冗余校验)组成。标识符用于标识消息的优先级和内容,数据域用于传输实际的数据,控制域包含帧的控制信息,而CRC用于发送节点计算校验和,接收节点用于验证数据的完整性。

扩展帧使用29位标识符,其他组成部分与标准帧相同。扩展帧的使用使得CAN网络能够处理更多的节点和更大的数据量。

标识符的选择对于CAN通信至关重要。帧使用的标识符决定了其在总线上的优先级,较低的标识符意味着较高的优先级。在设计和配置CAN网络时,需要合理设置标识符以确保系统的正确运行。

5. CAN通信管理和控制

CAN通信的管理和控制涉及多个方面,包括位定时、通信模式、错误处理和故障状态等。

5.1 CAN总线位定时(Bit Timing)

在CAN通信中,位定时是指将每个CAN总线的位划分为不同的时间段,并将位的电平保持一段时间。位定时可以通过设置同步段(Sync Segment)、传播段(Propagation Segment)和相位段(Phase Segment)来实现。

同步段用于确保总线上的节点能够在每个位开始时达到同步。传播段定义了信号在总线上传播的时间,而相位段用于确定位值的边界。

位定时的设置很关键,它直接影响到通信的可靠性和性能。在系统设计中,需要根据总线的特性和系统要求合理地设置位定时参数,以确保数据的正确传输。

5.2 CAN通信模式

CAN通信有几种不同的模式,可以通过配置CAN控制器的寄存器来选择适合应用需求的模式。

常见的CAN通信模式包括:

  • 正常模式(Normal Mode):用于实际通信,节点能够发送和接收数据。
    -** 监听模式(Listen-Only Mode)**:节点只能监听总线上的通信,但不能发送消息。
  • 回环模式(Loopback Mode):发送的帧会回环到本地接收,用于自测和调试。
  • 静默模式(Silent Mode):节点只能监听总线上的通信,不能发送消息,并向其他节点传递错误状态。

5.3 CAN错误处理与故障状态

在CAN通信中,可能会出现一些错误情况,例如位错误、格式错误、CRC错误、接收溢出等。CAN控制器会检测这些错误,并根据具体的错误类型生成相应的错误码。

在错误处理中,可以通过读取错误状态寄存器来获取错误码和错误类型。常见的错误处理方法包括:

  • 重传机制:如果发送的帧在总线上出现错误,发送节点可以重传帧以确保数据的正确传输。
  • 错误状态清除:将错误计数器重置为0,清除错误状态以使节点恢复正常通信。
  • 错误管理器(Error Management):通过协议定义的错误管理器对错误进行处理和控制,例如决定是否启用自动重传。
  • 错误标志位(Error Flag):通过检查错误标志位确定是否有错误发生,并根据需要采取相应的处理措施。

6. 使用HAL库实现CAN通信

对于使用HAL(Hardware Abstraction Layer)库进行STM32开发的用户,HAL库提供了高级的抽象接口和简洁的函数调用,方便编写和管理CAN通信。

6.1 STM32 CAN通信配置:

a. 使能CAN外设:在初始化阶段,需要使能所选择的CAN外设,并配置相应的时钟。

b. 配置CAN控制器:通过设置CAN控制器的特殊寄存器,配置CAN通信的参数,包括波特率、工作模式、过滤器等。

c. 配置GPIO引脚:将相关的GPIO引脚配置为CAN模式,以实现CAN数据的收发。

d. 初始化CAN通信:通过初始化CAN控制器的寄存器,准备CAN通信的环境,包括清除任何悬空状态和错误标志。

e. 开始CAN通信:使能CAN控制器的接收和发送功能,使其处于工作状态。

6.2 步骤的代码实现

  1. 包含所需的头文件:

    #include "stm32f4xx_hal.h"
    #include "stm32f4xx_hal_can.h"
    
  2. 定义CAN_HandleTypeDef结构体和CAN消息结构体:

    CAN_HandleTypeDef hcan;
    CAN_TxHeaderTypeDef TxHeader;
    CAN_RxHeaderTypeDef RxHeader;
    uint8_t TxData[8];
    uint8_t RxData[8];
    
  3. 配置CAN模式和参数:

    hcan.Instance = CAN1;
    hcan.Init.Mode = CAN_MODE_NORMAL;
    hcan.Init.AutoBusOff = ENABLE;
    hcan.Init.AutoRetransmission = ENABLE;
    hcan.Init.AutoWakeUp = DISABLE;
    hcan.Init.ReceiveFifoLocked = DISABLE;
    hcan.Init.TimeTriggeredMode = DISABLE;
    hcan.Init.TransmitFifoPriority = DISABLE;
    hcan.Init.Prescaler = 10;
    hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
    hcan.Init.TimeSeg1 = CAN_BS1_8TQ;
    hcan.Init.TimeSeg2 = CAN_BS2_7TQ;
    
    if (HAL_CAN_Init(&hcan) != HAL_OK) {
        // 错误处理
    }
    
  4. 配置CAN过滤器:

    CAN_FilterTypeDef sFilterConfig;
    sFilterConfig.FilterBank = 0;
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig.FilterIdHigh = 0x0000;
    sFilterConfig.FilterIdLow = 0x0000;
    sFilterConfig.FilterMaskIdHigh = 0x0000;
    sFilterConfig.FilterMaskIdLow = 0x0000;
    sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
    sFilterConfig.FilterActivation = ENABLE;
    sFilterConfig.SlaveStartFilterBank = 0;
    
    if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) {
        // 错误处理
    }
    
  5. 启动CAN:

    if (HAL_CAN_Start(&hcan) != HAL_OK) {
        // 错误处理
    }
    
  6. 发送和接收数据:

    if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) != HAL_OK) {
        // 错误处理
    }
    
    if (HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK) {
        // 错误处理
    }
    

6.3 实现的整体代码

// 包含所需的头文件
#include "stm32f4xx_hal.h"

// CAN消息结构体
CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
uint8_t TxData[8];
uint8_t RxData[8];

void CAN_Configuration(void)
{
  // 初始化CAN控制器
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 10;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_8TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_7TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = ENABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = ENABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  HAL_CAN_Init(&hcan);

  // 配置CAN过滤器
  CAN_FilterTypeDef sFilterConfig;
  sFilterConfig.FilterBank = 0;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = 0x0000;
  sFilterConfig.FilterIdLow = 0x0000;
  sFilterConfig.FilterMaskIdHigh = 0x0000;
  sFilterConfig.FilterMaskIdLow = 0x0000;
  sFilterConfig.Filter
继续
MaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);

// 启动CAN通信
HAL_CAN_Start(&hcan);

// 配置CAN消息头
TxHeader.StdId = 0x123;
TxHeader.ExtId = 0x00;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 8;
TxHeader.TransmitGlobalTime = DISABLE;
}

void CAN_SendData(uint8_t* data, uint32_t length)
{
// 填充发送消息的数据
for (uint8_t i = 0; i < length; i++) {
TxData[i] = data[i];
}

// 发送消息
if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) == HAL_OK) {
HAL_CAN_Transmit(&hcan, 100);
}
}

void CAN_ReceiveData(void)
{
// 接收消息
if (HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) > 0) {
if (HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) {
// 处理接收到的数据
// …
}
}
}

int main(void)
{
// 初始化HAL库和其他外设

// 配置CAN通信
CAN_Configuration();

while (1) {
// 发送数据
uint8_t sendData[] = {0x01, 0x02, 0x03};
CAN_SendData(sendData, sizeof(sendData));

// 接收数据
CAN_ReceiveData();
}
}

以上示例代码演示了一个简单的CAN发送和接收流程。首先,在CAN_Configuration函数中,配置CAN控制器和过滤器。然后,在主函数中,使用CAN_SendData函数发送数据,使用CAN_ReceiveData函数接收数据。

此外,为了调试和监测CAN通信,HAL库提供了一些有用的函数和工具。例如,可以使用HAL_CAN_GetState()函数获取CAN控制器的当前状态,包括初始化、准备就绪、发送中、传输完成等。还可以使用HAL_CAN_GetErrorCounter()函数获取错误计数器的值,以及使用HAL_CAN_GetRxMessage()函数获取接收到的CAN帧的相关信息。

7. 使用标准库实现CAN通信

除了HAL库,还可以使用标准库进行CAN通信的实现。标准库相对较底层,需要直接操作寄存器和位操作来配置和控制CAN控制器。

与HAL库类似,使用标准库进行CAN通信需要进行CAN总线的初始化、过滤器的配置、数据的发送和接收等操作。不同之处在于,需要直接操作寄存器来完成这些任务。

7.1 实现步骤

  • 配置GPIO端口和引脚,用于连接CAN总线。
  • 配置CAN控制器的工作模式、波特率、位定时参数等。
  • 配置CAN过滤器,设置过滤器的标识符、执行类型等。
  • 使用CAN发送函数将数据发送到总线上。
  • 使用CAN接收函数接收来自其他节点的数据。

7.2 步骤的代码实现

当使用标准库实现STM32的CAN通信时,需要按照以下步骤进行配置和操作:

  1. 配置CAN1时钟:

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    
  2. 初始化CAN1:

    CAN_InitTypeDef CAN_InitStructure;
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
    CAN_InitStructure.CAN_Prescaler = 10;
    CAN_Init(CAN1, &CAN_InitStructure);
    
  3. 配置CAN过滤器:

    CAN_FilterInitTypeDef CAN_FilterInitStructure;
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
    
  4. 使能CAN1接收中断:

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    
  5. 实现CAN1接收中断处理函数:

    void CAN1_RX0_IRQHandler(void) {
      if (CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET) {
        CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
        // 处理接收到的消息
      }
    }
    
  6. 编写CAN发送函数:

    void CAN_SendData(uint8_t* data, uint8_t length) {
      // 填充发送消息的数据
      for (uint8_t i = 0; i < length; i++) {
        TxMessage.Data[i] = data[i];
      }
    
      // 设置发送消息的参数
      TxMessage.StdId = 0x123;
      TxMessage.ExtId = 0x00;
      TxMessage.IDE = CAN_Id_Standard;
      TxMessage.RTR = CAN_RTR_DATA;
      TxMessage.DLC = length;
    
      // 发送消息
      uint8_t mailbox;
      CAN_Transmit(CAN1, &TxMessage);
    }
    
  7. 在主函数中调用相关函数:

    int main(void) {
      // 初始化CAN配置
      CAN_Configuration();
    
      while ((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) {
        // 等待CAN1退出初始化模式
      }
    
      while (1) {
        // 发送数据
        uint8_t sendData[] = {0x01, 0x02, 0x03};
        CAN_SendData(sendData, sizeof(sendData));
    
        // 延时一段时间
        for (volatile uint32_t i = 0; i < 1000000; i++) {}
      }
    }
    

7.3 实现的整体代码

#include "stm32f4xx.h"

// CAN消息结构体
CanTxMsgTypeDef TxMessage;
CanRxMsgTypeDef RxMessage;

void CAN_Configuration(void) {
  // 使能CAN1时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

  // CAN1初始化
  CAN_InitTypeDef CAN_InitStructure;
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
  CAN_InitStructure.CAN_Prescaler = 10;
  CAN_Init(CAN1, &CAN_InitStructure);

  // CAN过滤器配置
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
  CAN_FilterInitStructure.CAN_FilterNumber = 0;
  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);

  // CAN接收中断使能
  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

  // 使能CAN1
  CAN_Cmd(CAN1, ENABLE);

  // NVIC中断配置
  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void CAN_SendData(uint8_t* data, uint8_t length) {
  // 填充发送消息的数据
  for (uint8_t i = 0; i < length; i++) {
    TxMessage.Data[i] = data[i];
  }

  // 设置发送消息的参数
  TxMessage.StdId = 0x123;
  TxMessage.ExtId = 0x00;
  TxMessage.IDE = CAN_Id_Standard;
  TxMessage.RTR = CAN_RTR_DATA;
  TxMessage.DLC = length;

  // 发送消息
  uint8_t transmissionMailbox = 0;
  CAN_Transmit(CAN1, &TxMessage);
}

void CAN1_RX0_IRQHandler(void) {
  if (CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET) {
    // 接收到消息
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);

    // 处理接收到的消息
    // ...
  }
}

int main(void) {
  // 初始化CAN配置
  CAN_Configuration();

  while ((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) {
    // 等待CAN1退出初始化模式
  }

  while (1) {
    // 发送数据
    uint8_t sendData[] = {0x01, 0x02, 0x03};
    CAN_SendData(sendData, sizeof(sendData));

    // 延时一段时间
    for (volatile uint32_t i = 0; i < 1000000; i++) {}
  }
}

8. CAN通信实际案例分析

在汽车电控系统中,CAN通信被广泛应用于各个控制单元之间的数据传输。例如,在引擎控制单元(ECU)中,通过CAN总线与刹车系统的控制单元、仪表盘的控制单元进行通信。引擎控制单元可以向刹车系统发送刹车指令,同时获取仪表盘上的车速和引擎转速等信息。

在工业控制系统中,CAN通信常用于连接不同的设备和传感器,以实现实时数据交换和协调工作。例如,在机器人系统中,通过CAN总线连接各个关节控制器和传感器,实现机器人的协调运动和数据传输。文章来源地址https://www.toymoban.com/news/detail-646791.html

到了这里,关于【物联网】深入理解CAN通信:原理、应用和实现(超详细,万字警告)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入理解中文编码:原理、应用与实践

    编码是将信息转换为特定格式以便存储、传输或处理的过程。在计算机科学中,编码通常指的是将文本、图像、音频等数据转换为数字形式的过程。编码的作用在于统一数据格式、提高数据传输效率、确保数据安全性等方面发挥着重要作用。 中文编码相较于英文等西方语言编

    2024年04月12日
    浏览(47)
  • 深入理解Reactor模型的原理与应用

            Reactor意思是“反应堆”,是一种事件驱动机制。          和普通函数调用的不同之处在于:应用程序不是主动的调用某个 API 完成处理,而是恰恰相反,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到 Reactor 上,如果相应的时间发生,Reactor将

    2024年02月10日
    浏览(43)
  • “深入理解Spring框架的核心原理与应用“

    标题:深入理解Spring框架的核心原理与应用 摘要:本文旨在深入探讨Spring框架的核心原理与应用。我们将介绍Spring框架的主要特点、IOC容器的工作原理、AOP的实现方式以及Spring MVC的应用等内容,并通过示例代码来演示Spring框架的使用。 Spring框架是一款非常流行的Java开发框架

    2024年02月16日
    浏览(41)
  • 深入理解MD5算法:原理、应用与安全

    在当今数字化时代,数据安全和完整性变得至关重要。消息摘要算法是一种用于验证数据完整性和安全性的重要工具。在众多消息摘要算法中,MD5(Message Digest Algorithm 5)因其快速、广泛应用和相对较高的安全性而备受关注。本书将深入探讨MD5算法的原理、应用和安全性,帮

    2024年04月11日
    浏览(53)
  • 什么是JWT?深入理解JWT从原理到应用

    🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《ELement》。🎯🎯 👉点击这里,就可以查看我的主页啦!👇👇 Java方文山的个人主页 🎁如果感觉还不错的话请给我点赞吧!🎁🎁 💖期待你的加入,一起学习

    2024年02月08日
    浏览(51)
  • 【递归】:原理、应用与案例解析 ,助你深入理解递归核心思想

    递归在计算机科学中,递归是一种解决计算问题的方法,其中解决方案取决于同一类问题的更小子集 例如 递归遍历环形链表 基本情况(Base Case) :基本情况是递归函数中最简单的情况,它们通常是递归终止的条件。在基本情况下,递归函数会返回一个明确的值,而不再进行

    2024年02月21日
    浏览(45)
  • 深入理解 SpringBoot 日志框架:从入门到高级应用——(一)日志框架原理

    日志框架的历史可以追溯到计算机编程的早期。在早期的编程语言中,如 C 和 Pascal,程序员通常使用 printf 或 fprintf 函数将程序的状态信息输出到控制台或文件中,以便调试和排查问题。 随着计算机应用程序的不断发展,人们对日志管理的需求越来越高。当我们在开发项目时

    2024年02月09日
    浏览(51)
  • 万字长文深入理解Docker镜像分层原理、容器数据卷、网络通信架构(Docker系列第2章,共3章)

    在执行docker pull时,会发现多个Pull complete 字样,就能体现分层,如果是一个文件,只会有一个Pull complete 。 概念:文件系统是计算机系统中用于组织和管理数据存储的一种方式。它定义了数据如何存储、命名、访问和修改的方式。 举例:如Windows自带的NTFS、FAT32、EXFAT,和L

    2024年04月14日
    浏览(34)
  • 深入理解 python 虚拟机:字节码教程(3)——深入剖析循环实现原理

    在本篇文章当中主要给大家介绍 cpython 当中跟循环相关的字节码,这部分字节码相比起其他字节码来说相对复杂一点,通过分析这部分字节码我们对程序的执行过程将会有更加深刻的理解。 我们使用各种例子来理解和循环相关的字节码: 上面的代码对应的字节码如下所示:

    2023年04月15日
    浏览(37)
  • CSapp-DataLab——深入理解函数实现原理

    文章一 文章二 文章三 相比于上面这些参考文章,我增加了更多的个人理解在其中,可以互为参考。 bitXor函数 函数要求: 函数名 bitXor 参数 int , int 功能实现 x^y 要求 只能使用 ~ 和 | 运算符,将结果返回。 实现分析: 异或的最初形态是 x ⊕ y = ( x ∧ ! y ) ∨ ( ! x ∧ y ) xopl

    2024年02月07日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包