linux rs485 方向切换,嵌入式系统应用中实现RS485的方向切换

2.3UBoot代码修改

需要修改的文件:

①board/ti/ti8168/evm.c

②drivers/serial/ns16550.c

③include/configs/ti8168_evm.h

ti8168_evm.h文件中增加切换宏定义:

#defineCONFIG_RS485_DIR_SW1

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

voidrs485_dir_sw(intrs485_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方向控制:

voidNS16550_putc(NS16550_tcom_port,charc){

#ifdefCONFIG_RS485_DIR_SW

rs485_dir_sw(1);

#endif

……//此处代码省略

#ifdefCONFIG_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.4Linux代码修改

需要修改的文件:

①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)(intrs485_dir);原本考虑在uart_ops结构体中增加的,但是这个结构体是常量类型,对它不作改动,因此加到了uart_port结构体中。在该文件中添加相关宏定义和函数指针类型用于函数注册:

#defineSET_RS485_RX0

#defineSET_RS485_TX1

typedefvoid(*set_rs485_direction_t)(intrs485_dir);//用于函数注册

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

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

staticset_rs485_direction_tomap_rs485_dir_fun[OMAP_MAX_HSUART_PORTS]={NULL,NULL,NULL,NULL,NULL,NULL}

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

voidomap_rs485_dir_fun_reg(intport_num,set_rs485_direction_trs485_dir_fun){

if(port_num>=OMAP_MAX_HSUART_PORTS)

printk(KERN_ERR"%s,port_numerrormaxis%d,but%d\\n",__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切换为发送状态。

staticinclinevoidserial_omap_enable_ier_thri(structuart_omap_port*up){

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

/*rs485dirchangetotx*/

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

up->port.set_rs485_direction(SET_RS485_TX);

……//此处代码省略

}

}

⑥serial_omap_stop_tx函数中把RS485切换为接收状态。

staticvoidserial_omap_stop_tx(structuart_omap_port*port){

……//此处代码省略

if(up->ier&UART_IER_THRI){

up->ier&=~UART_IER_THRI;

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

/*rs485dirchangetorx*/

if(port->set_rs485_direction!=NULL)

port->set_rs485_direction(SET_RS485_RX);

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值