www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀] RS485總線是工業(yè)應(yīng)用中非常成熟的技術(shù),是現(xiàn)代通信技術(shù)的工業(yè)標(biāo)準(zhǔn)之一。RS485總線用于多站互連十分方便,用一對(duì)雙絞線即可實(shí)現(xiàn),采用平衡發(fā)送和差分接收,即在發(fā)送端驅(qū)動(dòng)器將TTL電平信號(hào)轉(zhuǎn)換成差分信號(hào)

RS485總線是工業(yè)應(yīng)用中非常成熟的技術(shù),是現(xiàn)代通信技術(shù)的工業(yè)標(biāo)準(zhǔn)之一。RS485總線用于多站互連十分方便,用一對(duì)雙絞線即可實(shí)現(xiàn),采用平衡發(fā)送和差分接收,即在發(fā)送端驅(qū)動(dòng)器將TTL電平信號(hào)轉(zhuǎn)換成差分信號(hào)輸出,在接收端接收器將差分信號(hào)變成TTL電平,因此具有抗共模干擾的能力。根據(jù)RS485標(biāo)準(zhǔn),傳送數(shù)據(jù)速率達(dá)100 kb/s時(shí)通信距離可達(dá)1200 m。

RS485在嵌入式系統(tǒng)中的應(yīng)用非常廣泛。嵌入式系統(tǒng)可以通過RS485接口來控制終端設(shè)備。由于RS485是半雙工模式,因此發(fā)送和接收的方向切換需要我們的關(guān)注和研究。如果方向切換方式選擇不好可能會(huì)導(dǎo)致RS485驅(qū)動(dòng)能力下降、軟件執(zhí)行效率下降,甚至導(dǎo)致系統(tǒng)異常等問題。

本文分別給出硬件實(shí)現(xiàn)RS485方向切換和軟件實(shí)現(xiàn)RS485方向切換兩種方式。兩種方式各有優(yōu)點(diǎn),硬件方式控制起來比較簡(jiǎn)單。軟件方式的驅(qū)動(dòng)能力更好,但是和嵌入式平臺(tái)關(guān)系比較密切,不同的平臺(tái)都需要調(diào)試和驗(yàn)證。


1 硬件方式控制RS485方向


圖1所示為硬件控制RS485的電路圖。電路中使用2N7002LT1G MOS場(chǎng)效晶體管把UART_TXD_485這個(gè)MCU輸出的RS485發(fā)送信號(hào)邏輯取反后送給RS485芯片的RE/DEPIN腳??刂频脑硎?,當(dāng)UART_TXD_485輸出低電平時(shí)RS485芯片的DE使能;輸出高電平時(shí)RE使能。默認(rèn)情況下UART_TXD_485是高電平,RS485芯片處于接收狀態(tài)。發(fā)送數(shù)據(jù)時(shí),UART_TXD_485上面有高低電平信號(hào)變化,低電平信號(hào)通過RS485芯片SP3072EENL/TR直接輸出,高電平信號(hào)通過外部上下拉電阻來控制。

  

但是這種方法的缺點(diǎn)是驅(qū)動(dòng)能力可能不足,由于這種控制方法沒有完全發(fā)揮出RS485驅(qū)動(dòng)芯片自身的驅(qū)動(dòng)能力,輸出信號(hào)依賴于外部上下拉電阻,因此在復(fù)雜環(huán)境下,譬如很多負(fù)載需要控制時(shí),就會(huì)存在驅(qū)動(dòng)能力不足的問題。但是在一些簡(jiǎn)單的環(huán)境或者軟件實(shí)現(xiàn)較復(fù)雜的平臺(tái)下,使用這種方法還是切實(shí)可行的。

  

圖1 硬件控制RS485電路圖


2 軟件方式控制RS485方向


2.1 驅(qū)動(dòng)能力分析


在復(fù)雜的RS485控制環(huán)境下,用上面介紹的硬件方式來控制RS485的方向會(huì)存在比較突出的驅(qū)動(dòng)能力不足的問題。修改上述控制方法,將TTL這一側(cè)的2線控制改為3線控制,就是將收發(fā)控制信號(hào)不用當(dāng)前的/TXD來控制,而從主控分出一根GPIO線來控制收發(fā)。

  

其驅(qū)動(dòng)能力提高了25~50倍(不同廠家不同型號(hào)有差異),如果輔以終端電阻靈活配置的措施,RS485的驅(qū)動(dòng)能力將完全不是問題。表1是兩種控制方式驅(qū)動(dòng)能力的對(duì)比。


2.2 軟硬件環(huán)境

  


圖2 軟件控制方法中的硬件設(shè)計(jì)


軟件控制方法采用圖2的硬件設(shè)計(jì),圖中很突出的修改是使用MCU的GPIO來控制RE和DE.RS485芯片的供電采用5 V供電,提高驅(qū)動(dòng)能力。RS485芯片的RE和DE控制使用MCU的GPIO輸出高低電平來控制。簡(jiǎn)單來說就是,在RS485進(jìn)行數(shù)據(jù)傳輸時(shí),通過GPIO來控制傳輸方向。這里采用的MCU是TI公司的DM8168處理器來實(shí)現(xiàn)軟件的RS485切換功能。軟件版本使用UBoot2010.06和linux2.6.37。用軟件來實(shí)現(xiàn)RS485的收發(fā),盡量要保證執(zhí)行效率;要達(dá)到上面的目的就需要對(duì)串口驅(qū)動(dòng)進(jìn)行調(diào)試,使用串口驅(qū)動(dòng)用到的軟件資源和串口控制器本身的硬件資源來實(shí)現(xiàn)RS485的控制。


表1 軟件和硬件控制方式驅(qū)動(dòng)能力的對(duì)比

  


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文件中增加切換函數(shù):

  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串口驅(qū)動(dòng)文件中增加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表示發(fā)送BUF和移位寄存器為空。默認(rèn)情況下RS485是接收狀態(tài),一旦要發(fā)送數(shù)據(jù),就把RS485切換為發(fā)送狀態(tài)。發(fā)送完數(shù)據(jù)后,等待發(fā)送BUF和移位寄存器為空,然后切換回接收狀態(tài),這里無需使用timeout。



2.4 Linux代碼修改

需要修改的文件:

 ?、?arch/arm/machomap2/bordti8168evm.c

 ?、?drivers/serial/omapserial.c

 ?、?include/linux/serial_core.h



serial_core.h文件,UART_port結(jié)構(gòu)體中增加set_rs485_direction函數(shù)指針,用于執(zhí)行RS485的方向切換void (*set_rs485_direction)(int rs485_dir);原本考慮在uart_ops結(jié)構(gòu)體中增加的,但是這個(gè)結(jié)構(gòu)體是常量類型,對(duì)它不作改動(dòng),因此加到了uart_port結(jié)構(gòu)體中。在該文件中添加相關(guān)宏定義和函數(shù)指針類型用于函數(shù)注冊(cè):

  #define SET_RS485_RX0

  #define SET_RS485_TX1

  typedef void (*set_rs485_direction_t)(int rs485_dir);//用于函數(shù)注冊(cè)

  omapserial.c文件主要做了如下幾點(diǎn)改動(dòng):

 ?、?添加omap_rs485_dir_fun全局的函數(shù)指針。

  statICset_rs485_direction_t omap_rs485_dir_fun[OMAP_MAX_HSUART_PORTS]={NULL, NULL, NULL, NULL, NULL, NULL}

 ?、?外部驅(qū)動(dòng)利用omap_rs485_dir_fun_reg注冊(cè)函數(shù)對(duì)omap_rs485_dir_fun進(jìn)行賦值。

  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 \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函數(shù)中對(duì)控制程序中用到的up->port.set_rs485_direction進(jìn)行賦值。

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

 ?、?默認(rèn)情況下RS485處于接收狀態(tài)。

 ?、?serial_omap_enable_ier_thri函數(shù)中把RS485切換為發(fā)送狀態(tài)。

  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函數(shù)中把RS485切換為接收狀態(tài)。

  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更改一下,原先的代碼是當(dāng)沒有更多的字符要發(fā)送(環(huán)形緩沖為空)時(shí)需要關(guān)閉發(fā)送中斷,這時(shí)串口控制器發(fā)送BUF和移位寄存器中還是有數(shù)據(jù)的,這些數(shù)據(jù)串口控制器自動(dòng)發(fā)送完成后才算結(jié)束,由于已經(jīng)關(guān)閉了發(fā)送中斷,因此發(fā)送結(jié)束后就沒有中斷產(chǎn)生了。但是RS485切換方向需要等到完全發(fā)送完成后才能進(jìn)行。因此對(duì)transmit_chars函數(shù)做了修改。調(diào)用serial_omap_stop_tx函數(shù)前判斷發(fā)送BUF和移位寄存器是否為空,如果為空就可以切換方向了。簡(jiǎn)而言之,延后了發(fā)送中斷的關(guān)閉時(shí)間。

  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函數(shù)中調(diào)用omap_rs485_dir_fun_reg函數(shù)注冊(cè)RS485切換函數(shù)。

  2.5 實(shí)驗(yàn)結(jié)果分析

  上述軟件修改有如下幾個(gè)優(yōu)點(diǎn):不增加硬件開銷;不增加和使用任何硬件資源;不增加軟件開銷;不影響軟件執(zhí)行效率;硬件控制是電信號(hào)控制,方向切換和TX綁定;軟件控制是整個(gè)發(fā)送緩沖區(qū)完成發(fā)送后再進(jìn)行方向切換,控制實(shí)現(xiàn)上更加合理。

  對(duì)軟件切換RS485做了基本的測(cè)試,情況如下:

 ?、?控制臺(tái)操作。整個(gè)啟動(dòng)打印信息正常。UBoot和Kernel下控制效果和硬件控制一樣,可以很流暢地進(jìn)行命令的輸入和回顯,串口終端增加輸入字符間的延時(shí)后可以進(jìn)行配置的粘貼。內(nèi)核在115 200和38 400下分別進(jìn)行測(cè)試OK。

 ?、?內(nèi)核下加大負(fù)責(zé)進(jìn)行大數(shù)據(jù)量的發(fā)送。增加負(fù)載,開多個(gè)PINg包進(jìn)程(產(chǎn)生大量中斷)、Nand Flash的操作、CPU占有率接近100%條件下,通過RS485輸出大量數(shù)據(jù),沒有亂碼,校驗(yàn)OK。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

在工業(yè)物聯(lián)網(wǎng)設(shè)備部署中,Modbus通信故障是導(dǎo)致系統(tǒng)停機(jī)的首要原因之一。據(jù)統(tǒng)計(jì),超過60%的現(xiàn)場(chǎng)問題源于通信配置錯(cuò)誤或數(shù)據(jù)解析異常。本文從嵌入式系統(tǒng)開發(fā)視角,系統(tǒng)闡述Modbus通信調(diào)試的方法論,結(jié)合實(shí)際案例解析如何高...

關(guān)鍵字: 嵌入式系統(tǒng) Modbus通信

在嵌入式系統(tǒng)開發(fā)中,看門狗(Watchdog Timer, WDT)是保障系統(tǒng)可靠性的核心組件,其初始化時(shí)機(jī)的選擇直接影響系統(tǒng)抗干擾能力和穩(wěn)定性。本文從硬件架構(gòu)、軟件流程、安全規(guī)范三個(gè)維度,系統(tǒng)分析看門狗初始化的最佳實(shí)踐...

關(guān)鍵字: 單片機(jī) 看門狗 嵌入式系統(tǒng)

人工智能(AI)和機(jī)器學(xué)習(xí)(ML)是使系統(tǒng)能夠從數(shù)據(jù)中學(xué)習(xí)、進(jìn)行推理并隨著時(shí)間的推移提高性能的關(guān)鍵技術(shù)。這些技術(shù)通常用于大型數(shù)據(jù)中心和功能強(qiáng)大的GPU,但在微控制器(MCU)等資源受限的器件上部署這些技術(shù)的需求也在不斷增...

關(guān)鍵字: 嵌入式系統(tǒng) 人工智能 機(jī)器學(xué)習(xí)

Zephyr開源項(xiàng)目由Linux基金會(huì)維護(hù),是一個(gè)針對(duì)資源受限的嵌入式設(shè)備優(yōu)化的小型、可縮放、多體系結(jié)構(gòu)實(shí)時(shí)操作系統(tǒng)(RTOS)。近年來,Zephyr RTOS在嵌入式開發(fā)中的采用度逐步增加,支持的開發(fā)板和傳感器不斷增加...

關(guān)鍵字: 嵌入式系統(tǒng) 軟件開發(fā) 實(shí)時(shí)操作系統(tǒng) Zephyr項(xiàng)目

在資源受限的嵌入式系統(tǒng)中,代碼執(zhí)行效率和內(nèi)存占用始終是開發(fā)者需要權(quán)衡的核心問題。內(nèi)聯(lián)函數(shù)(inline functions)和宏(macros)作為兩種常見的代碼展開技術(shù),在性能、可維護(hù)性和安全性方面表現(xiàn)出顯著差異。本文...

關(guān)鍵字: 內(nèi)聯(lián)函數(shù) 嵌入式系統(tǒng)

在嵌入式系統(tǒng)和服務(wù)器開發(fā)中,日志系統(tǒng)是故障排查和運(yùn)行監(jiān)控的核心組件。本文基于Linux環(huán)境實(shí)現(xiàn)一個(gè)輕量級(jí)C語言日志庫,支持DEBUG/INFO/WARN/ERROR四級(jí)日志分級(jí),并實(shí)現(xiàn)按大小滾動(dòng)的文件輪轉(zhuǎn)機(jī)制。該設(shè)計(jì)在某...

關(guān)鍵字: C語言 嵌入式系統(tǒng)

在嵌入式系統(tǒng)和底層驅(qū)動(dòng)開發(fā)中,C語言因其高效性和可控性成為主流選擇,但缺乏原生單元測(cè)試支持成為開發(fā)痛點(diǎn)。本文提出一種基于宏定義和測(cè)試用例管理的輕量級(jí)單元測(cè)試框架方案,通過自定義斷言宏和測(cè)試注冊(cè)機(jī)制,實(shí)現(xiàn)無需外部依賴的嵌入...

關(guān)鍵字: C語言 嵌入式系統(tǒng) 驅(qū)動(dòng)開發(fā)

在嵌入式系統(tǒng)與驅(qū)動(dòng)開發(fā)中,內(nèi)存映射I/O(Memory-Mapped I/O, MMIO)是一種將硬件寄存器映射到處理器地址空間的技術(shù),允許開發(fā)者通過指針直接讀寫寄存器,實(shí)現(xiàn)高效、低延遲的硬件控制。本文通過C語言實(shí)戰(zhàn)案例...

關(guān)鍵字: 內(nèi)存映射 I/O操作 嵌入式系統(tǒng)

在嵌入式系統(tǒng)開發(fā)和多線程編程中,程序崩潰、內(nèi)存越界等復(fù)雜問題常令開發(fā)者困擾。GDB作為強(qiáng)大的調(diào)試工具,其條件斷點(diǎn)和內(nèi)存查看功能可精準(zhǔn)定位隱蔽缺陷。本文通過實(shí)際案例演示這些高級(jí)功能的應(yīng)用,幫助開發(fā)者提升調(diào)試效率。

關(guān)鍵字: GDB 嵌入式系統(tǒng)
關(guān)閉