您的位置 首页 软件

嵌入式体系使用中完成RS485的方向切换

RS485总线是工业应用中非常成熟的技术,是现代通信技术的工业标准之一。RS485总线用于多站互连十分方便,用一对双绞线即可实现,采用平衡发送和差分接收,即在发送端驱动器将TTL电平信号转换成差分信号

  RS485总线是工业运用中十分老练的技能,是现代通讯技能的工业规范之一。RS485总线用于多站互连十分便利,用一对双绞线即可完结,选用平衡发送和差分接纳,即在发送端驱动器将TTL电平信号转换成差分信号输出,在接纳端接纳器将差分信号变成TTL电平,因而具有抗共模搅扰的才干。依据RS485规范,传送数据速率达100 kb/s时通讯间隔可达1200 m。

  RS485在嵌入式体系中的运用十分广泛。嵌入式体系能够经过RS485接口来操控终端设备。因为RS485是半双工形式,因而发送和接纳的方向切换需求咱们的重视和研讨。假如方向切换办法挑选欠好或许会导致RS485驱动才干下降、软件履行功率下降,乃至导致体系反常等问题。

  本文别离给出硬件完结RS485方向切换和软件完结RS485方向切换两种办法。两种办法各有长处,硬件办法操控起来比较简略。软件办法的驱动才干更好,可是和嵌入式渠道联系比较亲近,不同的渠道都需求调试和验证。

  1 硬件办法操控RS485方向

  图1所示为硬件操控RS485的电路图。电路中运用2N7002LT1G MOS场效晶体管把UART_TXD_485这个MCU输出的RS485发送信号逻辑取反后送给RS485芯片的RE/DE PIN脚。操控的原理是,当UART_TXD_485输出低电平时RS485芯片的DE使能;输出高电平时RE使能。默许状况下UART_TXD_485是高电平,RS485芯片处于接纳状况。发送数据时,UART_TXD_485上面有凹凸电平信号改变,低电平信号经过RS485芯片SP3072EENL/TR直接输出,高电平信号经过外部上下拉电阻来操控。

  这种办法的长处是操控简略,软件不需求做额定的作业,操控RS485像操控RS232相同。可是这种办法的缺陷是驱动才干或许缺乏,因为这种操控办法没有彻底发挥出RS485驱动芯片自身的驱动才干,输出信号依赖于外部上下拉电阻,因而在杂乱环境下,比如许多负载需求操控时,就会存在驱动才干缺乏的问题。可是在一些简略的环境或许软件完结较杂乱的渠道下,运用这种办法仍是切实可行的。

  

  图1 硬件操控RS485电路图

  2 软件办法操控RS485方向

  2.1 驱动才干剖析

  在杂乱的RS485操控环境下,用上面介绍的硬件办法来操控RS485的方向会存在比较杰出的驱动才干缺乏的问题。修正上述操控办法,将TTL这一侧的2线操控改为3线操控,便是将收发操控信号不必当时的/TXD来操控,而从主控分出一根GPIO线来操控收发。

  依照输出电流核算,3线操控办法相对用2线操控的总线上下拉作为输出的办法,其驱动才干进步了25~50倍(不同厂家不同类型有差异),假如辅以终端电阻灵敏装备的办法,RS485的驱动才干将彻底不是问题。表1是两种操控办法驱动才干的比照。

  2.2 软硬件环境

  

  图2 软件操控办法中的硬件规划

  软件操控办法选用图2的硬件规划,图中很杰出的修正是运用MCU的GPIO来操控RE和DE.RS485芯片的供电选用5 V供电,进步驱动才干。RS485芯片的RE和DE操控运用MCU的GPIO输出凹凸电平来操控。简略来说便是,在RS485进行数据传输时,经过GPIO来操控传输方向。这儿选用的MCU是TI公司的DM8168处理器来完结软件的RS485切换功用。软件版别运用UBoot2010.06和linux2.6.37。用软件来完结RS485的收发,尽量要确保履行功率;要到达上面的意图就需求对串口驱动进行调试,运用串口驱动用到的软件资源和串口操控器自身的硬件资源来完结RS485的操控。

  表1 软件和硬件操控办法驱动才干的比照

  

  2.3 UBoot代码修正

  需求修正的文件:

  ① board/ti/ti8168/evm.c

  ② drivers/serial/ns16550.c

  ③ include/configs/ti8168_evm.h

  ti8168_evm.h文件中添加切换宏界说:

  #define CONFIG_RS485_DIR_SW 1

  evm.c文件中添加切换函数:

  void rs485_dir_sw(int rs485_dir){

  if (rs485_dir ==0)

  _raw_writel(RS485_DIR_MASK, TI81XX_GPIO1_CLEARDATAOUT);

  else

  _raw_writel(RS485_DIR_MASK, TI81XX_GPIO1_SETDATAOUT);

  }

  s16550.c串口驱动文件中添加RS485方向操控:

  void NS16550_putc(NS16550_t com_port, char c){

  #ifdef CONFIG_RS485_DIR_SW

  rs485_dir_sw(1);

  #endif

  ……//此处代码省掉

  #ifdef CONFIG_RS485_DIR_SW

  while((serial_in(&com_port->lsr) & UART_LSR_TEMT) == 0)

  rs485_dir_sw(0);

  #endif

  }

  其间UART_LSR_TEMT表明发送BUF和移位寄存器为空。默许状况下RS485是接纳状况,一旦要发送数据,就把RS485切换为发送状况。发送完数据后,等候发送BUF和移位寄存器为空,然后切换回接纳状况,这儿无需运用timeout。

  2.4 Linux代码修正

  需求修正的文件:

  ① arch/arm/machomap2/bordti8168evm.c

  ② drivers/serial/omapserial.c

  ③ include/linux/serial_core.h

  serial_core.h文件,uart_port结构体中添加set_rs485_direction函数指针,用于履行RS485的方向切换void (*set_rs485_direction)(int rs485_dir);本来考虑在uart_ops结构体中添加的,可是这个结构体是常量类型,对它不作改动,因而加到了uart_port结构体中。在该文件中添加相关宏界说和函数指针类型用于函数注册:

  #define SET_RS485_RX0

  #define SET_RS485_TX1

  typedef void (*set_rs485_direction_t)(int rs485_dir);//用于函数注册

  omapserial.c文件首要做了如下几点改动:

  ① 添加omap_rs485_dir_fun大局的函数指针。

  static set_rs485_direction_t omap_rs485_dir_fun[OMAP_MAX_HSUART_PORTS]={NULL, NULL, NULL, NULL, NULL, NULL}

  ② 外部驱动运用omap_rs485_dir_fun_reg注册函数对omap_rs485_dir_fun进行赋值。

  void omap_rs485_dir_fun_reg(int port_num, set_rs485_direction_t rs485_dir_fun){

  if (port_num>=OMAP_MAX_HSUART_PORTS)

  printk(KERN_ERR “%s, port_num error max is %d, but %d \”, __FUNCTION__, OMAP_MAX_HSUART_PORTS-1, port_num);

  omap_rs485_dir_fun[port_num]= rs485_dir_fun;

  }

  EXPORT_SYMBOL(omap_rs485_dir_fun_reg);

  ③ serial_omap_probe函数中对操控程序中用到的up->port.set_rs485_direction进行赋值。

  up->port.set_rs485_direction= omap_rs485_dir_fun[pdev->id];

  ④ 默许状况下RS485处于接纳状况。

  ⑤ serial_omap_enable_ier_thri函数中把RS485切换为发送状况。

  static incline void serial_omap_enable_ier_thri(struct uart_omap_port *up){

  if (!(up->ier & UART_IER_THRI)) {

  /* rs485 dir change to tx */

  if (up->port.set_rs485_direction != NULL)

  up->port.set_rs485_direction(SET_RS485_TX);

  ……//此处代码省掉

  }

  }

  ⑥ serial_omap_stop_tx函数中把RS485切换为接纳状况。

  static void serial_omap_stop_tx(struct uart_omap_port *port){

  ……//此处代码省掉

  if (up->ier & UART_IER_THRI) {

  up->ier &= ~UART_IER_THRI;

  serial_out(up, UART_IER, up->ier);

  /* rs485 dir change to rx */

  if (port->set_rs485_direction != NULL)

  port->set_rs485_direction(SET_RS485_RX);

  }

  }

  ⑦ transmit_chars更改一下,原先的代码是当没有更多的字符要发送(环形缓冲为空)时需求封闭发送中止,这时串口操控器发送BUF和移位寄存器中仍是有数据的,这些数据串口操控器主动发送完结后才算完毕,因为现已封闭了发送中止,因而发送完毕后就没有中止发生了。可是RS485切换方向需求比及彻底发送完结后才干进行。因而对transmit_chars函数做了修正。调用serial_omap_stop_tx函数前判别发送BUF和移位寄存器是否为空,假如为空就能够切换方向了。简而言之,拖延了发送中止的封闭时刻。

  static void transmit_chars(struct uart_omap_port *up){

  ……//此处代码省掉

  if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {

  if (up->port.ops->tx_empty(&up->port)==0)

  return;//added for last transmit

  serial_omap_stop_tx(&up->port);

  return;

  }

  ……//此处代码省掉

  if (uart_circ_empty(xmit)) {

  if (up->port.ops->tx_empty(&up->port)==0)

  return;//added for last transmit

  serial_omap_stop_tx(&up->port);

  }

  }

  ⑧ arch/arm/machomap2/boardti8168evm.c文件在ti8168_evm_init函数中调用omap_rs485_dir_fun_reg函数注册RS485切换函数。

  2.5 试验成果剖析

  上述软件修正有如下几个长处:不添加硬件开支;不添加和运用任何硬件资源;不添加软件开支;不影响软件履行功率;硬件操控是电信号操控,方向切换和TX绑定;软件操控是整个发送缓冲区完结发送后再进行方向切换,操控完结上愈加合理。

  对软件切换RS485做了根本的测验,状况如下:

  ① 操控台操作。整个发动打印信息正常。UBoot和Kernel下操控作用和硬件操控相同,能够很流畅地进行指令的输入和回显,串口终端添加输入字符间的延时后能够进行装备的张贴。内核在115 200和38 400下别离进行测验OK。

  ② 内核下加大担任进行大数据量的发送。添加负载,开多个ping包进程(发生许多中止)、Nand Flash的操作、CPU占有率挨近100%条件下,经过RS485输出许多数据,没有乱码,校验OK。

  ③ 极高的实时性。

  因为本文给出的软件完结办法是根据Linux内核完结的,因而很好地确保了方向操控的实时性。实践成果显现,DM8168数据发送完结到发生方向操控信号之间的时刻在25 μs左右,简直能够忽略不计。而有些规划在用户空间运用运用程序进行方向切换的办法会导致20 ms以上的延时,导致了一系列反常问题的发生。

  结语

本文详细描述了RS485方向操控的硬件和软件两种完结办法。两种操控办法各有特点,硬件操控办法完结简略,不需求软件干涉,对软件而言RS485串口收发就像RS232相同简略。软件操控办法能够极大地进步整个RS485线路的驱动才干,本文给出的根据Linux内核的操控办法又很好地确保了RS485方向切换的实时性,满意了有用性要求。这两种办法在许多场合现已得到了很好的运用和验证。特别是软件完结办法,能够扩

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/ruanjian/244347.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部