CAN协议特点

1.多主控制
所有单元都可以发送消息,根据标识符(Identifier简称ID)决定优先级。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作

2.系统的柔软性
与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变

3.通信速度较快,通信距离远
最高 1Mbps(距离小于40M),最远可达10KM(速率低于5Kbps)

4.具有错误检测、错误通知和错误恢复功能
所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制
结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)

5.故障封闭功能
CAN可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去

6. 连接节点多
CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制

总线拓扑
总线电平分为显性电平和隐性电平两种。“显性”具有“优先”的意味,只要有一个单元输出显性电平,总线上即为显性电平。并且,“隐性”具有“包容”的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平

帧的种类

帧的种类及用途

数据帧的构成

帧起始:数据帧开始
仲裁段:该帧优先级
控制段:数据的字节数及保留位
数据段:数据的内容,可发送0~8个字节的数据
CRC段:检查帧的传输错误
ACK段:确认正常接收
帧结束:数据帧结束

遥控帧的构成
遥控帧没有数据帧的数据段

错误帧

错误标志:包括主动错误标志和被动错误标志两种。主动错误标志为6位的显性位;被动错误标志为6位的隐性位
错误界定符:由8位的隐性位构成

过载帧

过载标志:6位的显性位(与主动错误标志的构成相同)
过载界定符:8位的隐性位(与错误界定符的构成相同)

帧间隔

间隔:3位的隐性位
延迟传送:8位的隐性位
总线空闲:隐性电平,无长度限制(0 亦可)

数据帧

帧起始
标准、扩展格式相同。1位的显性位

仲裁段

扩展帧的仲裁段有29位,可以出现229种报文。标准帧的仲裁段是11位,可以出现211种报文。扩展帧能扩展更多的CAN节点,更好地支持上层协议

控制段

数据长度码和字节数的关系:

“D”为显性电平;“R”为隐性电平

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

CRC段
由15位的CRC顺序和1位的CRC界定符(用于分隔的位)构成

ACK段
由ACK槽(ACK Slot)和ACK界定符2位构成

帧结束
由7位的隐性位构成

优先级的决定

连续输出显性电平最多的单元可继续发送


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

标准格式和扩展格式的优先级
标准格式的RTR位为显性位的具有优先权,可继续发送

bxCAN工作模式

bxCAN有3个主要的工作模式:初始化、正常和睡眠模式

初始化模式
设置CAN_MCR寄存器的INRQ位为’1’,请求bxCAN进入初始化模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’来进行确认

正常模式
软件对CAN_MCR寄存器的INRQ位清’0’,来请求从初始化模式进入正常模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’的确认

睡眠模式
软件对CAN_MCR寄存器的SLEEP位置’1’,来请求进入这一模式

测试模式

通过对CAN_BTR寄存器的SILM和LBKM配置

静默模式(CAN_Mode_Silent)
通过对CAN_BTR寄存器的SILM位置’1’,来选择静默模式

环回模式(CAN_Mode_LoopBack)
通过对CAN_BTR寄存器的LBKM位置’1’,来选择环回模式

环回静默模式(CAN_Mode_Silent_LoopBack)
通过对CAN_BTR寄存器的LBKM和SILM位同时置’1’,可以选择环回静默模式

超过8字节数据发送

可以采取拆包、组包方法。记录包id和是否为结尾包标识。接收方如果未接收完整个包,直到接收完整包再进行处理
详细参考:uavcan

CAN配置步骤

1.使能CAN时钟
2.使能GPIO端口时钟
3.GPIO端口模式设置
4.配置CAN工作模式、波特率等
5.配置CAN筛选器
6.选择CAN中断类型,开启中断
7.初始化NVIC外设
8.编写CAN中断处理函数
9.CAN发送和接收消息
10.CAN状态获取

硬件设计


举例


typedef struct
{uint32_t StdId; //标准标识符uint32_t ExtId; //扩展标识符uint8_t IDE; //标识符选择uint8_t RTR; //远程发送请求uint8_t DLC; //发送数据长度uint8_t Data[8]; //数据字节
} CanTxMsg;void CAN_transmit(u8 *data, u8 len)
{u8 i = 0, box;CanTxMsg msg = {0};msg.StdId = 0x12;msg.ExtId = 0x12;msg.IDE = CAN_Id_Standard; //使用标准标识符msg.RTR = CAN_RTR_Data; //数据帧msg.DLC = len;for(i = 0; i < len; i++){msg.Data[i] = data[i];}box = CAN_Transmit(CAN1, &msg);while(CAN_TransmitStatus(CAN1, box) == CAN_TxStatus_Failed);return;
}u8 CAN_receive(u8 *data)
{u8 i = 0;CanRxMsg msg = {0};if(CAN_MessagePending(CAN1, CAN_FIFO0) == 0){return 0;}CAN_Receive(CAN1, CAN_FIFO0, &msg);for(i = 0; i < msg.DLC; i++){data[i] = msg.Data[i];}return msg.DLC;
}#ifdef CAN_IT
void USB_LP_CAN1_RX0_IRQHandler()
{u8 data[8], len;if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) == SET){len = CAN_receive(data);CAN_transmit(data, len);led1 = ~led1;    }CAN_ClearFlag(CAN1, CAN_IT_FMP0);
}
#endiftypedef struct
{uint16_t CAN_Prescaler; //波特率分频器uint8_t CAN_Mode; //测试模式uint8_t CAN_SJW; //重新同步跳跃宽度uint8_t CAN_BS1; //时间段1uint8_t CAN_BS2; //时间段2FunctionalState CAN_TTCM; //时间触发通信模式FunctionalState CAN_ABOM; //自动离线管理FunctionalState CAN_AWUM; //自动唤醒模式FunctionalState CAN_NART; //禁止报文自动重传 FunctionalState CAN_RFLM; //接收FIFO锁定模式FunctionalState CAN_TXFP; //发送FIFO优先级
} CAN_InitTypeDef;typedef struct
{uint16_t CAN_FilterIdHigh;uint16_t CAN_FilterIdLow;uint16_t CAN_FilterMaskIdHigh;uint16_t CAN_FilterMaskIdLow;uint16_t CAN_FilterFIFOAssignment; //过滤器位宽设置uint8_t CAN_FilterNumber;uint8_t CAN_FilterMode; //过滤器模式uint8_t CAN_FilterScale; //过滤器位宽设置FunctionalState CAN_FilterActivation; //过滤器激活
} CAN_FilterInitTypeDef;void CAN_init()
{GPIO_InitTypeDef gpio11 = {GPIO_Pin_11,GPIO_Speed_50MHz,GPIO_Mode_IPU};   GPIO_InitTypeDef gpio12 = {GPIO_Pin_12,GPIO_Speed_50MHz,GPIO_Mode_AF_PP};  CAN_InitTypeDef can = {0};CAN_FilterInitTypeDef can_filter = {0};NVIC_InitTypeDef nvic = {USB_LP_CAN1_RX0_IRQn,2,2,ENABLE};RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_Init(GPIOA, &gpio11);GPIO_Init(GPIOA, &gpio12);can.CAN_Prescaler = 4;can.CAN_Mode = CAN_Mode_LoopBack; //环回模式can.CAN_SJW = CAN_SJW_1tq; //占用1个时间单元can.CAN_BS1 = CAN_BS1_9tq; //占用9个时间单元can.CAN_BS2 = CAN_BS2_8tq; //占用8个时间单元can.CAN_TTCM = DISABLE; //详见上图can.CAN_ABOM = DISABLE;can.CAN_AWUM = DISABLE;can.CAN_NART = ENABLE;can.CAN_RFLM = DISABLE;can.CAN_TXFP = DISABLE;CAN_Init(CAN1, &can);can_filter.CAN_FilterIdHigh = 0;can_filter.CAN_FilterIdLow = 0;can_filter.CAN_FilterMaskIdHigh = 0;can_filter.CAN_FilterMaskIdLow = 0;can_filter.CAN_FilterFIFOAssignment = CAN_FilterFIFO0; //过滤器被关联到FIFO0can_filter.CAN_FilterNumber = 0;can_filter.CAN_FilterMode = CAN_FilterMode_IdMask; //过滤器组x的2个32位寄存器工作在标识符屏蔽位模式can_filter.CAN_FilterScale = CAN_FilterScale_32bit;  //过滤器位宽为单个32位can_filter.CAN_FilterActivation = ENABLE; //过滤器被激活CAN_FilterInit(&can_filter);#ifdef CAN_ITCAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);NVIC_Init(&nvic);
#endif
}int main(void)
{CAN_init();for(i = 0; i < 8; i++){txbuf[i] = i;}while(1){led1 = ~led1;CAN_transmit(txbuf, 8);res = CAN_receive(rxbuf);if(res){for(i = 0; i < 8; i++){rxbuf[i] = rxbuf[i] + 0x30;}printf("CAN_receive len %d, %s\n", res, rxbuf);}delay_ms(1000);}
}

CAN过滤器组配置:http://blog.csdn.net/zhangxuechao_/article/details/78488603

stm32 CAN通信 TJA1040相关推荐

  1. python实现STM32单片机通信

    python实现STM32单片机通信 注意事项 注意事项 Python3中的encode('unicode-escape')和encode('raw_unicode_escape')区别与联系 htt ...

  2. stm32串口通信(初学者对于串口通信的理解)

    stm32串口通信(初学者对于串口通信的理解) 标签: stm32串口通信单片机 2015-01-24 10:12 987人阅读 评论(0) 收藏 举报  分类: stm32 版权声明:本文为博主原创 ...

  3. STM32串口通信中使用printf发送数据配置方法 开发环境 Keil

    STM32串口通信中使用printf发送数据配置方法(开发环境 Keil RVMDK) 已有 12456 次阅读2011-6-29 23:29 | 在STM32串口通信程序中使用printf发送数据, ...

  4. STM32——串口通信

    STM32--串口通信 宗旨:技术的学习是有限的,分享的精神是无限的. 一.异步串口通信协议 STM32 的串口非常强大,它不仅支持最基本的通用串口同步.异步通信,还具有 LIN 总线功能(局域互联网 ...

  5. openmv和stm32串口通信完成二维码识别

    openmv和stm32串口通信完成二维码识别 文章目录 前言 一.所用的硬件: 二.openmv端 2.stm32端 总结 前言 注:我只是个大一的小白,本文只完成基本功能,希望能帮助有困惑的人(我 ...

  6. 通俗理解STM32 SPI通信(主从双机SPI通信)

    STM32 SPI通信 高速全双工的通信总线 SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK.MOSI.MISO,片选线为NSS(CS) NSS 信号线由高变低 ,是 SPI 通讯的起 ...

  7. STM32——stm32 I2C通信代码配置(2)(学习笔记)

    STM32--I2C通信配置 I2C的系统框架 1.通讯引脚 2.时钟控制逻辑 3.数据控制逻辑 4.整体控制逻辑 通信过程 写入过程 读取过程 I2C代码配置 I2C的初始化结构体 几个重要的函数 ...

  8. Ardunio下的STM32串口通信

    文章目录 任务要求 Ardunio下的STM32串口通信 软件准备 编译烧录 标准库函数与HAL库函数的stm32编程方式差异 国人版的MCU集成开发平台 stduino IDE 总结 任务要求 安装 ...

  9. 安装STM32CubeMX,stm32串口通信

    目录 一.串口通信和RS-232标准 1.串口通信 波特率 数据位 停止位 奇偶校验 2.RS-232标准 二.安装STM32CubeMX,搭建STM32的开发环境 1.安装jdk 2.安装STM32 ...

  10. 【串口通信】K210与STM32串口通信、K210与OpenMV串口通信

    [串口通信]K210与STM32串口通信.K210与OpenMV串口通信 串口通信 前言 为何需要串口通信 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口发送测试 ...

最新文章

  1. what is MEAN
  2. What you should do if you want to become more professional in career?
  3. 【Python】/ 和 // 的区别
  4. DBeaverEE7.3.0安装教程
  5. CF280C-Game on Tree【数学期望】
  6. linux shell脚本链接操作符,Shell脚本中的操作符
  7. form data怎么接收_VUE发送Formdata数据,NodeJS接收
  8. DBCA静默建库中的两个小问题
  9. Java异常处理机制(基础知识)
  10. Html垂直居中不起作用,html – 垂直居中不起作用,因为行不会达到100%的高度
  11. rtx2060什么水平_《赛博朋克2077》持续火热 什么样的笔记本才能畅玩这款游戏
  12. 阿里云图标icon使用symbol 引用方式
  13. 苹果cms如何添加广告代码
  14. 电脑硬件故障排除经验
  15. 遇到了一个date控件显示的问题
  16. C语言程序设计笔记(浙大翁恺版) 第二周:计算
  17. 骑行318、 2016.7.13
  18. py实战绘制人口金字塔图
  19. Google服务和软件大全
  20. 【数据集介绍】The Idiap Research Institute REPLAY-Mobile Database

热门文章

  1. redis短信发送限制
  2. 挑选电脑免费加密软件特别注意哪些?
  3. 建设内链要注意的事项
  4. 裸眼3d项目,数字平原是这样制作的
  5. 非平衡载流子和pn结
  6. Java用ListArray以人名的姓氏排队
  7. 服务器停止响应是什么意思,该如何排查?
  8. WINVNC源码阅读(二)
  9. c语言魔方编程,用C语言编程玩转魔方阵小游戏
  10. APP启动时间检测——u-apm