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

相关文章
相关标签/搜索