完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
英创Linux主板可以通过RS485总线挂载多个单片机组成多机系统,如图1所示,其中Linux主机作为上位机,单片机作为从机,485总线最多能挂载256个从机。系统工作的时候,每一个从机都有自己的地址(从机号),上位机首先发送从机的地址,再发送命令/数据,其发送的命令/数据可以被每一个从机接收,从机收到命令和数据后,如果地址和自己的相符,就进行应答。 图1 Linux主机与单片机组成的多机系统 图2 多机通信帧格式 单片机每收到一个字节都要产生中断,在一般情况下,当Linux主机向从机1发送数据的时候,从机2、3在每一个字节都要产生中断,不论传输的是地址还是数据,也不论是不是跟自己通信。当从机设备比较多、传输数据比较频繁的时候,单片机的负载将大大增加,影响正常的工作。 比较通用的解决办法是充分利用串口固定校验位(Parity Stick)的功能,使用Mark/Space校验位区分地址和数据,如图2所示的多机通信帧中,发送和接收地址字节时,可以使用Mark校验(也可以使用Space校验),发送和接收数据字节时,使用Space校验(也可以使用Mark校验)。系统初始化的时候,所有的从机都设置成Mark校验,进入等待状态。主机发送第一个字节(addr = 从机1)的时候使用Mark校验。这时,所有的从机都收到了addr,并通过校验产生中断。在从机的中断程序中,如果addr和自己的地址相符,就将从机设置成Space校验(从机1),否则,继续保持Mark校验(从机2、3)。紧接着,主机发送data1、data2的时候使用Space校验,这时,由于从机2、3不能通过Space校验,将不会产生中断,只有从机1会产生中断,应答主机。这样就大大降低了处于等待状态的从机2、3的中断负载。 对Linux目前的串口驱动程序而言,在逻辑上应用程序可以先设置一次Mark校验位,write一个地址字节,再设置一次Space校验,接着write多个数据字节来实现多机通信。但是,两次调用write之间可能会有较大的时间间隙,导致单片机接收数据超时,多机通信失败。为此,英创公司专门修改了Linux串口驱动程序,在不增加新的API调用的前提下,只需要在应用程序中连续两次设置校验位即可使串口驱动进入ADDR_DATA_MODE模式,支持Mark/Space多机通信,并且将同一帧数据的addr、data连续发送出去(应用程序只调用一次write函数)。应用程序具体步骤如下(为方便校验位设置,编写了一个校验位设置函数): 1、校验位设置函数 int CSerial::SetParity(int parity) { struct termios new_opt; int status; unsigned int old_ccflag;
tcgetattr(m_fd,&new_opt); old_ccflag = new_opt.c_cflag;
new_opt.c_cflag &= ~PARODD ; new_opt.c_cflag &= ~CMSPAR ;
if(parity == 0) { //使用Space校验 标记数据 new_opt.c_cflag |= PARENB | CS8 | CMSPAR; } else if(parity == 1) { //使用Mark校验 标记地址 new_opt.c_cflag |= PARENB | CS8 | CMSPAR | PARODD; } else if(parity == 2) { //使用偶校验 new_opt.c_cflag |= PARENB; /* Enable parity */ new_opt.c_cflag &= ~PARODD; /* 转换为偶效验*/ } else if(parity == 3) { //使用奇校验 new_opt.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ } else { new_opt.c_cflag = old_ccflag; } status = tcsetattr(m_fd,TCSANOW,&new_opt); return status; } 2、主程序两次调用校验位设置函数,进入ADDR_DATA_MODE模式 Buf[0] = 0x39; Buf[1] = 0xC1; Buf[2] = 0x80; Buf[3] = 0x1; Buf[4] = 0x0;
//连续两次设置校验位,进入ADDR_DATA_MODE. //先设置数据使用的校验位,后设置地址使用的校验位 m_Serial.SetParity(0); //数据使用space校验 m_Serial.SetParity(1); //地址使用mark校验 sleep(1); m_Serial.WritePort( Buf, 5 ); 如上程序将5个字节一起发送出去,其中Buf[0]作为地址,使用mark校验,Buf[1-4]作为数据,使用space校验,波形如图3所示。所有从机收到地址后,都通过校验位,产生中断,但仅地址为0x39的从机会将自己的校验位设置为0。之后Buf[1-4]仅有从机0x39能够产生接收中断,应答主机。 发送完这5个字节后,就退出了ADDR_DATA_MODE模式,继续串口发送的所有字节都使用space校验(先设置的校验位)。如果需要其他校验方式,可以调用SetParity()进行设置。 图3 ADDR_DATA_MODE发送波形图 有兴趣的客户可以与我们联系,我们会提供驱动和测试应用程序。 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 18:36 , Processed in 0.770823 second(s), Total 56, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号