9-ESP8266 SDK開發(fā)基礎(chǔ)入門篇--編寫串口上位機軟件

https://www.cnblogs.com/yangfengwu/p/11087613.html


頁面修改成這樣子







現(xiàn)在看串口發(fā)送數(shù)據(jù)?

點擊點亮?發(fā)送0xaa 0x55 0x01 ? ?

我電腦上安裝了虛擬串口軟件,虛擬出來了COM1和COM2,然后COM1發(fā)送的數(shù)據(jù)會發(fā)給COM2 ?COM2發(fā)送的數(shù)據(jù)會發(fā)給COM1

大家如果有兩個串口模塊也可以





https://jingyan.baidu.com/article/e3c78d648965303c4c85f535.html




那個按鈕的程序這樣寫



?測試一下




現(xiàn)在看串口接收數(shù)據(jù)



說一下哈,這個是上位機的串口中斷函數(shù),就是只要接收到數(shù)據(jù)就會進入這個中斷

現(xiàn)在咱讀出來接收的數(shù)據(jù),然后顯示在


讀取數(shù)據(jù)給了好幾個方法

咱就說1個,哈哈哈,其實自己一選擇方法的時候就有中文注釋......



大家注沒注意



現(xiàn)在調(diào)用一個函數(shù)讀出來,然后顯示出來



ReadExisting() ? 這個方法就會返回緩沖區(qū)里面的所有字節(jié),注意返回的是字符串形式的

調(diào)用這個方法就是 ?serialPort1.ReadExisting(); ? ? ??serialPort1就是咱的


因為咱就是要里面的數(shù)據(jù)所以 ?

string str = serialPort1.ReadExisting();//讀出來當前緩存里面的所有數(shù)據(jù)




Invoke((new Action(() =>

{

? ? 這里面放要操作的主線程的控件的方法

})));

其實這個方法主要是方便解決一個問題,稍候再說,咱先測試一下哈



?說明可以了,現(xiàn)在呢,咱去掉





?大家可以點開那個? 如何跨線程調(diào)用 Windows 窗體控件

大家可以看這個https://www.cnblogs.com/yangfengwu/p/5761841.html(最好別看,看了就會感覺麻煩)

4.0之后引進了這種方法


對于初學(xué)者知道這個就可以了,像C#,C++,JAVA等等這種高級語言哈,因為可以做界面了,,高級語言規(guī)定,操作頁面不能在子線程中進行

哪些是子線程呢!..像上面那個串口中斷函數(shù),還有自己創(chuàng)建的任務(wù)Thread,,,等等吧

好現(xiàn)在,咱接收16進制,

接收到


0xaa 0x55 0x01??



0xaa 0x55 0x00??



好,上菜


//串口接收到數(shù)據(jù)就會進入privatevoidserialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)

? ? ? ? {

? ? ? ? ? ? intlen = serialPort1.BytesToRead;//獲取可以讀取的字節(jié)數(shù)if(len >0)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? byte[] recvBytes =newbyte[len];//創(chuàng)建接收的數(shù)組serialPort1.Read(recvBytes,0, len);//接收數(shù)據(jù)if(recvBytes[0] ==0xaa&& recvBytes[1] ==0x55)//判斷數(shù)據(jù)? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? if(recvBytes[2] ==0x01)//? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? Invoke((newAction(() =>? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? button3.Text ="熄滅";

? ? ? ? ? ? ? ? ? ? ? ? ? ? label5.Text ="點亮";

? ? ? ? ? ? ? ? ? ? ? ? })));

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? elseif(recvBytes[2] ==0x00)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? Invoke((newAction(() =>? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? button3.Text ="點亮";

? ? ? ? ? ? ? ? ? ? ? ? ? ? label5.Text ="熄滅";

? ? ? ? ? ? ? ? ? ? ? ? })));

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? //string str = serialPort1.ReadExisting();//讀出來當前緩存里面的所有數(shù)據(jù)

? ? ? ? ? ? //Invoke((new Action(() =>

? ? ? ? ? ? //{

? ? ? ? ? ? ////顯示在文本框里面

? ? ? ? ? ? //? ? textBox1.AppendText(str);

? ? ? ? ? ? //})));}









測試




雖然可以了,但是這樣寫不保險...

原因是那個中斷是不定長的數(shù)據(jù)就進去(受到電腦整體運行狀態(tài)的影響),所以呢咱優(yōu)化下



//串口接收到數(shù)據(jù)就會進入privatevoidserialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)

? ? ? ? {

? ? ? ? ? ? intlen = serialPort1.BytesToRead;//獲取可以讀取的字節(jié)數(shù)if(len >0)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? byte[] recvBytes =newbyte[len];//創(chuàng)建接收的數(shù)組serialPort1.Read(recvBytes,0, len);//接收數(shù)據(jù)for(inti =0; i < len; i++)//拷貝數(shù)據(jù)到UsartReadBuff? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? UsartReadBuff[i+ UsartReadCnt] = recvBytes[i];//從上次的地方接著填入數(shù)據(jù)? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? UsartReadCnt = UsartReadCnt + len;//記錄上次的數(shù)據(jù)個數(shù)if(UsartReadCnt >=3)//接收到可以處理的數(shù)據(jù)個數(shù)? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? UsartReadCnt =0;

? ? ? ? ? ? ? ? ? ? if(UsartReadBuff[0] ==0xaa&& UsartReadBuff[1] ==0x55)//判斷數(shù)據(jù)? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? if(UsartReadBuff[2] ==0x01)//? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? Invoke((newAction(() =>? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? button3.Text ="熄滅";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label5.Text ="點亮";

? ? ? ? ? ? ? ? ? ? ? ? ? ? })));

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? elseif(UsartReadBuff[2] ==0x00)

? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? Invoke((newAction(() =>? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? button3.Text ="點亮";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label5.Text ="熄滅";

? ? ? ? ? ? ? ? ? ? ? ? ? ? })));

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? //string str = serialPort1.ReadExisting();//讀出來當前緩存里面的所有數(shù)據(jù)

? ? ? ? ? ? //Invoke((new Action(() =>

? ? ? ? ? ? //{

? ? ? ? ? ? ////顯示在文本框里面

? ? ? ? ? ? //? ? textBox1.AppendText(str);

? ? ? ? ? ? //})));}

自己測試哈

現(xiàn)在說一下


?如果接收的是字符串,想顯示出來






如果發(fā)過來了16進制? ?注意哈,發(fā)過來的是16進制? 假設(shè) 00? 就是數(shù)字0? ?因為那個文本框顯示的時候是顯示的字符串

所以需要轉(zhuǎn)成? "00"? ? 發(fā)過來0F? ?需要顯示字符串形式的? "0F"


給大家準備好了

///<字節(jié)數(shù)組轉(zhuǎn)16進制字符串>///<param name="bytes"></param>///<returns> String 16進制顯示形式</returns>publicstaticstringbyteToHexStr(byte[] bytes)

? ? ? ? {

? ? ? ? ? ? stringreturnStr ="";

? ? ? ? ? ? try? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(bytes !=null)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? for(inti =0; i < bytes.Length; i++)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? returnStr += bytes[i].ToString("X2");

? ? ? ? ? ? ? ? ? ? ? ? returnStr +="";//兩個16進制用空格隔開,方便看數(shù)據(jù)? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? return returnStr;

? ? ? ? ? ? }

? ? ? ? ? ? catch (Exception)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return returnStr;

? ? ? ? ? ? }

? ? ? ? }


//串口接收到數(shù)據(jù)就會進入privatevoidserialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)

? ? ? ? {

? ? ? ? ? ? intlen = serialPort1.BytesToRead;//獲取可以讀取的字節(jié)數(shù)if(len >0)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? byte[] recvBytes =newbyte[len];//創(chuàng)建接收的數(shù)組serialPort1.Read(recvBytes,0, len);//接收數(shù)據(jù)? ? ? ? ? ? ? ? Invoke((newAction(() =>//顯示字符串? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? textBox1.AppendText("字符串:"+Encoding.Default.GetString(recvBytes));//顯示在文本框里面? ? ? ? ? ? ? ? })));

? ? ? ? ? ? ? ? Invoke((newAction(() =>//顯示16進制? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? textBox1.AppendText("\r\n16進制:"+ byteToHexStr(recvBytes) +"\r\n");//顯示在文本框里面? ? ? ? ? ? ? ? })));

? ? ? ? ? ? ? ? for(inti =0; i < len; i++)//拷貝數(shù)據(jù)到UsartReadBuff? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? UsartReadBuff[i+ UsartReadCnt] = recvBytes[i];//從上次的地方接著填入數(shù)據(jù)? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? UsartReadCnt = UsartReadCnt + len;//記錄上次的數(shù)據(jù)個數(shù)if(UsartReadCnt >=3)//接收到可以處理的數(shù)據(jù)個數(shù)? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? UsartReadCnt =0;

? ? ? ? ? ? ? ? ? ? if(UsartReadBuff[0] ==0xaa&& UsartReadBuff[1] ==0x55)//判斷數(shù)據(jù)? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? if(UsartReadBuff[2] ==0x01)//? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? Invoke((newAction(() =>? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? button3.Text ="熄滅";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label5.Text ="點亮";

? ? ? ? ? ? ? ? ? ? ? ? ? ? })));

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? elseif(UsartReadBuff[2] ==0x00)

? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? Invoke((newAction(() =>? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? button3.Text ="點亮";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label5.Text ="熄滅";

? ? ? ? ? ? ? ? ? ? ? ? ? ? })));

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }






?現(xiàn)在看發(fā)送

發(fā)送就只做字符串發(fā)送哈,,,16進制發(fā)送后期補上,,大家先吸收吸收現(xiàn)在的....





?執(zhí)行文件



我把16進制發(fā)送用到的函數(shù)放在這里,后期再回來加上

///<字符串轉(zhuǎn)16進制格式,不夠自動前面補零>//////</summary>///<param name="hexString"></param>///<returns></returns>privatestaticbyte[] strToToHexByte(String hexString)

? ? ? ? {

? ? ? ? ? ? int i;

? ? ? ? ? ? boolFlag =false;

? ? ? ? ? ? hexString = hexString.Replace("","");//清除空格if((hexString.Length %2) !=0)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? Flag =true;

? ? ? ? ? ? }

? ? ? ? ? ? if(Flag ==true)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? byte[] returnBytes =newbyte[(hexString.Length +1) /2];

? ? ? ? ? ? ? ? try? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? for(i =0; i < (hexString.Length -1) /2; i++)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? returnBytes[i] = Convert.ToByte(hexString.Substring(i *2,2),16);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? returnBytes[returnBytes.Length -1] = Convert.ToByte(hexString.Substring(hexString.Length -1,1).PadLeft(2,'0'),16);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? catch? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? for(i =0; i < returnBytes.Length; i++)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? returnBytes[i] =0;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? MessageBox.Show("超過16進制范圍A-F,已初始化為0","提示");

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? return returnBytes;

? ? ? ? ? ? }

? ? ? ? ? ? else? ? ? ? ? ? {

? ? ? ? ? ? ? ? byte[] returnBytes =newbyte[(hexString.Length) /2];

? ? ? ? ? ? ? ? try? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? for(i =0; i < returnBytes.Length; i++)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? returnBytes[i] = Convert.ToByte(hexString.Substring(i *2,2),16);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? catch? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? for(i =0; i < returnBytes.Length; i++)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? returnBytes[i] =0;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? MessageBox.Show("超過16進制范圍A-F,已初始化為0","提示");

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? return returnBytes;

? ? ? ? ? ? }

? ? ? ? }



對了,其實上位機串口是有空閑時間中斷的(異常捕獲),只不過,我還沒細研究呢!!!


https://www.cnblogs.com/yangfengwu/p/11094009.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容