| 有人做出来了吗 |
| 就是主机发送的数据需要有地址 |
| 老哥做出来多机通信了吗? |
| 关于主从机,他是咋分配的 |
|
产品上用的部分程序,可以参考,modbus协议 /********485通讯接收处理*******/ void com_recv(void) { recv_ok=0; red_addr_flg=0; /*读寄存器功能码03H处理*/ if(recv_data[1]==0x03) //读寄存器(功能码03H)处理 { if((recv_data[0]==0)&&(recv_data[3]==17)) { red_addr_flg=1; } if((recv_data[0]!=0)||(red_addr_flg!=0))//地址不为0,或为0读地址 { send_data[0]=ADDR_s1; //本机地址 send_data[1]=0x03; //功能码 send_data[2]=recv_data[5]<<1; //字节数 send_count=send_data[2]; while(send_count!=0) { send_data[send_i+3]=(ram_data[recv_data[3]+send_j]&0xff00)>>8; //取变量高字节 send_i++; send_data[send_i+3]=ram_data[recv_data[3]+send_j]&0x00ff; //取变量低字节 send_i++; send_j++; send_count--; } CRC_string(send_data[2]+3); //发送数据串CRC校验 send_data[send_data[2]+3]=(CRC_data&0x00ff); //CRC校验码低字节 send_data[send_data[2]+4]=(CRC_data&0xff00)>>8; //CRC校验码高字节 send_count=send_data[2]+5; p1_6=1; //485设为输出 re_u0c1=0; //不允许接收 tx_count=1; send_count--; u0tb=send_data[0]; CRC_data=0xffff; send_i=0; send_j=0; red_addr_flg=0; } else { re_u0c1=1; //允许串口接收 } } else { if((status.stu.far_near==1)&&(recv_data[0]!=0)) //为远程和地址不为0才能设置 { /*功能码10H处理*/ if(recv_data[1]==0x10) //写寄存器(功能码10H)处理 { /********10H功能给主机返馈***********/ send_data[0]=ADDR_s1; //本机地址 send_data[1]=0x10; //功能码 send_data[2]=recv_data[2]; //变量起始地址高字节 send_data[3]=recv_data[3]; //变量起始地址低字节 send_data[4]=recv_data[4]; //变量个数高字节 send_data[5]=recv_data[5]; //变量个数低字节 CRC_string(6); //发送数据串CRC校验 send_data[6]=(CRC_data&0x00ff); //CRC校验码低字节 send_data[7]=(CRC_data&0xff00)>>8;//CRC校验码高字节 p1_6=1; //485设为输出 re_u0c1=0; //不允许接收 tx_count=1; //指向第二个字节 send_count=7; //后续字节在发送中断中发 u0tb=send_data[0]; //发第一个字节 CRC_data=0xffff; /**************************************/ /**********装载收到的数据*************/ load_count=recv_data[5];//变量个数 send_i=7; //recv_data[7]开始为数据 while(load_count!=0) { ram_data[recv_data[3]+send_j]=recv_data[send_i]<<8; send_i++; ram_data[recv_data[3]+send_j]=ram_data[recv_data[3]+send_j]|recv_data[send_i]; send_i++; send_j++; load_count--; } ram_data[1]=status.stus;//状态不能写 if((ram_data[16]==0x0008)||(ram_data[16]==0x0009)||(ram_data[16]==0x000a)) { ram_data[16]=0x0008; } send_i=0; send_j=0; //time_spke=0; //声音延时时间清零 //delay_spke_flg=1; //声音延时标志 } } re_u0c1=1; //允许串口接收 } } |
honey_teck 发表于 2019-6-5 17:10 第二个方法不好实现,会出现多个从机同时发的冲突。 |
|
多机通讯需要一个可靠的协议: 可以参考其他通讯的协议,自己给他搞个简单的协议。 比如你这个可以这样定义。 主机发送:命令+地址+校验。等待对应的地址进行返回。 从机返回:地址+数据+校验。 例如:主机发送0a(cmd)+01(address)+0b(sum) //采用简单的求和,也可以采用其他的检验方式) address的从机发送:01(address)+88(数据)+89(sum)。 其他地址的从机不处理。 这个只是最简单的一种协议,当然可以拓展成更复杂的。 通过CMD可以对从机决心参数设定,校准等待。 仅供参考。 |
| 学习了,谢谢楼主,太棒了 |
honey_teck 发表于 2019-6-5 17:10 谢谢。这个流程就是地址确认,然后再传输数据,大方向我能理解,但是细节的代码部分,漏洞百出 。请问一下,中断方式是第一种方法还是第二种方法? |
涛涛涛涛12138 发表于 2019-6-5 13:13 没有欸 |
| 我做过这个相关的仿真,多从机的,实在不行你加我的QQ 1014461948 |
| 一对多通信,那么就有地址问题,将从机编号啊,按你的图,你就将从机编为1号和3号。现在你要改的是通信程序,有两种方法:主机发起,从机响应。二、从机定时上传,主机接收。你来决定用哪一个方法。主机发起,从机响应的思路是这样的:你需要定义一个帧结构,至少要包含从机地址。比如说,你定义一个两字节的帧,第一个字节表示地址,如1,第二个字节表示命令。那么从机接收到这两个字节后,各自判读,如果1号机读到后响应返回温度值,那么主机就读到了啊,由于是1号机,2号机其实也读到了相同的命令,由于地址不对,所以2号机不响应。定时响应的方法,你自己思考一下 |
| 你有完成的程序吗?我也在做一个多机通行的设计,怎么实现无线远程的多机通信? |