Rockchip USB转485
#RS232 / RS485 ?簡介
#RS232
#RS485
#R485與RS232比較
#開發
#DTS配置
#驅動開發
#POSIX規范API
#HAL層以上APP層
#APK call JNI
#APP
#調試
#log開啟
#RS232/RS485/RS422常見問題
#RS232 / RS485 ?簡介
#RS232
RS-232是美國電子工業聯盟(EIA)制定的串行數據通信的接口標準,原始編號全稱是EIA-RS-232(簡稱232,RS232)。它被廣泛用于計算機串行接口外設連接。RS-232C標準,其中EIA(Electronic Industry Association)代表美國電子工業聯盟,RS(Recommended standard)代表推薦標準,232是標識號,C代表RS232的第三次修改(1969年),在這之前,還有RS232B、RS232A. 在RS-232標準中,字符是以一串行的比特串來一個接一個的串列(serial)方式傳輸,優點是傳輸線少,配線簡單,發送距離可以較遠。最常用的編碼格式是異步起停(asynchronous start-stop)格式,它使用一個起始比特后面緊跟7或8個數據比特(bit),然后是可選的奇偶校驗比特,最后是一或兩個停止比特。所以發送一個字符至少需要10比特,帶來的一個好的效果是使全部的傳輸速率,發送信號的速率以10劃分。
表中列出的是被較多使用的RS-232中的信號和管腳分配:
DE-9 Male(Pin Side) DE-9 Female (Pin Side)------------- -------------\ 1 2 3 4 5 / \ 5 4 3 2 1 /\ 6 7 8 9 / \ 9 8 7 6 /--------- ---------| 公共接地 | 7 | 5 | 4 | 4,5 |
| 發送數據(TD、TXD) | 2 | 3 | 6 | 3 |
| 接受數據(RD、RXD) | 3 | 2 | 5 | 6 |
| 數據終端準備(DTR) | 20 | 4 | 3 | 2 |
| 數據準備好(DSR) | 6 | 6 | 1 | 7 |
| 請求發送(RTS) | 4 | 7 | 8 | 1 |
| 清除發送(CTS) | 5 | 8 | 7 | 8 |
| 數據載波檢測(DCD) | 8 | 1 | 2 | 7 |
| 振鈴指示(RI) | 22 | 9 | 1 | - |
| Pin1 | DCD | Data Carrier Detect | 調制解調器通知計算機有載波被偵測到。 |
| Pin2 | RXD | Receiver | 接收數據。 |
| Pin3 | TXD | Transmit | 發送數據。 |
| Pin4 | DTR | Data Terminal Ready | 計算機告訴調制解調器可以進行傳輸。 |
| Pin5 | GND | Ground | 地線。 |
| Pin6 | DSR | Data Set Ready | 調制解調器告訴計算機一切準備就緒。 |
| Pin7 | RTS | Request To Send | 計算機要求調制解調器將數據提交。 |
| Pin8 | CTS | Clear To Send | 調制解調器通知計算機可以傳數據過來。 |
| Pin9 | RI | Ring Indicator | 調制解調器通知計算機有電話進來。 |
串行通信在軟件設置里需要做多項設置,最常見的設置包括波特率(Baud)、奇偶校驗(Parity Check)和停止位(Stop Bit)
#RS485
RS485是由EIA(Electronic Industry Association,美國電子工業協會)于1983年在RS-422基礎上制定并發布的一種串行通信平衡式數據發送標準, 經通訊工業協會(TIA)修訂后命名為TIA/EIA-485-A。滿足RS485標準的收發器采用差分傳輸方式(Differential Driver Mode),數據最高傳輸速率為10Mbps,最大通信距離約為1219m。
用纜線兩端的電壓差值來表示傳遞信號,不同的電壓差分別標識為邏輯1及邏輯0。兩端的電壓差最小為0.2V以上時有效,任何不大于12V或者不小于-7V的差值對接受端都被認為是正確的。
RS485具有支持多節點(32個節點),傳輸距離遠(最大1219m),接收靈敏度高(200mV電壓),連接簡單(在構成通信網絡時,僅需要一對雙絞線作傳輸線),能抑制共模干擾(差分傳輸), 成本低廉等特點,在多站、遠距離通信等多種工控環境中獲得了廣泛應用。
#R485與RS232比較
RS485相比RS232具有抑制共模干擾、傳輸距離長等優點,所以許多大型的工業設備都采用RS485進行串口通訊。
RS485采用的是差分信號,所以在進行串口通訊時,只能采用半雙工的工作方式,必須使用1個或2個I/O口來控制RS485的發送和接收狀態
#開發
#DTS配置
項目中主芯片RS232 RS485不夠 需要通過USB 擴展RS232(silicon CP2105) ,RS232再轉RS485 (thvd1500) ?RS232轉RS485,RE/DE 控住輸出 ,項目中通過GPIO控制
rs485-thvd1500{status = "okay";compatible = "ti,thvd1500-gpio";thvd1500-gpio1 = <&pca0 1 1>;thvd1500-gpio2 = <&pca0 2 1>; };2路RS485 控制腳
#驅動開發
協議轉換
drivers/usb/serial/cp210x.c /** cp210x_get_config* Reads from the CP210x configuration registers* 'size' is specified in bytes.* 'data' is a pointer to a pre-allocated array of integers large* enough to hold 'size' bytes (with 4 bytes to each integer)*/ static int cp210x_get_config(struct usb_serial_port *port, u8 request,unsigned int *data, int size) {... }/** cp210x_set_config* Writes to the CP210x configuration registers* Values less than 16 bits wide are sent directly* 'size' is specified in bytes.*/ static int cp210x_set_config(struct usb_serial_port *port, u8 request,unsigned int *data, int size) {.... }static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) {int result;result = cp210x_set_config_single(port, CP210X_IFC_ENABLE,UART_ENABLE);if (result) {dev_err(&port->dev, "%s - Unable to enable UART\n", __func__);return result;}/* Configure the termios structure */cp210x_get_termios(tty, port);/* The baud rate must be initialised on cp2104 */if (tty)cp210x_change_speed(tty, port, NULL);return usb_serial_generic_open(tty, port); }通過設置termios類型的數據結構中的值,可以對終端接口進行控制。
使能控制:
if (gpio_is_valid(gpio)){┊ devm_gpio_request_one(&pdev->dev, gpio,GPIOF_OUT_INIT_HIGH, "thvd1500-gpio1");┊ thvd1500_priv1.gpio_num = gpio;┊ thvd1500_priv1.active_high = flag;┊ thvd1 = proc_create_data("thvd1", 0777, thvd1500_dir, &thvd_proc_fops1,(void *)&thvd1500_priv1);....#POSIX規范API
標準接口:
#include <termios.h>speed_t cfgetispeed(const struct termios *); speed_t cfgetospeed(const struct termios *); int cfsetispeed(struct termios *, speed_t speed); int cfseospeed(struct termios *, speed_t speed);這些API 作用于termios結構。需要先調用tcgetattr()獲得termios結構,再調用以上函數設置終端速度,最后調用tcsetattr()使設置生效。
其他API
#include <termios.h> int tcdrain(int fd);讓調用程序一直等待,直到所有排隊的輸出都發送完畢 int tcflow(int, int flowtype);暫停或重新開始輸出 int tcflush(int fd, int in_out_selector);清空輸入,輸出或兩者都清空#HAL層以上APP層
#APK call JNI
JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_open(JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags) {int fd;speed_t speed;jobject mFileDescriptor;/* Configure device */{struct termios cfg;LOGD("Configuring serial port");if (tcgetattr(fd, &cfg)){LOGE("tcgetattr() failed");close(fd);/* TODO: throw an exception */return NULL;}cfmakeraw(&cfg);cfsetispeed(&cfg, speed);cfsetospeed(&cfg, speed);if (tcsetattr(fd, TCSANOW, &cfg)){LOGE("tcsetattr() failed");close(fd);/* TODO: throw an exception */return NULL;}}...return mFileDescriptor; }Java 中調用JNI// JNIprivate native static FileDescriptor open(String path, int baudrate,int flags);調用相關API ,配置termios結構數據
#APP
public class SerialPort {public SerialPort(File device, int baudrate, int flags)throws SecurityException, IOException {/* Check access permission */if (!device.canRead() || !device.canWrite()) {...}mFd = open(device.getAbsolutePath(), baudrate, flags);/*調用JNI總open*/if (mFd == null) {Log.e(TAG, "native open returns null");throw new IOException();}mFileInputStream = new FileInputStream(mFd);mFileOutputStream = new FileOutputStream(mFd);}... }構建類
/** 打開串口,接收數據* 通過串口,接收單片機發送來的數據*/public void openSerialPort() {try {serialPort = new SerialPort(new File(TTYUSB0), 115200, 0);//調用對象SerialPort方法,獲取串口中"讀和寫"的數據流inputStream = serialPort.getInputStream();outputStream = serialPort.getOutputStream();serialPort1 = new SerialPort(new File(TTYUSB1), 115200, 0);//調用對象SerialPort方法,獲取串口中"讀和寫"的數據流inputStream1 = serialPort1.getInputStream();outputStream1 = serialPort1.getOutputStream();Log.i(TAG, "打開串口");} catch (IOException e) {e.printStackTrace();}//getSerialPort();}通過流讀取數據
#調試
#log開啟
開啟USB轉RS232 dev_dbg config文件添加
CONFIG_DEBUG_FS=y CONFIG_DYNAMIC_DEBUG=ykernel debug <linux/device.h> 打印級別
#define KERN_EMERG KERN_SOH "0" /* system is unusable */ #define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */ #define KERN_CRIT KERN_SOH "2" /* critical conditions */ #define KERN_ERR KERN_SOH "3" /* error conditions */ #define KERN_WARNING KERN_SOH "4" /* warning conditions */ #define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */ #define KERN_INFO KERN_SOH "6" /* informational */ #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */ #define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel*/kernel/printk.c
/* printk's without a loglevel use this.. */#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */int console_printk[4] = {DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel 控制臺日志級別,優先級高于該值的消息將在控制臺顯示*/DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel 最低的控制臺日志級別 */DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ };查看打印級別 和修改打印級別。
rk3399_mid:/ # cat /proc/sys/kernel/printk 7 4 1 7 rk3399_mid:/ # echo 1 4 1 7 >/proc/sys/kernel/printk rk3399_mid:/ # cat /proc/sys/kernel/printk 1 4 1 7#RS232/RS485/RS422常見問題
問題一 :A廠的屏可以和設備通信,換成B廠的屏就通信不上了。方向:1) 首先確認一下接線是否正確了,RX和TX是否兼容。2) 地線是否沒有接。3) 除了RX,TX,GND,是否還有其它引腳需要短接的。4) 通信協議是否一致或不完善,波特率是否一樣。
問題二:設備A是RS232,設備B是RS422,沒有轉換設備 怎么處理?
設備A是RS422接口,但是只有RS232通信可以測試通信。需要將RS422轉成RS232進行通信,兩者都是全雙工的,接收和發送都是同時到的,而RS422只是以一種差分信號進行傳輸。將422的Rx+與232的TX接,422的RX-與232的GND接。將422的TX+與232的RX接,422的TX-與232的GDN接。
問題三:RS232接口通信OK ,RS485通信也OK,但是使用RS232轉RS485通信就不穩定。RS232全雙工,RS485半雙工,應用層發送/接受數據時,RS485不能同時收/發,需要Master嚴格控制數據命令,這是通信倍率調慢一些(不是調節波特率)
? 回復「?籃球的大肚子」進入技術群聊
回復「1024」獲取1000G學習資料
總結
以上是生活随笔為你收集整理的Rockchip USB转485的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wms开发语言c 还是java,专业WM
- 下一篇: 商业计划书-智能导盲仗