上位机软件(C/Python/Java等)
直播中

陈安

未满1年用户 3经验值
擅长:嵌入式技术
私信 关注
[问答]

VS上位机开发串口应该注意什么,为何发送的数据单片机无回应

我用vs写了一个上位机,为了修改我的单片机的两个参数,现在遇到了一个问题就是,发送的命令格式对了,可是单片机没有回传应答数据,看不出来什么问题了,请教各位大牛们帮忙解决一下!

这是正常应该返回的单片机数据

image.png

这是我自己写的,如图,并没有数据返回

image.png

话不多说,直接上代码看

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace 串口助手
{
    public partial class 串口助手 : Form
    {
        public 串口助手()
        {
            InitializeComponent();
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//设置该属性 为false
        }
        /* 新增自定义函数:更新可用串口 */
        private void Updata_Serialport_Name(ComboBox MycomboBox)
        {
            string[] ArryPort;                               // 定义字符串数组,数组名为 ArryPort
            ArryPort = SerialPort.GetPortNames();            // SerialPort.GetPortNames()函数功能为获取计算机所有可用串口,以字符串数组形式输出
            MycomboBox.Items.Clear();                        // 清除当前组合框下拉菜单内容                  
            for (int i = 0; i < ArryPort.Length; i++)
            {
                MycomboBox.Items.Add(ArryPort[i]);           // 将所有的可用串口号添加到端口对应的组合框中
            }
        }

        private void 串口助手_Load(object sender, EventArgs e)
        {
            Updata_Serialport_Name(comboBoxPort);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Updata_Serialport_Name(comboBoxPort);// 定时刷新可用串口,可以保证在程序启动之后连接的设备也能被检测到
        }

        private void btnOpenSerialPort_Click(object sender, EventArgs e)
        {
            if (btnOpenSerialPort.Text == "打开串口")                                  // 如果当前是串口设备是关闭状态
            {
                try
                {
                    serialPort1.PortName = comboBoxPort.Text;                   // 将串口设备的串口号属性设置为comboBox1复选框中选择的串口号
                    serialPort1.BaudRate = Convert.ToInt32(comboBoxBaudRate.Text);  // 将串口设备的波特率属性设置为comboBox2复选框中选择的波特率
                    serialPort1.Open();                                      // 打开串口,如果打开了继续向下执行,如果失败了,跳转至catch部分
                    comboBoxPort.Enabled = false;                               // 串口已打开,将comboBox1设置为不可操作
                    comboBoxBaudRate.Enabled = false;                               // 串口已打开,将comboBox2设置为不可操作
                    btnOpenSerialPort.BackColor = Color.Red;                           // 将串口开关按键的颜色,改为红色
                    btnOpenSerialPort.Text = "关闭串口";                               // 将串口开关按键的文字改为“关闭串口”
                }
                catch
                {
                    MessageBox.Show("打开串口失败,请检查串口", "错误");     // 弹出错误对话框
                }
            }
            else                                             // 如果当前串口设备是打开状态
            {
                try
                {
                    serialPort1.Close();                     // 关闭串口
                    comboBoxPort.Enabled = true;                // 串口已关闭,将comboBox1设置为可操作
                    comboBoxBaudRate.Enabled = true;                // 串口已关闭,将comboBox2设置为可操作
                    btnOpenSerialPort.BackColor = Color.Lime;          // 将串口开关按键的颜色,改为青绿色
                    btnOpenSerialPort.Text = "打开串口";               // 将串口开关按键的文字改为“打开串口”
                }
                catch
                {
                    MessageBox.Show("关闭串口失败,请检查串口", "错误");   // 弹出错误对话框
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            textBoxStatus.Text = "";
        }

        private void btnSendCommand_Click(object sender, EventArgs e)
        {
            if (serialPort1 != null && serialPort1.IsOpen)
            {
                // 获取NumericUpDown控件的值
                int shakeTimesValue = (int)numericUpDownShakeTimes.Value;
                int shakeDelayValue = (int)numericUpDownShakeDelay.Value;

                // 将整数值转换为16进制字符串,并确保每个数字都是两位数
                string hexShakeTimes = shakeTimesValue.ToString("X2");
                string hexShakeDelay = shakeDelayValue.ToString("X2");

                // 构建命令字符串,例如 "AA BB 07 01 64 C8 FF"
                string commandStr = $"AA BB 07 01 {hexShakeTimes} {hexShakeDelay} FF";

                // 将16进制字符串转换为字节数组
                byte[] commandBytes = 
                {
                    0xAA, 0xBB, 0x07, 0x01,
                    Convert.ToByte(hexShakeTimes, 16),
                    Convert.ToByte(hexShakeDelay, 16),
                    0xFF
                };

                try
                {
                    // 发送命令
                    serialPort1.Write(commandBytes, 0, commandBytes.Length);
                    textBoxStatus.AppendText($"发送的命令:{commandStr}\r\n");
                }
                catch (Exception ex)
                {
                    textBoxStatus.AppendText($"发送命令失败:{ex.Message}\r\n");
                }
            }
            else
            {
                MessageBox.Show("串口未打开,请先打开串口。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                // 读取接收到的数据
                byte[] buffer = new byte[serialPort1.BytesToRead];
                serialPort1.Read(buffer, 0, buffer.Length);

                // 尝试以ASCII编码方式显示数据
                //string asciiString = Encoding.ASCII.GetString(buffer);
                //textBoxStatus.AppendText(asciiString);

                // 如果ASCII显示为乱码,尝试以UTF-8编码方式显示数据
                // string utf8String = Encoding.UTF8.GetString(buffer);
                //textBoxStatus.AppendText(utf8String);

                // 如果数据是16进制,可以这样显示
                 string hexString = BitConverter.ToString(buffer).Replace("-", " ");
                textBoxStatus.AppendText($"接收到的数据:{hexString}\r\n");
            }
            catch (Exception ex)
            {
                textBoxStatus.AppendText($"接收数据时发生错误: {ex.Message}\r\n");
            }
        }
    }
}

这是我串口的属性
image.png

希望能看出问题的哥们帮忙指正一下,好人一生平安!

已退回5积分

回帖(1)

他在笑

2024-6-6 18:10:34
在Visual Studio上位机开发串口时,需要注意以下几点:

1. 确保串口设置正确:检查波特率、数据位、停止位和奇偶校验位是否与单片机设置一致。

2. 确保单片机程序正确:检查单片机接收和发送数据的程序是否正确编写,确保单片机能够正确处理接收到的数据并发送响应。

3. 检查上位机发送数据格式:确保发送的数据格式与单片机接收的数据格式一致。

4. 使用合适的串口通信库:在Visual Studio中,可以使用System.IO.Ports命名空间下的SerialPort类进行串口通信。

5. 确保单片机和上位机连接正常:检查硬件连接是否正确,确保单片机和上位机之间的通信线路没有问题。

6. 检查异常处理:在代码中添加异常处理,以便在出现问题时能够及时发现并解决。

7. 使用调试工具:使用串口调试工具(如串口助手)来监控串口通信,以便发现问题。

针对您的问题,我建议您按照以下步骤进行排查:

1. 检查串口设置是否与单片机一致。

2. 使用串口调试工具监控单片机接收到的数据,确保单片机能够正确接收到上位机发送的数据。

3. 检查单片机程序,确保单片机能够正确处理接收到的数据并发送响应。

4. 在上位机代码中添加异常处理,以便在出现问题时能够及时发现并解决。

5. 如果以上步骤都无法解决问题,可以尝试在单片机和上位机之间添加一些调试信息,以便更好地定位问题所在。

希望以上建议能够帮助您解决问题。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分