联通 网站备案,wordpress评论微信登录,网站标题tdk,郑州seo教程系列文章#xff0c;持续探索CAN多节点通讯#xff0c;
上一篇文章链接#xff1a;
STM32 CAN多节点组网项目实操 挖坑与填坑记录-CSDN博客文章浏览阅读120次。CAN线性组网项目开发过程中遇到的数据丢包问题#xff0c;并尝试解决的记录和推测分析。开发了一个多节点线性…系列文章持续探索CAN多节点通讯
上一篇文章链接
STM32 CAN多节点组网项目实操 挖坑与填坑记录-CSDN博客文章浏览阅读120次。CAN线性组网项目开发过程中遇到的数据丢包问题并尝试解决的记录和推测分析。开发了一个多节点线性组网采集数据的项目。系统包含1个供电和数据网关板还有最多10个节点。节点之间和网关之间通过CAN通讯。硬件环境节点软件开发环境节点IAR 8.32.1VSCODE软件支持包ST HAL 库硬件环境网关板软件开发环境节点KEIL5.14VSCODE软件支持包ST HAL 库PC上位机环境windows10USB-CAN PC上位机CANAGAROOPC串口助手。https://blog.csdn.net/qq_21370051/article/details/134919608?spm1001.2014.3001.5502 摘要 CAN线性组网项目开发过程中遇到的数据丢包问题并尝试解决的记录和推测分析。 关键词 CAN串联多节点通讯、CAN10节点通讯、CAN数据丢包、STM32 CAN 背景/项目介绍 概述 开发了一个多节点线性组网采集数据的项目。 系统包含1个供电和数据网关板还有最多10个节点。 节点之间和网关之间通过CAN通讯。 网关板主要功能
1.是给总线上每个节点供电
2.并将CAN协议转换为USB CDC设备和PC上位机通讯。
节点的功能
采集当前位置数据并通过CAN协议上传给网关板。
通讯线束
CAT6 六类网线用的网线来传输CAN信号取网线中的1对双绞线来做CAN_H CAN_L通讯再取2对网线来做供电由网关板输出DC12到网线以此给10个节点做供电算是自己做了个POE供电不过是非标的哈哈哈哈。
节点硬件设计
一个STM32单片机、两个不带网络变压器的RJ45插座。CAN收发器芯片。
两个RJ45插座完全并联当接线时一个用来插入上一个节点延展出的网线水晶头另一个RJ45插座插入一条网线用来连接下一个节点。
整体系统总线布局 虽然系统物理宏观角度来看是线性连接的但其实内部每个节点还是通过CAN_H CAN_L挂载到总线上的。类似上图的链接方式。
运行开发环境介绍 硬件环境 节点 STM32F091CCT6 J-LINK V11 软件开发环境 节点 IAR 8.32.1 VSCODE 软件支持包ST HAL 库 硬件环境 网关板 STM32F072C816 J-LINK V11 软件开发环境 节点 KEIL5.14 VSCODE 软件支持包ST HAL 库PC上位机环境windows10USB-CAN PC上位机CANAGAROOPC串口助手Serial Port Utility 实验1
实验条件
测试条件在最高18层的居民楼馁网关板在二居室卧室里后级网线从市内拉到居民楼楼道内随楼道步梯往楼上呈“之”字形往楼上延伸。网关板和PC之间是USB-TYPE-C线连接协议为USB-TTL 。
节点布局
CAN网关板和第一个节点之间用50米的CAT6网线第二个节点到第十个节点之间都是2米的CAT6网线。
节点间的2米网线没有伸展开绕圈放置。
线束材料
CAT6类网线我是用网线来传输的CAN信号并且用网线来传输12V DC给接点供电。
其中第一根网线10米其余为5米。
通讯波特率
10k
接入节点
实验1接入的是1.2.3.4.5.6.7.8.9.10 这几个节点。
接点接入方法1 先开启网关板的供电,然后一个个接入节点设备 节点接入方法2 先不开启网关板供电先将所有节点接好然后再开启网关板供电所有节点上电。或者是用“节点接入方法1”接好总线后再给网关板断电然后重新上电都是为了实现一个所有节点同时上电。 实验发现
只能接收到 5节点的数据。 实验2
实验条件
线束材料
和实验1 相同。
通讯波特率
10k
接入节点
也接入的是1.2.3.4.5.6.7.8 9.10 这几个节点。 线束布局
和实验1 相同。
实验变量
在实验1的基础上将节点间的2米网线伸展开。
实验发现
只能接收到6个节点的数据。 总结扩展
我为了增加通讯距离已经将通讯速率降低到了10Kbps,理论上通讯距离50米应该没问题啊我之前设置125Kbps也是网关10个节点第一个节点和网关之间20米CAT6网线节点之间5米网线实验时通讯是正常的总长度已经是70米了。而今天的实验任意两节点间距离达到了50米就出现了如此严重的丢数据现象是不能接受的。 实验3:
实验条件
线束材料、通讯波特率同实验2。
实验变量
找一个普通节点相同的电路板将程序改为收到就转发。让他成为一个中继节点。
接入节点
中继1 节点1 2 3 4 5 6 7 8 9 10
节点布局
网关板和第一个中继板之间为10米蓝色的超六类双屏蔽的网线
再接20米的灰色普通CAT6网线。后面的10个节点之间为2米的CAT6网线。
因为空间受限节点之间的网线没有全延展开。
程序修改
收到CAN数据就原封不动转发的代码实现如下 uint16_t RecvCanDataToCmdQueue(void)
{// uint8_t lu8_sta 0;// uint16_t lu16_temp 0;// memset(UpComCmdDP,0,sizeof(UpComCmdDP));// memset(gu8Ar_Result,0,sizeof(gu8Ar_Result)); CanDataRx_TypeDef ls_CanRxData;CanDataTx_TypeDef Frame;ErrorStatus err SUCCESS;uint16_t lu16_cnt 0;uint32_t lu32_sta 0;uint16_t lu16_temp 0;memset(Frame,0,sizeof(Frame));memset(UpComCmdDP,0,sizeof(UpComCmdDP));memset(ls_CanRxData,0,sizeof(ls_CanRxData));lu16_cnt QUEUE_StructOut(QueCanRxData,ls_CanRxData,1); // CanDataTx_TypeDef Frame;// ErrorStatus err SUCCESS;// memset(Frame,0,sizeof(Frame));if(gu8_DecvType M_Repeater){if(1 lu16_cnt) {Frame.Header.IDE CAN_ID_EXT;Frame.Header.StdId ls_CanRxData.Header.StdId;Frame.Header.ExtId ls_CanRxData.Header.ExtId;Frame.Header.RTR CAN_RTR_DATA; Frame.Header.DLC 8; Frame.DataBuf[0] ls_CanRxData.DataBuf[0];Frame.DataBuf[1] ls_CanRxData.DataBuf[1];Frame.DataBuf[2] ls_CanRxData.DataBuf[2]; Frame.DataBuf[3] ls_CanRxData.DataBuf[3]; Frame.DataBuf[4] ls_CanRxData.DataBuf[4]; Frame.DataBuf[5] ls_CanRxData.DataBuf[5]; Frame.DataBuf[6] ls_CanRxData.DataBuf[6]; Frame.DataBuf[7] ls_CanRxData.DataBuf[7]; err CanPackData2TxQue(Frame);if(err! SUCCESS){myprintf(DEBUG_UART,CanPackData2TxQue ERR \r\n);return ERROR;}}}else{if(1 lu16_cnt) {if(gS_SysParm.PCCanID ls_CanRxData.Header.ExtId ) //如果数据是从PC发来的{if( ( gS_SysParm.LocalCanID ls_CanRxData.DataBuf[0] ) || ( BROADCAST_CANID ls_CanRxData.DataBuf[0] ) ) //如果是发送给本设备的{ if( MC_SEND_MESS ls_CanRxData.DataBuf[1] ) //判断MESSAGETYPE{switch (ls_CanRxData.DataBuf[2]){case MC_WIHTE_BALANCE_START:{UpComCmdDP.CMD_TYPE UPM_WHITE_BLANCE_START; lu32_sta QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1);if(1 lu32_sta){APP_ACK2PC_CanTxQue(MC_WIHTE_BALANCE_START,0);}else{myprintf(DEBUG_UART,QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1) ERR\r\n);}}break;case MC_OPEN_LED:{UpComCmdDP.CMD_TYPE UPM_SET_TCS_LED_PWM_START;if(ls_CanRxData.DataBuf[3] 1){UpComCmdDP.u32Value 1;}else if(ls_CanRxData.DataBuf[3] 10){UpComCmdDP.u32Value 10;} else{UpComCmdDP.u32Value ls_CanRxData.DataBuf[3];}uint8_t lu8_val (uint8_t)UpComCmdDP.u32Value;// UpComCmdDP.u32Value MC_TCS_LED_INIT_PWM;lu32_sta QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1);if(1 lu32_sta){APP_ACK2PC_CanTxQue(MC_OPEN_LED,lu8_val);}else{myprintf(DEBUG_UART,QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1) ERR\r\n);} }break; case MC_CLOSE_LED:{UpComCmdDP.CMD_TYPE UPM_CLOSE_TCS_LED; UpComCmdDP.u32Value 0;lu32_sta QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1);if(1 lu32_sta){APP_ACK2PC_CanTxQue(MC_CLOSE_LED,0);}else{myprintf(DEBUG_UART,QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1) ERR\r\n);} }break; case MC_OPEN_RGB_DATAUP:{UpComCmdDP.CMD_TYPE UPM_OPEN_RGB_DATAUP; lu32_sta QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1);if(1 lu32_sta){APP_ACK2PC_CanTxQue(MC_OPEN_RGB_DATAUP,0);}else{myprintf(DEBUG_UART,QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1) ERR\r\n);} }break; case MC_CLOSE_RGB_DATAUP:{UpComCmdDP.CMD_TYPE UPM_CLOSE_RGB_DATAUP; lu32_sta QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1);if(1 lu32_sta){APP_ACK2PC_CanTxQue(MC_CLOSE_RGB_DATAUP,0);}else{myprintf(DEBUG_UART,QUEUE_StructIn(UpMachComCmdQue,UpComCmdDP,1) ERR\r\n);} }break; default:myprintf(DEBUG_UART,{ CAN_UPM: unknow DataBuf[2] 002 !!}\r\n); break;}} // else if( MC_ACK_MESS ls_CanRxData.DataBuf[1] ) //判断MESSAGETYPE// {// }// else if( MC_AUTO_UP ls_CanRxData.DataBuf[1] ) //判断MESSAGETYPE// {// } } }} //endof if(1 lu16_cnt) }//endof elsereturn 1;//1条指令解析成功入通讯命令队列
} 实验发现
10个节点全都能收到数据了。 备注 监听软件CANGAROO。 敬请期待 没来得及继续探究剩下的问题欢迎关注后面我会记录并更新我的程序更改和实验方案~ 关注我不迷路。