CAN通讯配置及接收报文--学习笔记1~2

这篇具有很好参考价值的文章主要介绍了CAN通讯配置及接收报文--学习笔记1~2。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

硬件设备

STM32F103C8T6工控板、USB转TLL接口、TLL转CAN串口小板,继电器,降压模块,警示灯

can收发报文,CAN通讯,报文控制器,stm32,学习,单片机,Powered by 金山文档
can收发报文,CAN通讯,报文控制器,stm32,学习,单片机,Powered by 金山文档

软件工具

CANPro协议分析平台、CubeMX、MDK-ARM

实现过程及功能

基础功能:PC端通过CANPro设置报文,发出串口信号经过USB和串口小板转成CAN信号,在单片机上接收特定ID的报文,通过判断需要接收的首byte数据执行相应操作(LED亮)

进阶功能:通过修改CAN_Filter完成对两种报文的筛选,并设计一个特定报文,选择执行两种报文命令,通过连接继电器和警示灯,更直观的表现出来选择效果。

CubeMX的配置

can收发报文,CAN通讯,报文控制器,stm32,学习,单片机,Powered by 金山文档

定义引脚 根据板子的原理图来定义,这里CAN是PB8、PB9,LED是PB14、PB15

can收发报文,CAN通讯,报文控制器,stm32,学习,单片机,Powered by 金山文档
can收发报文,CAN通讯,报文控制器,stm32,学习,单片机,Powered by 金山文档

CAN的配置,最重要的是使得接收的波特率和发送的信号一致,至于怎么配置,可以查查别人的文章,我记得之前有看到过,我这里是因为后续使用在汽车上测试的,所以设置为500K

can收发报文,CAN通讯,报文控制器,stm32,学习,单片机,Powered by 金山文档

时钟的初始化,输入频率看板子上的晶振,在范围内选择。单独使用CAN的话,数值不太重要,高速时钟为72MHz,APB1外围时钟为最大频率即可。

can收发报文,CAN通讯,报文控制器,stm32,学习,单片机,Powered by 金山文档

配置完回去检查一下,随后工程管理设置一下,生成代码即可

代码

main.c


/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "gpio.h"

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void SystemClock_Config(void);
CAN_HandleTypeDef hcan;
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{ 
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
    MX_GPIO_Init();//引脚初始化函数
    
    MX_CAN_Init();//CAN初始化函数
  /* USER CODE BEGIN 2 *//
    MY_CAN_Filter();//自定义滤波器设置函数
    HAL_CAN_Start(&hcan);//调用HAL启动CAN
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  }
  /* USER CODE END 3 */
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {       
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif /* USE_FULL_ASSERT */

can.c


/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"

void MX_CAN_Init(void)
{
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 12;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_3TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(canHandle->Instance==CAN1)
  {
    /* CAN1 clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**CAN GPIO Configuration
    PB8     ------> CAN_RX
    PB9     ------> CAN_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    __HAL_AFIO_REMAP_CAN1_2();

    /* CAN1 interrupt Init *///这里也可以设置一下,在cubemx里NVIC
    HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);//没设置就直接添加
    HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
  }
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
  if(canHandle->Instance==CAN1)
  {
    /* Peripheral clock disable */
    __HAL_RCC_CAN1_CLK_DISABLE();
    /**CAN GPIO Configuration
    PB8     ------> CAN_RX
    PB9     ------> CAN_TX
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9);
    /* CAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
  }
}

/* USER CODE BEGIN 1 */
    CAN_FilterTypeDef  CAN_FilterStructure;//过滤器结构体
static    CAN_RxHeaderTypeDef  RxMessage;//接收的结构体
void MY_CAN_Filter(void)
{
    uint32_t mask;

    CAN_FilterStructure.FilterBank=0;
    CAN_FilterStructure.FilterMode=CAN_FILTERMODE_IDMASK;
    CAN_FilterStructure.FilterScale=CAN_FILTERSCALE_32BIT;
    CAN_FilterStructure.FilterIdHigh=0x0018<<5;//CAN报文标准帧识别是11位,向左移5位,变为16位
    CAN_FilterStructure.FilterIdLow=CAN_ID_STD;//我的需求是标准帧,扩展帧,远程帧就没设置了
    
    mask = 0x0018;//用于筛选ID
    mask =~mask;
    mask<<=3;
    mask |=0x02;
    CAN_FilterStructure.FilterMaskIdHigh=(mask>>16)&0xffff;
    CAN_FilterStructure.FilterMaskIdLow=mask&0xffff;//筛选模式可以设置,例如mask&0x0000
    CAN_FilterStructure.FilterFIFOAssignment=CAN_FILTER_FIFO0;
    CAN_FilterStructure.FilterActivation=CAN_FILTER_ENABLE;
    CAN_FilterStructure.SlaveStartFilterBank=0;
    HAL_CAN_ConfigFilter(&hcan,&CAN_FilterStructure);
    HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
}
//接收回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{  
    uint8_t data[8];//根据所需要发送的报文byte决定
    RxMessage.DLC=8;
    RxMessage.StdId=0x18;//接收报文的ID
    RxMessage.RTR=CAN_ID_STD;//ID类型如上,标准帧,扩展帧等等可选
    RxMessage.IDE=CAN_RTR_DATA;
    
     if (HAL_CAN_GetState(hcan)!= RESET)
     {
            HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxMessage, data);        
         
         if(data[0] == 0x00)
         {
             HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,GPIO_PIN_RESET);
             HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15,GPIO_PIN_SET);
         }                 
   }
}

/* USER CODE END 1 */

gpio.c

/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/*----------------------------------------------------------------------------*/
/* Configure GPIO                                                             */
/*----------------------------------------------------------------------------*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

  /*Configure GPIO pins : PB14 PB15 */
  GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */
void GPIO_Init()
{
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);
}
/* USER CODE END 2 */

当然,也可以实现单片机之间的相互发送报文,再定义一下 CAN_RxHeaderTypeDef结构体即可。这里由于我们是PC端发报文,不多此一举了。在实际的应用中可以加入CAN_Debug,Receive_Debug等等

下一章:记录一下我对CAN总线/CAN协议/CAN报文的理解。

与君共勉!!!

进阶功能

记得配置输出引脚

修改的can.c部分一样的系统代码就不放了

/*Define filter function*/
void MY_CAN_Filter(void)
{
  uint16_t mask,num,tmp,i;
    uint16_t STDIDArray[3]={0x18,0x559,0x666};//
//    /*0x599 Filter setting*/
    CAN_FilterStructure.FilterBank=0;//Set filter 0,ranges from 0 to 13
    CAN_FilterStructure.FilterMode=CAN_FILTERMODE_IDMASK;//Mask mode
    CAN_FilterStructure.FilterScale=CAN_FILTERSCALE_32BIT;//The bit width is set to 32
    CAN_FilterStructure.FilterIdHigh=STDIDArray[1]<<5;//Sets the identifier register height byte
    CAN_FilterStructure.FilterIdLow=0;//The low byte is set to 0
    
    mask=0xfff;//Start calculating the mask code,
    num=sizeof(STDIDArray)/sizeof(STDIDArray[1]);
    
    for(i=0;i<num;i++)//Mask the same or result of all members of the StdIdArray[] array
    {
        tmp = STDIDArray[i]^(~STDIDArray[1]);//All array members operate with the 0th member
        mask &=tmp;
    }
    CAN_FilterStructure.FilterMaskIdHigh=(mask<<5);
    CAN_FilterStructure.FilterMaskIdLow=0|0x02;//Only data frames are received
    CAN_FilterStructure.FilterFIFOAssignment=CAN_FILTER_FIFO0;//Set the data frame that passes into FIFO0
    CAN_FilterStructure.FilterActivation=CAN_FILTER_ENABLE;
    HAL_CAN_ConfigFilter(&hcan,&CAN_FilterStructure);
    HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
//    
}


int flag=0;//Set flag bits to select execution
CAN_Receive can_receive;//Custom structure,Check in stm32f1xx_hal_can_h.//Note that modifying it in CUNBEMX causes the struct to be lost
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//Receive the callback function
{         
     if (HAL_CAN_GetState(hcan)!= RESET)
     {
            HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can_receive.RxMessage,can_receive.data);    //Receive data in FIFO0

         if(can_receive.RxMessage.StdId==0x666)//Determines whether to control the packet ID
         {    
             if(can_receive.data[0]==0x10)//The first byte is 0x10, and 0x18 is assigned to flag
             {flag =0x18;}
             if(can_receive.data[0]==0x20)//The first byte is 0x20, and 0x18 is assigned to flag
             {flag =0x599;}
         }
        /*The flag is 0x18 and the ID of the received packet is 0x18,Switch to single-node mode*/
         if(flag==0x18)
         {
            if(can_receive.RxMessage.StdId==0x18)
             {Single_node_model();}
         }
         /*The flag is 0x559 and the ID of the received packet is 0x559,Switch to BX1E mode*/
         if(flag==0x599)
         {
            if(can_receive.RxMessage.StdId==0x559)
             {BX1E();}
         }

     }
     HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
}
/*Single node mode execution function */
void Single_node_model(void)
{
    uint8_t TMP_Twobit;//Set the variable to take the first two bits of the second byte
    TMP_Twobit=can_receive.data[1];
    TMP_Twobit>>=6;
         if(can_receive.data[0] == 0x19)//Currently ten bits are 100 in decimal
         {
             if(TMP_Twobit==0x00)
             {//PB-LED  Used for warning lamp faults
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);//PB14-LEDl on
              HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);//PB15-LED2 off
              HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2 | GPIO_PIN_3,GPIO_PIN_RESET);//Yellow light 
              HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4 | GPIO_PIN_1,GPIO_PIN_SET);
          }
      }
         if(can_receive.data[0] == 0x19)//Currently ten bits are 101 in decimal
         {
             if(TMP_Twobit==0x01)
            {
             HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET);//PB14-LEDl off
             HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET);//PB15-LED2 on
           HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);//green light
             HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1 | GPIO_PIN_3| GPIO_PIN_4 ,GPIO_PIN_SET);
            }
        }
                  
         if(can_receive.data[0] == 0xe1)//Currently ten bits are 900 in decimal
         {
             if(TMP_Twobit==0x00)
             {
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);//PB14-LED1 on
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET);//PB15-LED2 on
              HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3|GPIO_PIN_4,GPIO_PIN_RESET);// The buzzer sounded and red light
              HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1 | GPIO_PIN_2  ,GPIO_PIN_SET);
         }
           }    
}
/*BX1E mode execution function*/
void BX1E(void)
{
            uint8_t TMP_FB;//Define a variable to take the first four bits of the first byte
            TMP_FB=can_receive.data[0];
            TMP_FB>>=4;
            
             if(TMP_FB==0x0)//the first four bits are 0 in decimal
         {
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);    //PB14-LED1 on
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);    //PB15-LED2 off
            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2 | GPIO_PIN_3,GPIO_PIN_RESET);//Yellow light 
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4 | GPIO_PIN_1,GPIO_PIN_SET);
         }
         if(TMP_FB==0x1)//the first four bits are 1 in decimal
         {
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET);//PB14-LED1 off
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET);//PB15-LED2 on
            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);//Green light
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1 | GPIO_PIN_3| GPIO_PIN_4 ,GPIO_PIN_SET);
         }
         if(TMP_FB==0x2)//the first four bits are 2 in decimal
         {
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);//PB14-LED1 on
          HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET);//PB15-LED2 on
            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3|GPIO_PIN_4,GPIO_PIN_RESET);//The buzzer sounded and red light
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1 | GPIO_PIN_2  ,GPIO_PIN_SET);
         }
}
/* USER CODE END 1 */

下面的结构体不定义也可以,定义了CAN_Receive,方便查找

typedef struct CAN_Receive
{
  CAN_RxHeaderTypeDef RxMessage;
    
    uint8_t data[8];//Received message
}CAN_Receive;

实际效果

can收发报文,CAN通讯,报文控制器,stm32,学习,单片机,Powered by 金山文档

0 0x00000666 1s 橙色

1 0x00000018 1s 黄色

2 0x00000018 1s 绿色

3 0x00000018 1s 红色+蜂鸣器

4 0x00000559 1s 红色+蜂鸣器

5 0x00000666 1s 红色+蜂鸣器

6 0x00000559 1s 红色+蜂鸣器

7 0x00000559 1s 绿色

8 0x00000559 1s 黄色

不知道怎么上传视频,但是实际效果符合预期。文章来源地址https://www.toymoban.com/news/detail-703058.html

到了这里,关于CAN通讯配置及接收报文--学习笔记1~2的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • CAN总线通讯协议学习

    s目录 CAN(controller Area Network) 控制器局域网 CAN通讯 CAN总线的数据帧 解析         CAN总线应用最多的是汽车领域,这里的控制器在汽车领域的专业术语是ECU.(electronic control unit)电子控制单元。可以看成一个超小型的计算机,内部集成了供电系统,单片机,驱动系统,是汽车领

    2024年02月05日
    浏览(24)
  • 【STM32】CAN过滤器配置----接收特定ID发来的数据

    滤波器详细配置 (slave_id为只接收的id号): 1、对扩展数据帧进行过滤:(只接收扩展数据帧) 2、对扩展远程帧过滤:(只接收扩展远程帧) 3、对标准远程帧过滤:(只接收标准远程帧) 4、对标准数据帧过滤:(只接收标准数据帧) 5、对扩展帧进行过滤:(只接收扩展帧) 6、对标准帧进行

    2024年02月12日
    浏览(30)
  • CAN收发器与CAN控制器

    CAN收发器是一种用于CAN总线通信的专用芯片,主要用于将CAN控制器和CAN总线物理层之间的信号进行转换和调节。它的主要作用是将CAN控制器输出的数字信号转换为CAN总线所需要的物理信号,同时将CAN总线上接收到的物理信号转换为数字信号,并将其传递给CAN控制器进行处理。

    2024年01月24日
    浏览(39)
  • 【嵌入式】HC32F07X CAN通讯配置和使用&配置不同缓冲器以连续发送

            使用小华(华大)的MCU HC32F07X实现 CAN 通讯配置和使用 【1】 CAN原理说明 (参考文章《CAN通信详解》):         CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现分布式实时控制的串行通信网络。         (i) CAN通信形式 :CAN 使用称为 C

    2024年02月06日
    浏览(37)
  • CAN报文解析

    CAN报文是指发送单元向接受单元传送数据的帧。我们通常所说的CAN报文是指在CAN线(内部CAN、整车CAN、充电CAN)上利用ECU和CAN卡接收到的十六进制报文。 对于单个Byte,CAN总线在进行数据传输时,首先传输一个字节的高位(MSB),最后传输该字节的低位(LSB)。 一般情况下,

    2023年04月08日
    浏览(25)
  • CAN报文基础

    通信分类 根据数据传输方式可分为 串行通信 和 并行通信 ,根据接收端和发送端时钟频率的异同可以分为 同步通信 和 异步通信 ,根据通信双方的分工和信号传输方向可分为 单工通信 、 半双工通信 和 全双工通信 。 串行通信、并行通信 串行通信:数据的各位在 同一根数

    2024年02月04日
    浏览(29)
  • 车载通信——CAN报文信号排列方式(报文/信号结构)

    一、CAN报文信号排列方式 在定义CAN通信矩阵或制作dbc时,需确定报文的信号排列方式。字节的排列顺序有:Intel的排列顺序;Motorola的排列顺序。 注: Motorola和Intel格式,只在信号数据跨字节解析时有区别,单个字节数据没有区别 。 二、 编码格式 (1)Intel格式——小端 当

    2024年02月14日
    浏览(34)
  • CAN转EtherNet/IP网关can协议支持哪两种报文

    你是否曾经遇到过不同的总线协议难以互相通信的问题?远创智控的YC-EIP-CAN网关为你解决了这个烦恼! 远创智控YC-EIP-CAN通讯网关是一款自主研发的设备,它能够将各种CAN总线和ETHERNET/IP网络连接起来,解决不同总线协议之间的通信障碍。作为ETHERNET/IP总线的从站,它可以连接

    2024年02月16日
    浏览(24)
  • CAN总线报文格式———标准数据帧

    标准数据帧由帧起始、仲裁段、控制段、数据段、CRC段、ACK段、帧结束等组成。 CAN总线空闲时,总线上会输出持续的高电平“1”。当总线空闲时任何连接的单元都可以开始发送新的报文。 SOF是数据帧传输的起始位。发送方(sender)会发送一个显性电平作为SOF,由于总线空闲

    2024年01月22日
    浏览(33)
  • CAN总线学习笔记 | CAN基础知识介绍

    1.1 CAN协议简介 CAN 是控制器局域网络 (Controller Area Network) 的简称,它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的,并最终成为国际标准(ISO11519以及ISO11898),是国际上应用最广泛的现场总线之一。差异点如下: 1.2 CAN物理层 CAN 通讯不是以时钟信号来进行同步的,它

    2023年04月09日
    浏览(34)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包