当前位置: 首页 > news >正文

协议-CAN-CANopen

是什么?

  • 汽车工程师的总线协议

为什么?

  • 1980年代初期,由于没有可满足汽车工程师的总线协议,人们开始开发新的串行总线
  • 在底特律举行SAE会议上CAN总线诞生,称之为Automotive Serial Controller Area Network

在这里插入图片描述


怎么做?


核心本质

  • 两根线上特殊电平的特殊协议
  • 张嘴显性电平‘0’,闭嘴隐形电平‘1’
  • 头是识别头,身是控制端加数据段,尾是识别尾
  • CANFD 数据多 CRC多 速度快

电平定义

两个ISO标准

  • CAN ISO11898 标准和 ISO11519-2 标准
    • ISO11898 是针对通信速率为 125Kbps~1Mbps 的高速通信标准
    • ISO11519-2 是针对通信速率为 125Kbps 以下的低速通信标准

在这里插入图片描述

在这里插入图片描述

张嘴是嘴巴形状是显性电平,闭嘴如横着的隐性电平

在这里插入图片描述


CAN帧类型

在这里插入图片描述

数据帧

  • 数据帧一般由 7 个段构成

传统CAN

在这里插入图片描述

CAN-FD

在这里插入图片描述

仲裁段

在这里插入图片描述

控制段

在这里插入图片描述

DLC

在这里插入图片描述

CRC

在这里插入图片描述

ACK

在这里插入图片描述

在这里插入图片描述

错误帧

在这里插入图片描述

总结

  • 开始了SOF
  • 我是谁ID
  • 我要告诉你几件事DLC
  • 下面是具体事情DATA
  • 这是几件事验证码CRC
  • 你知晓了事情给我回信ACK
  • 结束EOF

Tq采样点

CAN位时序

在这里插入图片描述

在这里插入图片描述

STM位时序

在这里插入图片描述


仲裁功能

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

在这里插入图片描述


过滤器(屏蔽位、标志位)

在这里插入图片描述

  • CANFD支持:
    • 范围过滤器(Rangefilter):该过滤器匹配标识符在两个ID定义的范围内的所有消息。
    • 专用ID的过滤器(Filter for dedicatedIDs):可以将过滤器配置为匹配一个或两个特定的标识符。
    • 经典位屏蔽过滤器(classic bit mask filter):通过对接收到的标识符的位进行屏蔽来匹配标识符组。

STM流程控制

STM发送流程

在这里插入图片描述

在这里插入图片描述


STM接收流程

在这里插入图片描述


STM- TJA1050

在这里插入图片描述


STM 代码

  • STM32F429 提供了两种测试模式,环回模式和静默模式
CAN_HandleTypeDef CAN1_Handler; //CAN1 句柄
CanTxMsgTypeDef TxMessage; //发送消息
CanRxMsgTypeDef RxMessage; //接收消息
CAN_FilterConfTypeDef CAN1_FilerConf

HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan);
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan);//回调函数
HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig);
HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout);
HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout);
u8 CAN1_Mode_Init(u32 tsjw,u32 tbs2,u32 tbs1,u16 brp,u32 mode)
{
   
 CAN_FilterConfTypeDef CAN1_FilerConf;
 
 CAN1_Handler.Instance=CAN1; 
 CAN1_Handler.pTxMsg=&TxMessage; //发送消息
 CAN1_Handler.pRxMsg=&RxMessage; //接收消息
 CAN1_Handler.Init.Prescaler=brp; //分频系数(Fdiv)为 brp+1
 CAN1_Handler.Init.Mode=mode; //模式设置
 CAN1_Handler.Init.SJW=tsjw; //重新同步跳跃宽度
 CAN1_Handler.Init.BS1=tbs1; //tbs1 范围 CAN_BS1_1TQ~CAN_BS1_16TQ
 CAN1_Handler.Init.BS2=tbs2; //tbs2 范围 CAN_BS2_1TQ~CAN_BS2_8TQ
 CAN1_Handler.Init.TTCM=DISABLE; //非时间触发通信模式
 CAN1_Handler.Init.ABOM=DISABLE; //软件自动离线管理
 CAN1_Handler.Init.AWUM=DISABLE; //睡眠模式通过软件唤醒
 CAN1_Handler.Init.NART=ENABLE; //禁止报文自动传送
 CAN1_Handler.Init.RFLM=DISABLE; //报文不锁定,新的覆盖旧的
 CAN1_Handler.Init.TXFP=DISABLE; //优先级由报文标识符决定
 if(HAL_CAN_Init(&CAN1_Handler)!=HAL_OK) return 1; //初始化 CAN1
 
 CAN1_FilerConf.FilterIdHigh=0X0000; //32 位 ID
 CAN1_FilerConf.FilterIdLow=0X0000;
 CAN1_FilerConf.FilterMaskIdHigh=0X0000; //32 位 MASK
 CAN1_FilerConf.FilterMaskIdLow=0X0000; 
 CAN1_FilerConf.FilterFIFOAssignment=CAN_FILTER_FIFO0;//过滤器 0 关联到 FIFO0
 CAN1_FilerConf.FilterNumber=0; //过滤器 0
 CAN1_FilerConf.FilterMode=CAN_FILTERMODE_IDMASK;
 CAN1_FilerConf.FilterScale=CAN_FILTERSCALE_32BIT;
 CAN1_FilerConf.FilterActivation=ENABLE; //激活滤波器 0
 CAN1_FilerConf.BankNumber=14;
if(HAL_CAN_ConfigFilter(&CAN1_Handler,&CAN1_FilerConf)!=HAL_OK) return 2;
//滤波器初始化
 return 0;
}


//CAN 底层驱动,引脚配置,时钟配置,中断配置
//此函数会被 HAL_CAN_Init()调用
//hcan:CAN 句柄
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
   
 GPIO_InitTypeDef GPIO_Initure;
 
 __HAL_RCC_CAN1_CLK_ENABLE(); //使能 CAN1 时钟
 __HAL_RCC_GPIOA_CLK_ENABLE(); //开启 GPIOA 时钟
 GPIO_Initure.Pin=GPIO_PIN_11|GPIO_PIN_12; //PA11,12
 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用
 GPIO_Initure.Pull=GPIO_PULLUP; //上拉
 GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速
 GPIO_Initure.Alternate=GPIO_AF9_CAN1; //复用为 CAN1
 HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化
 
#if CAN1_RX0_INT_ENABLE
 __HAL_CAN_ENABLE_IT(&CAN1_Handler,CAN_IT_FMP0);//FIFO0 挂起中断允许.
 HAL_NVIC_SetPriority(CAN1_RX0_IRQn,1,2); //抢占优先级 1,子优先级 2
 HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); //使能中断
#endif
}
#if CAN1_RX0_INT_ENABLE //使能 RX0 中断
//CAN 中断服务函数
void CAN1_RX0_IRQHandler(void)
{
   
 HAL_CAN_IRQHandler(&CAN1_Handler);//此函数会调用 CAN_Receive_IT()接收数据
}


//CAN 中断处理过程
//此函数会被 CAN_Receive_IT()调用
//hcan:CAN 句柄
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
{
   
 int i=0;
//CAN_Receive_IT()函数会关闭 FIFO0 消息挂号中断,因此我们需要重新打开
 __HAL_CAN_ENABLE_IT(&CAN1_Handler,CAN_IT_FMP0);
//重新开启 FIF00 消息挂号中断
 printf("id:%d\r\n",CAN1_Handler.pRxMsg->StdId);
 printf("ide:%d\r\n",CAN1_Handler.pRxMsg->IDE);
 printf("rtr:%d\r\n",CAN1_Handler

相关文章:

  • Android音视频多媒体开源库基础大全
  • AD(Altium Designer)已有封装库的基础上添加器件封装
  • pytorch小土堆学习有感
  • 什么是TCP,UDP,MQTT?
  • Touch Diver:Weart为XR和机器人遥操作专属设计的触觉反馈动捕手套
  • BlockChain.java
  • 荣获全栈身份nodejs实现登录功能
  • DHCP工作原理
  • Floyd 算法--多源最短路
  • 在 Elasticsearch 中扩展后期交互模型 - 第 2 部分 - 8.18
  • WRF/Chem 模式技术解读:为大气污染治理提供有力支撑
  • 【设计模式】常用的设计模式详解
  • C#Dictionary值拷贝还是引用
  • 项目篇:模拟实现高并发内存池(2)
  • MFC中CString类型是如何怎么转std::string的
  • 基于大模型的下颌前突畸形预测及治疗方案研究报告
  • Trick:vs编译的release中提示debug库找不到方案
  • 报错 - redis - Unit redis.service could not be found.
  • go安装lazydocker
  • MyBatis-Plus:告别手写 SQL 的高效之道
  • 昆明一学校门外小吃摊占满人行道,城管:会在重点时段加强巡查处置
  • 四川资阳市原市长王善平被双开,“笃信风水,大搞迷信活动”
  • 2025年上海市模范集体、劳动模范和先进工作者名单揭晓
  • 以总理内塔尼亚胡称决心彻底击败哈马斯
  • 巴基斯坦称约50名印度士兵在克什米尔实控线丧生
  • 昆廷·斯金纳:作为“独立自主”的自由