9-ESP8266 SDK開發基礎入門篇--編寫串口上位機軟件

http://www.javashuo.com/article/p-hqatrkow-x.html

 

頁面修改爲這樣子html

 

 

            

 

 

 

 

如今看串口發送數據 數組

點擊點亮 發送0xaa 0x55 0x01    緩存

 我電腦上安裝了虛擬串口軟件,虛擬出來了COM1和COM2,而後COM1發送的數據會發給COM2  COM2發送的數據會發給COM1函數

你們若是有兩個串口模塊也能夠測試

 

 

 

 

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

 

 

 

那個按鈕的程序這樣寫spa

 

 

 測試一下線程

 

 

 

如今看串口接收數據3d

 

 

 

 說一下哈,這個是上位機的串口中斷函數,就是隻要接收到數據就會進入這個中斷code

如今咱讀出來接收的數據,而後顯示在

 

 讀取數據給了好幾個方法

咱就說1個,哈哈哈,其實本身一選擇方法的時候就有中文註釋......

 

 

你們注沒注意

 

 

如今調用一個函數讀出來,而後顯示出來

 

 

ReadExisting()   這個方法就會返回緩衝區裏面的全部字節,注意返回的是字符串形式的

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

 

由於咱就是要裏面的數據因此  

string str = serialPort1.ReadExisting();//讀出來當前緩存裏面的全部數據

 

 

 

Invoke((new Action(() =>
{
    這裏面放要操做的主線程的控件的方法
})));

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

 

 

 

 說明能夠了,如今呢,咱去掉

 

 

 

 

 

 你們能夠點開那個  如何跨線程調用 Windows 窗體控件

你們能夠看這個 http://www.javashuo.com/article/p-bcpnbylk-r.html   (最好別看,看了就會感受麻煩)

4.0以後引進了這種方法

 

 對於初學者知道這個就能夠了,像C#,C++,JAVA等等這種高級語言哈,由於能夠作界面了,,高級語言規定,操做頁面不能在子線程中進行

哪些是子線程呢!..像上面那個串口中斷函數,還有本身建立的任務Thread,,,等等吧

好如今,咱接收16進制,

接收到

 

0xaa 0x55 0x01  

 

 

0xaa 0x55 0x00  

 

 

 好,上菜

 

        //串口接收到數據就會進入
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int len = serialPort1.BytesToRead;//獲取能夠讀取的字節數
            if (len > 0)
            {
                byte[] recvBytes = new byte[len];//建立接收的數組
                serialPort1.Read(recvBytes, 0, len);//接收數據
                if (recvBytes[0] == 0xaa && recvBytes[1] == 0x55)//判斷數據
                {
                    if (recvBytes[2] == 0x01)//
                    {
                        Invoke((new Action(() =>
                        {
                            button3.Text = "熄滅";
                            label5.Text = "點亮";
                        })));
                    }
                    else if (recvBytes[2] == 0x00)
                    {
                        Invoke((new Action(() =>
                        {
                            button3.Text = "點亮";
                            label5.Text = "熄滅";
                        })));
                    }
                }
            }
            //string str = serialPort1.ReadExisting();//讀出來當前緩存裏面的全部數據
            //Invoke((new Action(() =>
            //{
            //    //顯示在文本框裏面
            //    textBox1.AppendText(str);
            //})));
        }

 

 

 

 

 

 

 

 

 測試

 

 

 

 

 

 雖然能夠了,可是這樣寫不保險...

緣由是那個中斷是不定長的數據就進去(受到電腦總體運行狀態的影響),因此呢咱優化下

 

 

        //串口接收到數據就會進入
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int len = serialPort1.BytesToRead;//獲取能夠讀取的字節數
            if (len > 0)
            {
                byte[] recvBytes = new byte[len];//建立接收的數組
                serialPort1.Read(recvBytes, 0, len);//接收數據

                for (int i = 0; i < len; i++)//拷貝數據到UsartReadBuff
                {
                    UsartReadBuff[i+ UsartReadCnt] = recvBytes[i];//從上次的地方接着填入數據
                }
                UsartReadCnt = UsartReadCnt + len;//記錄上次的數據個數
                if (UsartReadCnt >= 3)//接收到能夠處理的數據個數
                {
                    UsartReadCnt = 0;
                    if (UsartReadBuff[0] == 0xaa && UsartReadBuff[1] == 0x55)//判斷數據
                    {
                        if (UsartReadBuff[2] == 0x01)//
                        {
                            Invoke((new Action(() =>
                            {
                                button3.Text = "熄滅";
                                label5.Text = "點亮";
                            })));
                        }
                        else if (UsartReadBuff[2] == 0x00)
                        {
                            Invoke((new Action(() =>
                            {
                                button3.Text = "點亮";
                                label5.Text = "熄滅";
                            })));
                        }
                    }
                }
            }
            //string str = serialPort1.ReadExisting();//讀出來當前緩存裏面的全部數據
            //Invoke((new Action(() =>
            //{
            //    //顯示在文本框裏面
            //    textBox1.AppendText(str);
            //})));
        }

本身測試哈

如今說一下

 

 若是接收的是字符串,想顯示出來

 

 

 

 

 

 

若是發過來了16進制   注意哈,發過來的是16進制  假設 00  就是數字0   由於那個文本框顯示的時候是顯示的字符串

因此須要轉成  "00"    發過來0F   須要顯示字符串形式的  "0F"

 

給你們準備好了

        /// <字節數組轉16進制字符串>
        /// <param name="bytes"></param>
        /// <returns> String 16進制顯示形式</returns>
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            try
            {
                if (bytes != null)
                {
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        returnStr += bytes[i].ToString("X2");
                        returnStr += " ";//兩個16進制用空格隔開,方便看數據
                    }
                }
                return returnStr;
            }
            catch (Exception)
            {
                return returnStr;
            }
        }

 

        //串口接收到數據就會進入
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int len = serialPort1.BytesToRead;//獲取能夠讀取的字節數
            if (len > 0)
            {
                byte[] recvBytes = new byte[len];//建立接收的數組
                serialPort1.Read(recvBytes, 0, len);//接收數據

                Invoke((new Action(() =>//顯示字符串
                {
                    textBox1.AppendText("字符串:"+Encoding.Default.GetString(recvBytes)); //顯示在文本框裏面
                })));

                Invoke((new Action(() =>//顯示16進制
                {
                    textBox1.AppendText("\r\n16進制:" + byteToHexStr(recvBytes) + "\r\n"); //顯示在文本框裏面
                })));

                for (int i = 0; i < len; i++)//拷貝數據到UsartReadBuff
                {
                    UsartReadBuff[i+ UsartReadCnt] = recvBytes[i];//從上次的地方接着填入數據
                }
                UsartReadCnt = UsartReadCnt + len;//記錄上次的數據個數
                if (UsartReadCnt >= 3)//接收到能夠處理的數據個數
                {
                    UsartReadCnt = 0;
                    if (UsartReadBuff[0] == 0xaa && UsartReadBuff[1] == 0x55)//判斷數據
                    {
                        if (UsartReadBuff[2] == 0x01)//
                        {
                            Invoke((new Action(() =>
                            {
                                button3.Text = "熄滅";
                                label5.Text = "點亮";
                            })));
                        }
                        else if (UsartReadBuff[2] == 0x00)
                        {
                            Invoke((new Action(() =>
                            {
                                button3.Text = "點亮";
                                label5.Text = "熄滅";
                            })));
                        }
                    }
                }
            }
        }

 

 

 

 

 

 

 

 如今看發送

發送就只作字符串發送哈,,,16進制發送後期補上,,你們先吸取吸取如今的....

 

 

 

 

 

 執行文件

 

 

我把16進制發送用到的函數放在這裏,後期再回來加上

        /// <字符串轉16進制格式,不夠自動前面補零>
        /// 
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private static byte[] strToToHexByte(String hexString)
        {
            int i;
            bool Flag = false;


            hexString = hexString.Replace(" ", "");//清除空格
            if ((hexString.Length % 2) != 0)
            {
                Flag = true;
            }
            if (Flag == true)
            {
                byte[] returnBytes = new byte[(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 = new byte[(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;
            }
        }

 

 

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

 

http://www.javashuo.com/article/p-vgkgdsja-x.html

相關文章
相關標籤/搜索