RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

上位機(jī)下位機(jī)串口通信設(shè)計(jì)詳解

sharepcb ? 來(lái)源:直觀(guān)學(xué)PLC ? 2023-02-21 09:55 ? 次閱讀

串行接口是一種可以將接受來(lái)自CPU的并行數(shù)據(jù)字符轉(zhuǎn)換為連續(xù)的串行數(shù)據(jù)流發(fā)送出去,同時(shí)可將接受的串行數(shù)據(jù)流轉(zhuǎn)換為并行的數(shù)據(jù)字符供給CPU的器件。一般完成這種功能的電路,我們稱(chēng)為串行接口電路。

串口通信結(jié)構(gòu)

串口通信是指外設(shè)和計(jì)算機(jī)間,通過(guò)數(shù)據(jù)信號(hào)線(xiàn) 、地線(xiàn)、控制線(xiàn)等,按位進(jìn)行傳輸數(shù)據(jù)的一種通訊方式。這種通信方式使用的數(shù)據(jù)線(xiàn)少,在遠(yuǎn)距離通信中可以節(jié)約通信成本,但其傳輸速度比并行傳輸?shù)汀?/p>

串口是計(jì)算機(jī)上一種非常通用的設(shè)備通信協(xié)議。大多數(shù)計(jì)算機(jī)(不包括筆記本電腦)包含兩個(gè)基于RS-232的串口。串口同時(shí)也是儀器儀表設(shè)備通用的通信協(xié)議;很多GPIB兼容的設(shè)備也帶有RS-232口。同時(shí),串口通信協(xié)議也可以用于獲取遠(yuǎn)程采集設(shè)備的數(shù)據(jù)。

RS-232(ANSI/EIA-232標(biāo)準(zhǔn))是IBM-PC及其兼容機(jī)上的串行連接標(biāo)準(zhǔn)??捎糜谠S多用途,比如連接鼠標(biāo)、打印機(jī)或者M(jìn)odem,同時(shí)也可以接工業(yè)儀器儀表。用于驅(qū)動(dòng)和連線(xiàn)的改進(jìn),實(shí)際應(yīng)用中RS-232的傳輸長(zhǎng)度或者速度常常超過(guò)標(biāo)準(zhǔn)的值。RS-232只限于PC串口和設(shè)備間點(diǎn)對(duì)點(diǎn)的通信。RS-232串口通信最遠(yuǎn)距離是50英尺。

串口通信

串口通信是在工程應(yīng)用中很常見(jiàn)。在上位機(jī)與下位機(jī)通訊過(guò)程中常通過(guò)有線(xiàn)的串口進(jìn)行通信,在低速傳輸模式下串口通信得到廣泛使用。在說(shuō)個(gè)之前先來(lái)簡(jiǎn)單解釋一下上位機(jī)與下位機(jī)的概念。

上位機(jī)與下位機(jī)設(shè)計(jì)

通常上位機(jī)指的是PC,下位機(jī)指的是單片機(jī)或者帶微處理器的系統(tǒng)。下位機(jī)一般是將模擬信號(hào)經(jīng)過(guò)AD采集將模擬量轉(zhuǎn)換為數(shù)字量,下位機(jī)再經(jīng)過(guò)數(shù)字信號(hào)處理以后將數(shù)字信號(hào)通過(guò)串口發(fā)送到上位機(jī),相反上位機(jī)可以給下位機(jī)發(fā)送一些指令或者信息。常見(jiàn)的通信串口包括RS232、RS485、RS422等。這些串口只是在電平特性有所不同,在上位機(jī)與下位機(jī)進(jìn)行數(shù)據(jù)通信時(shí)可以不考慮電平特性,而且現(xiàn)在在硬件上有各種轉(zhuǎn)接接口,使用起來(lái)也很方便。

當(dāng)然在通常做簡(jiǎn)單的串口UART實(shí)驗(yàn)時(shí)我們可以使用各種各樣的串口助手小軟件,但是這些串口小工具有時(shí)候并不能很好滿(mǎn)足需求,那就嘗試著自己寫(xiě)一套屬于自己的串口助手?接下來(lái)說(shuō)說(shuō)如何使用java實(shí)現(xiàn)上位機(jī)與下位機(jī)之間的RS485串口通信。

step 1:下載支持java串口通信的jar包,這里給出下載地址:

http://files.cnblogs.com/files/Dreamer-1/mfz-rxtx-2.2-20081207-win-x86.zip(32bit 下載地址)

http://files.cnblogs.com/files/Dreamer-1/mfz-rxtx-2.2-20081207-win-x64.zip (64位下載地址)

對(duì)以上的版本解釋一下,因?yàn)楸救嗽谶@里踩了一個(gè)坑,32位或者64位是與ecplise/myecplise一致,要是版本弄錯(cuò)了會(huì)報(bào)錯(cuò)。

step 2:下載了那個(gè)jar包解壓后會(huì)出現(xiàn)以下內(nèi)容:

8e8e58cc-b122-11ed-bfe3-dac502259ad0.png

這個(gè)文件夾里面需要注意兩點(diǎn):jar包RXTXcomm需要導(dǎo)入到j(luò)ava工程里面去。另外就是需要將rxtxParallel.dll與rxtxSerial.dll復(fù)制在安裝JDK的bin文件下和jre的bin文件夾下面,這樣才能保證能夠正常使用這個(gè)jar包。以下是將兩個(gè)dll文件復(fù)制的位置:

C:Program Files (x86)Javajdk1.8.0_25in

C:Program Files (x86)Javajdk1.8.0_25jrein12

怎么講jar包導(dǎo)入java工程里面就是比較簡(jiǎn)單的操作,可以參考:http://jingyan.baidu.com/arTIcle/ca41422fc76c4a1eae99ed9f.html

step 3:RXTXComm Api如何使用

接下來(lái)就是使用該導(dǎo)入jar包進(jìn)行編碼實(shí)現(xiàn)串口通信的功能了。在編碼之前先來(lái)理一理串口通信的主要環(huán)節(jié),本人總結(jié)主要分為以下幾點(diǎn):

1)計(jì)算機(jī)首先需要進(jìn)行硬件check,查找是否有可用的COM端口,并對(duì)該對(duì)端口進(jìn)行簡(jiǎn)要判斷,包括這些端口是否是串口,是否正在使用。以下是部分主要代碼:

/*類(lèi)方法 不可改變 不接受繼承

* 掃描獲取可用的串口

* 將可用串口添加至list并保存至list

*/

public staTIc final ArrayList《String》 uartPortUseAblefind()

{

//獲取當(dāng)前所有可用串口

//由CommPorTIdenTIfier類(lèi)提供方法

Enumeration《CommPortIdentifier》 portList=CommPortIdentifier.getPortIdentifiers();

ArrayList《String》 portNameList=new ArrayList();

//添加并返回ArrayList

while(portList.hasMoreElements())

{

String portName=portList.nextElement().getName();

portNameList.add(portName);

}

return portNameList;

}123456789101112131415161718

以下是測(cè)試類(lèi)的測(cè)試實(shí)例:

ArrayList《String》 arraylist=UARTParameterSetup.uartPortUseAblefind();

int useAbleLen=arraylist.size();

if(useAbleLen==0)

{

System.out.println(“沒(méi)有找到可用的串口端口,請(qǐng)check設(shè)備!”);

}

else

{

System.out.println(“已查詢(xún)到該計(jì)算機(jī)上有以下端口可以使用:”);

for(int index=0;index《arraylist.size();index++)

{

System.out.println(“該COM端口名稱(chēng):”+arraylist.get(index));

//測(cè)試串口配置的相關(guān)方法

}

} 123456789101112131415

2)通過(guò)計(jì)算機(jī)對(duì)串口的自檢后,可以對(duì)串口參數(shù)進(jìn)行簡(jiǎn)單的配置。常見(jiàn)的配置可以從常見(jiàn)的串口助手中得到啟發(fā)。以下是一個(gè)串口助手的人機(jī)交換界面:

8eb51570-b122-11ed-bfe3-dac502259ad0.png

以下是對(duì)串口設(shè)置主要代碼:

/*

* 串口常見(jiàn)設(shè)置

* 1)打開(kāi)串口

* 2)設(shè)置波特率 根據(jù)單板機(jī)的需求可以設(shè)置為57600 。。。

* 3)判斷端口設(shè)備是否為串口設(shè)備

* 4)端口是否占用

* 5)對(duì)以上條件進(jìn)行check以后返回一個(gè)串口設(shè)置對(duì)象new UARTParameterSetup()

* 6)return:返回一個(gè)SerialPort一個(gè)實(shí)例對(duì)象,若判定該com口是串口則進(jìn)行參數(shù)配置

* 若不是則返回SerialPort對(duì)象為null

*/

public static final SerialPort portParameterOpen(String portName,int baudrate)

{

SerialPort serialPort=null;

try

{ //通過(guò)端口名識(shí)別串口

CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);

//打開(kāi)端口并設(shè)置端口名字 serialPort和超時(shí)時(shí)間 2000ms

CommPort commPort=portIdentifier.open(portName,1000);

//進(jìn)一步判斷comm端口是否是串口 instanceof

if(commPort instanceof SerialPort)

{

System.out.println(“該COM端口是串口!”);

//進(jìn)一步強(qiáng)制類(lèi)型轉(zhuǎn)換

serialPort=(SerialPort)commPort;

//設(shè)置baudrate 此處需要注意:波特率只能允許是int型 對(duì)于57600足夠

//8位數(shù)據(jù)位

//1位停止位

//無(wú)奇偶校驗(yàn)

serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8,SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

//串口配制完成 log

System.out.println(“串口參數(shù)設(shè)置已完成,波特率為”+baudrate+“,數(shù)據(jù)位8bits,停止位1位,無(wú)奇偶校驗(yàn)”);

}

//不是串口

else

{

System.out.println(“該com端口不是串口,請(qǐng)檢查設(shè)備!”);

//將com端口設(shè)置為null 默認(rèn)是null不需要操作

}

}

catch (NoSuchPortException e)

{

e.printStackTrace();

}

catch (PortInUseException e)

{

e.printStackTrace();

}

catch (UnsupportedCommOperationException e)

{

e.printStackTrace();

}

return serialPort;

}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

以上代碼就是返回一個(gè)對(duì)象,同時(shí)也返回了對(duì)象屬性,因?yàn)閷?duì)象在java里面是屬于傳值引用。對(duì)以上需要說(shuō)明的是:在實(shí)驗(yàn)時(shí)需要連接串口才能讓計(jì)算機(jī)檢測(cè)到才能讓程序工作,這里使用的是RS485轉(zhuǎn)接線(xiàn):

8edf9b24-b122-11ed-bfe3-dac502259ad0.png

3)通過(guò)以上兩個(gè)步驟后基本對(duì)串口的設(shè)置也完成了,對(duì)于串口類(lèi)型的確認(rèn)例如:RS232/RS485/RS422等,可以作為進(jìn)一步確認(rèn)的條件。RS485可以在gnu.io中找到。

8f15a85e-b122-11ed-bfe3-dac502259ad0.png

接下來(lái)就是上位機(jī)與下位機(jī)之間的雙向通信的功能實(shí)現(xiàn)了。該部分主要是利用java的輸入輸出流來(lái)實(shí)現(xiàn)。以下是主要代碼:

/*

* 串口數(shù)據(jù)發(fā)送以及數(shù)據(jù)傳輸作為一個(gè)類(lèi)

* 該類(lèi)做主要實(shí)現(xiàn)對(duì)數(shù)據(jù)包的傳輸至下單板機(jī)

*/

class DataTransimit

{

/*

* 上位機(jī)往單板機(jī)通過(guò)串口發(fā)送數(shù)據(jù)

* 串口對(duì)象 seriesPort

* 數(shù)據(jù)幀:dataPackage

* 發(fā)送的標(biāo)志:數(shù)據(jù)未發(fā)送成功拋出一個(gè)異常

*/

public static void uartSendDatatoSerialPort(SerialPort serialPort,byte[] dataPackage)

{

OutputStream out=null;

try

{

out=serialPort.getOutputStream();

out.write(dataPackage);

out.flush();

} catch (IOException e)

{

e.printStackTrace();

}finally

{

//關(guān)閉輸出流

if(out!=null)

{

try

{

out.close();

out=null;

System.out.println(“數(shù)據(jù)已發(fā)送完畢!”);

} catch (IOException e)

{

e.printStackTrace();

}

}

}

}

/*

* 上位機(jī)接收數(shù)據(jù)

* 串口對(duì)象seriesPort

* 接收數(shù)據(jù)buffer

* 返回一個(gè)byte數(shù)組

*/

public static byte[] uartReceiveDatafromSingleChipMachine(SerialPort serialPort)

{

byte[] receiveDataPackage=null;

InputStream in=null;

try

{

in=serialPort.getInputStream();

//獲取data buffer數(shù)據(jù)長(zhǎng)度

int bufferLength=in.available();

while(bufferLength!=0)

{

receiveDataPackage=new byte[bufferLength];

in.read(receiveDataPackage);

bufferLength=in.available();

}

}

catch (IOException e)

{

e.printStackTrace();

}

return receiveDataPackage;

} 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970

通過(guò)以上關(guān)于Uart兩個(gè)基本類(lèi)實(shí)現(xiàn)對(duì)底層Uart的功能封裝,其中一個(gè)類(lèi)主要負(fù)責(zé)Uart串口自檢和基本設(shè)置,另外一個(gè)類(lèi)主要has數(shù)據(jù)傳輸?shù)膬蓚€(gè)方法。接下來(lái)以一個(gè)實(shí)例說(shuō)一說(shuō)通過(guò)RS485串口通信將系統(tǒng)當(dāng)前時(shí)間發(fā)送至單板機(jī)系統(tǒng)。

step 4:實(shí)現(xiàn)實(shí)時(shí)系統(tǒng)時(shí)間的數(shù)據(jù)包傳輸至下位機(jī)

這一步可以分為以下兩個(gè)步驟:首先實(shí)現(xiàn)獲取系統(tǒng)時(shí)間,將時(shí)間進(jìn)行封裝成幀;另外就是通過(guò)RS485串口將時(shí)間數(shù)據(jù)包發(fā)送至單板機(jī)系統(tǒng)進(jìn)行解析。

1) 系統(tǒng)時(shí)間的獲取

根據(jù)java面對(duì)對(duì)象設(shè)計(jì)思想,這里將有關(guān)系統(tǒng)時(shí)間的方法歸為一類(lèi)。

以下是獲取當(dāng)前系統(tǒng)時(shí)間代碼:

public static String getCurrentDateTime()

{

//單例模式

Calendar calendar=Calendar.getInstance();

int year = calendar.get(Calendar.YEAR);//獲取年份

int month=calendar.get(Calendar.MONTH);//獲取月份

int day=calendar.get(Calendar.DATE);//獲取日期

int minute=calendar.get(Calendar.MINUTE);//分

int hour=calendar.get(Calendar.HOUR);//小時(shí)

int second=calendar.get(Calendar.SECOND);//秒

String curerentDateTime = year + “ ” + (month + 1 )+ “ ” + day + “ ”+ (hour+12) + “ ” + minute + “ ” + second + “ ”;

timeCheckSum=year+(month+1)+day+(hour+12)+minute+second;

return curerentDateTime;

}1234567891011121314

java 提供了calender類(lèi),該類(lèi)提供了一些與時(shí)間有關(guān)方法。至于Calendar.getInstance()使用單例模式獲取一個(gè)Calendar實(shí)例對(duì)象,單例模式就是一個(gè)類(lèi)在任何時(shí)候只允許有一個(gè)實(shí)例化對(duì)象。獲取系統(tǒng)時(shí)間除了使用Calendar還可以使用Date類(lèi),通過(guò)創(chuàng)建對(duì)象也可以實(shí)現(xiàn)系統(tǒng)當(dāng)前時(shí)間的獲取。timeCheckSum作為時(shí)間數(shù)據(jù)的校驗(yàn)和發(fā)送至單板機(jī)作為自定義協(xié)議的一部分。

由于發(fā)送的數(shù)據(jù)包通常是以字節(jié)(byte)為單位進(jìn)行發(fā)送和傳輸?shù)?,因此需要將int型的時(shí)間轉(zhuǎn)換為byte使用byte[]進(jìn)行存儲(chǔ),作為一個(gè)數(shù)據(jù)包發(fā)送。

/*

* 將以上時(shí)間字符串進(jìn)行隔開(kāi)用byte[]保存

*/

public static byte[] dateTimeBytesGet(String currenDateTime)

{

//對(duì)當(dāng)前時(shí)間參數(shù)進(jìn)行格式判斷

//對(duì)格式進(jìn)行判斷

int rawDataSize=6;

byte[] dateTimeBytes=new byte[rawDataSize+1];

String[] currentDateTimeSplit=currenDateTime.split(“ ”);

if(currentDateTimeSplit.length==rawDataSize)

{

//時(shí)間數(shù)據(jù)格式正確

//eg 2016 12 23 22 18 26

//使用byte[]進(jìn)行存儲(chǔ)時(shí)需要 -128~+127

//對(duì)于年份使用兩個(gè)byte存儲(chǔ)

for(int dataIndex=0;dataIndex《rawDataSize;dataIndex++)

{

int dateTemp=Integer.parseInt(currentDateTimeSplit[dataIndex]);

if(dataIndex==0)

{

byte H8bits=(byte)((dateTemp)》》8);

byte L8bits=(byte)((dateTemp)&0xff);

dateTimeBytes[dataIndex]= H8bits;

dateTimeBytes[dataIndex+1]= L8bits;

}

dateTimeBytes[dataIndex+1]=(byte)dateTemp;

}

}else

{

System.out.println(“當(dāng)前時(shí)間獲取出現(xiàn)異常數(shù)據(jù)”);

System.exit(-1);

dateTimeBytes=null;

}

return dateTimeBytes;

}123456789101112131415161718192021222324252627282930313233343536

以上數(shù)據(jù)可以使用7個(gè)byte對(duì)時(shí)間數(shù)據(jù)進(jìn)行存儲(chǔ),因?yàn)槟攴菪枰褂脙蓚€(gè)字節(jié)來(lái)存儲(chǔ),格式為高字節(jié)在前,低字節(jié)在后,之后依次存放。

將時(shí)間數(shù)據(jù)存放在byte[]數(shù)組以后接下來(lái)就是添加自己的協(xié)議部分了。該部分具有較大的隨意性,因?yàn)樵搮f(xié)議可以根據(jù)不同的風(fēng)格有不同的形式。為了簡(jiǎn)單起見(jiàn),只需要在時(shí)間數(shù)據(jù)byte[]之前添加head、CMD、時(shí)間數(shù)據(jù)長(zhǎng)度length這三個(gè)字節(jié)進(jìn)行補(bǔ)充,時(shí)間數(shù)據(jù)byte[]后面依次添加校驗(yàn)和高低字節(jié)以及tail指令即可。以上基本實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的時(shí)間數(shù)據(jù)package。以下是本模塊的代碼:

/*

* 將數(shù)組封裝成幀

* 每一個(gè)數(shù)據(jù)幀由以下幾個(gè)部分組成

* 1)數(shù)據(jù)包頭部 head 0X2F

* 2)數(shù)據(jù)包命令 CMD 0X5A

* 3)數(shù)據(jù)個(gè)數(shù) length of data 7

* 4)校驗(yàn)和 H8/L8 byte of check sum(高字節(jié)在前 低字節(jié)在后)

* 5)數(shù)據(jù)結(jié)尾標(biāo)志 tail OX30

* 6)可采用線(xiàn)程進(jìn)行獲取當(dāng)前時(shí)間

*/

public static byte[] makeCurrentDateTimefromStringtoFramePackage(byte[] dateTimeBytes)

{

//在時(shí)間byte[]前后添加一些package校驗(yàn)信息

int dataLength=13;

byte[] terimalTimePackage=new byte[dataLength];

//裝填信息

//時(shí)間數(shù)據(jù)包之前的信息

terimalTimePackage[0]=0x2F;

terimalTimePackage[1]=0X5A;

terimalTimePackage[2]=7;

//計(jì)算校驗(yàn)和

//轉(zhuǎn)化為無(wú)符號(hào)進(jìn)行校驗(yàn)

for(int dataIndex=0;dataIndex《dateTimeBytes.length;dataIndex++)

{

terimalTimePackage[dataIndex+3]=dateTimeBytes[dataIndex];

}

//將校驗(yàn)和分為高低字節(jié)

byte sumH8bits=(byte)((timeCheckSum)》》8);

byte sumL8bits=(byte)((timeCheckSum)&0xff);

terimalTimePackage[10]=sumH8bits;//高字節(jié)在前

terimalTimePackage[11]=sumL8bits;//低字節(jié)在后

//數(shù)據(jù)包結(jié)尾

terimalTimePackage[12]=0X30;

return terimalTimePackage;

}1234567891011121314151617181920212223242526272829303132333435

下面給出了將時(shí)間數(shù)據(jù)byte數(shù)組進(jìn)行解析的debug代碼,一方面是確定上位機(jī)本部分模塊的程序可靠性,另外也可以直接移植到下位機(jī)對(duì)數(shù)據(jù)包的解析之中。在下位機(jī)解析過(guò)程中需要注意一點(diǎn):因?yàn)樵趈ava中8大基本類(lèi)型都是帶符號(hào),年份時(shí)間和時(shí)間校驗(yàn)和拆分為高低字節(jié)時(shí),低字節(jié)是二進(jìn)制無(wú)符號(hào)的,但是計(jì)算機(jī)卻是按照有符號(hào)數(shù)(補(bǔ)碼方式)進(jìn)行讀取,例如在2016年轉(zhuǎn)換為二進(jìn)制數(shù)為:11111100000,那么高字節(jié)為00000111,低字節(jié)為11100000。計(jì)算機(jī)讀取為:高字節(jié)為7,低字節(jié)為-32。其實(shí)由兩個(gè)byte真實(shí)還原的過(guò)程應(yīng)為:7《《8+(低字節(jié)二進(jìn)制數(shù)字)=7*256+224=2016,因此在debug解析時(shí)間數(shù)據(jù)包時(shí)需要將有符號(hào)數(shù)字轉(zhuǎn)換為無(wú)符號(hào)數(shù)字。

/*

* 對(duì)時(shí)間格式進(jìn)行解析并還原原來(lái)的時(shí)間格式

* 對(duì)數(shù)據(jù)進(jìn)行還原

* 僅限于debug使用

*/

public static String dateTimeBytesfromTostring(byte[] currentDateTime)

{

String string=“”;

if(currentDateTime.length==7)

{

string=((currentDateTime[0]《《8)+bytetoUnsigendInt(currentDateTime[1]))+“ ”+currentDateTime[2]+“ ”+

currentDateTime[3]+“ ”+currentDateTime[4]+“ ”+currentDateTime[5]+“ ”+

currentDateTime[6];

}

return string;

}

/*

* 將byte轉(zhuǎn)化為字符串

* 將有符號(hào)byte轉(zhuǎn)化為無(wú)符號(hào)數(shù)字

* debug使用

*/

public static int bytetoUnsigendInt(byte aByte)

{

String s=String.valueOf(aByte);

//System.out.println(s);

int bytetoUnsigendInt=0;

for(int i=0;i《s.length();i++)

{

if(s.charAt(i)!=‘0’)

{

bytetoUnsigendInt+=1《《(7-i);

}

}

return bytetoUnsigendInt;

}12345678910111213141516171819202122232425262728293031323334353637

2)將最后的時(shí)間數(shù)據(jù)包通過(guò)RS485串口發(fā)送至下位機(jī)

結(jié)合前面的串口程序就可以使用串口發(fā)送程序了。在程序debug的前期可以在程序的關(guān)鍵位置輸出日志就是打印log的方法可以提高程序調(diào)試的效率。以下是主類(lèi)的測(cè)試代碼:

//取出第一個(gè)COM端口進(jìn)行測(cè)試

SerialPort serialPort=UARTParameterSetup.portParameterOpen(arraylist.get(0), 57600);

//退出程序 后續(xù)不需要監(jiān)測(cè) 因?yàn)閠ransimit一直需要保證連接狀態(tài)

//System.exit(0);

DataTransimit.uartSendDatatoSerialPort(serialPort, dataFrame);

String currentDateTime=SystemDateTimeGet.getCurrentDateTime();

System.out.println(currentDateTime);

byte[] bytes=SystemDateTimeGet.dateTimeBytesGet(currentDateTime);

//System.out.println(Arrays.toString(bytes));

String str=SystemDateTimeGet.dateTimeBytesfromTostring(bytes);

System.out.println(str);

//System.out.println(SystemDateTimeGet.bytetoUnsigendInt((byte) -32));

byte[] terimalTimeByte=SystemDateTimeGet.makeCurrentDateTimefromStringtoFramePackage(bytes);

System.out.println(Arrays.toString(terimalTimeByte));

DataTransimit.uartSendDatatoSerialPort(serialPort, terimalTimeByte);123456789101112131415

以下是測(cè)試結(jié)果:

當(dāng)沒(méi)有串口設(shè)備接入計(jì)算機(jī)時(shí)控制臺(tái)打印一條信息:

沒(méi)有找到可用的串口端口,請(qǐng)check設(shè)備!

12

當(dāng)RS485設(shè)備接入計(jì)算機(jī)時(shí),控制臺(tái)打印消息如下:

8f35a974-b122-11ed-bfe3-dac502259ad0.png

通過(guò)以上幾個(gè)步驟基本實(shí)現(xiàn)了上位機(jī)與下位機(jī)串口通信的功能,接下來(lái)還可以對(duì)程序進(jìn)行改進(jìn):

1)添加界面,可以類(lèi)比串口助手界面根據(jù)自身需要設(shè)計(jì)獨(dú)具風(fēng)格的人機(jī)交互界面。

2) 在程序中添加線(xiàn)程,在以上程序中對(duì)于系統(tǒng)時(shí)間的獲取可以通過(guò)線(xiàn)程的方式進(jìn)行獲取,這樣上位機(jī)就可以一直往下位機(jī)發(fā)送數(shù)據(jù)包,而不是僅僅發(fā)一次。

3)對(duì)于上位機(jī)數(shù)據(jù)接收,除了以上最基本的接收功能外,還可以使用JDBC與mysql等數(shù)據(jù)進(jìn)行存儲(chǔ),并繪畫(huà)數(shù)據(jù)曲線(xiàn)實(shí)現(xiàn)特性分析。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10854

    瀏覽量

    211574
  • uart
    +關(guān)注

    關(guān)注

    22

    文章

    1235

    瀏覽量

    101354
  • 串口通信
    +關(guān)注

    關(guān)注

    34

    文章

    1624

    瀏覽量

    55507
  • 上位機(jī)
    +關(guān)注

    關(guān)注

    27

    文章

    941

    瀏覽量

    54790
  • 下位機(jī)
    +關(guān)注

    關(guān)注

    0

    文章

    94

    瀏覽量

    18753

原文標(biāo)題:上位機(jī)下位機(jī)串口通信設(shè)計(jì)詳解

文章出處:【微信號(hào):直觀(guān)學(xué)PLC,微信公眾號(hào):直觀(guān)學(xué)PLC】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    實(shí)現(xiàn)基于Qt的上位機(jī)下位機(jī)進(jìn)行串口通信

    :Qt5.96Mingw32-bit keil3項(xiàng)目目標(biāo)1、實(shí)現(xiàn)下位機(jī)基于STC單片機(jī)控制LED燈模塊、獨(dú)立鍵盤(pán)模塊.2、實(shí)現(xiàn)基于Qt的上位機(jī)
    發(fā)表于 12-08 07:26

    上位機(jī)下位機(jī)串口通信設(shè)計(jì)詳解

    串行接口是一種可以將接受來(lái)自CPU的并行數(shù)據(jù)字符轉(zhuǎn)換為連續(xù)的串行數(shù)據(jù)流發(fā)送出去,同時(shí)可將接受的串行數(shù)據(jù)流轉(zhuǎn)換為并行的數(shù)據(jù)字符供給CPU的器件。一般完成這種功能的電路,我們稱(chēng)為串行接口電路。
    發(fā)表于 11-10 10:27 ?7.9w次閱讀
    <b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b><b class='flag-5'>下位</b><b class='flag-5'>機(jī)</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>設(shè)計(jì)<b class='flag-5'>詳解</b>

    什么是上位機(jī),什么是下位機(jī)?

    上位機(jī)發(fā)出的命令首先給下位機(jī),下位機(jī)再根據(jù)此命令解釋成相應(yīng)時(shí)序信號(hào)直接控制相應(yīng)設(shè)備。
    的頭像 發(fā)表于 03-23 10:11 ?2w次閱讀
    什么是<b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b>,什么是<b class='flag-5'>下位</b><b class='flag-5'>機(jī)</b>?

    基于RS232串口實(shí)現(xiàn)PIC單片機(jī)下位機(jī)與QT上位機(jī)通信

    基于RS232串口實(shí)現(xiàn)PIC單片機(jī)下位機(jī)與QT上位機(jī)通信
    發(fā)表于 11-16 12:21 ?21次下載
    基于RS232<b class='flag-5'>串口</b>實(shí)現(xiàn)PIC單片<b class='flag-5'>機(jī)</b><b class='flag-5'>下位</b><b class='flag-5'>機(jī)</b>與QT<b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b><b class='flag-5'>通信</b>

    打開(kāi)單片機(jī)世界的大門(mén)——上位機(jī)控制下位機(jī)實(shí)例詳解

    上位機(jī)控制下位機(jī)實(shí)例詳解一、基本概念上位機(jī)
    發(fā)表于 11-20 11:06 ?27次下載
    打開(kāi)單片<b class='flag-5'>機(jī)</b>世界的大門(mén)——<b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b>控制<b class='flag-5'>下位</b><b class='flag-5'>機(jī)</b>實(shí)例<b class='flag-5'>詳解</b>

    什么是上位機(jī)

    1.上位機(jī)下位機(jī)上位機(jī),與下位機(jī)對(duì)應(yīng),用來(lái)給
    發(fā)表于 01-14 13:43 ?5次下載
    什么是<b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b>

    上位機(jī)下位機(jī)的區(qū)別

    上位機(jī)下位機(jī)的區(qū)別 一、區(qū)別 1)上位機(jī):系統(tǒng)中起主控,主要作為系統(tǒng)的規(guī)劃控制,屬于決策層。
    發(fā)表于 04-26 14:32 ?4593次閱讀

    上位機(jī)和MYSQL連接_上位機(jī)下位機(jī)串口通信設(shè)計(jì)詳解

    串行接口是一種可以將接受來(lái)自CPU的并行數(shù)據(jù)字符轉(zhuǎn)換為連續(xù)的串行數(shù)據(jù)流發(fā)送出去,同時(shí)可將接受的串行數(shù)據(jù)流轉(zhuǎn)換為并行的數(shù)據(jù)字符供給CPU 的器件。一般完成這種功能的電路,我們稱(chēng)為串行接口電路。串口通信
    發(fā)表于 05-08 10:53 ?0次下載
    <b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b>和MYSQL連接_<b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b><b class='flag-5'>下位</b><b class='flag-5'>機(jī)</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>設(shè)計(jì)<b class='flag-5'>詳解</b>

    java實(shí)現(xiàn)上位機(jī)下位機(jī)串口通信

    串口通信是在工程應(yīng)用中很常見(jiàn)。在上位機(jī)下位機(jī)通訊過(guò)程中常通過(guò)有線(xiàn)的
    發(fā)表于 05-08 09:51 ?1次下載
    java實(shí)現(xiàn)<b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b>與<b class='flag-5'>下位</b><b class='flag-5'>機(jī)</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    上位機(jī)下位機(jī)通信

    。里程計(jì)提供ROS需要的速度信息,陀螺儀提供加速度方向等信息給 ROS,再加上連接到樹(shù)莓派上的激光雷達(dá),ROS就可以進(jìn)行SLAM制圖和導(dǎo)航了。下位機(jī)接收到ROS下發(fā)的速度信息后,轉(zhuǎn)換成電機(jī)的PWM信號(hào)和舵機(jī)的PWM信號(hào)進(jìn)行方向和速度控制。本篇就介紹
    發(fā)表于 05-09 11:44 ?0次下載
    <b class='flag-5'>上位</b><b class='flag-5'>機(jī)</b>與<b class='flag-5'>下位</b><b class='flag-5'>機(jī)</b><b class='flag-5'>通信</b>

    上位機(jī)下位機(jī)是什么意思

    上位機(jī)下位機(jī)是什么意思 上位機(jī)的意思是指可以直接發(fā)出操控命令的計(jì)算機(jī),一般是PC/host c
    發(fā)表于 06-05 11:09 ?4521次閱讀

    上位機(jī)下位機(jī)是什么意思 上位機(jī)下位機(jī)的區(qū)別

    上位機(jī)下位機(jī)是計(jì)算機(jī)控制系統(tǒng)中兩個(gè)重要的概念,它們?cè)诳刂啤?b class='flag-5'>通信和數(shù)據(jù)處理等方面發(fā)揮著關(guān)鍵作用。在本文中,我們將詳細(xì)探討
    的頭像 發(fā)表于 06-06 10:11 ?5772次閱讀

    上位機(jī)下位機(jī)串口通信的區(qū)別在哪

    上位機(jī)下位機(jī)串口通信的區(qū)別主要體現(xiàn)在以下幾個(gè)方面: 通信
    的頭像 發(fā)表于 06-06 10:34 ?1028次閱讀

    上位機(jī)下位機(jī)通信協(xié)議的優(yōu)化策略

    在現(xiàn)代工業(yè)自動(dòng)化系統(tǒng)中,上位機(jī)下位機(jī)之間的通信是不可或缺的環(huán)節(jié)。上位
    的頭像 發(fā)表于 06-28 16:36 ?912次閱讀

    上位機(jī)下位機(jī)實(shí)時(shí)通信的實(shí)現(xiàn)

    在工業(yè)自動(dòng)化、遠(yuǎn)程控制、數(shù)據(jù)采集與處理等領(lǐng)域,上位機(jī)下位機(jī)之間的實(shí)時(shí)通信是實(shí)現(xiàn)高效、準(zhǔn)確的數(shù)據(jù)交換和系統(tǒng)控制的基礎(chǔ)。本文旨在介紹實(shí)現(xiàn)
    的頭像 發(fā)表于 06-28 17:01 ?1476次閱讀
    RM新时代网站-首页