stm32 CAN通信 TJA1040
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相关推荐
- python实现STM32单片机通信
python实现STM32单片机通信 注意事项 注意事项 Python3中的encode('unicode-escape')和encode('raw_unicode_escape')区别与联系 htt ...
- stm32串口通信(初学者对于串口通信的理解)
stm32串口通信(初学者对于串口通信的理解) 标签: stm32串口通信单片机 2015-01-24 10:12 987人阅读 评论(0) 收藏 举报 分类: stm32 版权声明:本文为博主原创 ...
- STM32串口通信中使用printf发送数据配置方法 开发环境 Keil
STM32串口通信中使用printf发送数据配置方法(开发环境 Keil RVMDK) 已有 12456 次阅读2011-6-29 23:29 | 在STM32串口通信程序中使用printf发送数据, ...
- STM32——串口通信
STM32--串口通信 宗旨:技术的学习是有限的,分享的精神是无限的. 一.异步串口通信协议 STM32 的串口非常强大,它不仅支持最基本的通用串口同步.异步通信,还具有 LIN 总线功能(局域互联网 ...
- openmv和stm32串口通信完成二维码识别
openmv和stm32串口通信完成二维码识别 文章目录 前言 一.所用的硬件: 二.openmv端 2.stm32端 总结 前言 注:我只是个大一的小白,本文只完成基本功能,希望能帮助有困惑的人(我 ...
- 通俗理解STM32 SPI通信(主从双机SPI通信)
STM32 SPI通信 高速全双工的通信总线 SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK.MOSI.MISO,片选线为NSS(CS) NSS 信号线由高变低 ,是 SPI 通讯的起 ...
- STM32——stm32 I2C通信代码配置(2)(学习笔记)
STM32--I2C通信配置 I2C的系统框架 1.通讯引脚 2.时钟控制逻辑 3.数据控制逻辑 4.整体控制逻辑 通信过程 写入过程 读取过程 I2C代码配置 I2C的初始化结构体 几个重要的函数 ...
- Ardunio下的STM32串口通信
文章目录 任务要求 Ardunio下的STM32串口通信 软件准备 编译烧录 标准库函数与HAL库函数的stm32编程方式差异 国人版的MCU集成开发平台 stduino IDE 总结 任务要求 安装 ...
- 安装STM32CubeMX,stm32串口通信
目录 一.串口通信和RS-232标准 1.串口通信 波特率 数据位 停止位 奇偶校验 2.RS-232标准 二.安装STM32CubeMX,搭建STM32的开发环境 1.安装jdk 2.安装STM32 ...
- 【串口通信】K210与STM32串口通信、K210与OpenMV串口通信
[串口通信]K210与STM32串口通信.K210与OpenMV串口通信 串口通信 前言 为何需要串口通信 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口发送测试 ...
最新文章
- what is MEAN
- What you should do if you want to become more professional in career?
- 【Python】/ 和 // 的区别
- DBeaverEE7.3.0安装教程
- CF280C-Game on Tree【数学期望】
- linux shell脚本链接操作符,Shell脚本中的操作符
- form data怎么接收_VUE发送Formdata数据,NodeJS接收
- DBCA静默建库中的两个小问题
- Java异常处理机制(基础知识)
- Html垂直居中不起作用,html – 垂直居中不起作用,因为行不会达到100%的高度
- rtx2060什么水平_《赛博朋克2077》持续火热 什么样的笔记本才能畅玩这款游戏
- 阿里云图标icon使用symbol 引用方式
- 苹果cms如何添加广告代码
- 电脑硬件故障排除经验
- 遇到了一个date控件显示的问题
- C语言程序设计笔记(浙大翁恺版) 第二周:计算
- 骑行318、 2016.7.13
- py实战绘制人口金字塔图
- Google服务和软件大全
- 【数据集介绍】The Idiap Research Institute REPLAY-Mobile Database