Chan_1109 2024-06-05 21:47 采纳率: 0%
浏览 37

VS上位机开发串口助手发送数据收不到单片机的回传,问题出在哪

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

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

img

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

img

话不多说,直接上代码


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");
            }
        }
    }
}

这是我串口的属性

img

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

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-06-05 22:01
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    根据您提供的信息和代码,我将尝试帮助您诊断问题并提供一些可能的解决方案。首先,让我们逐步检查可能的问题点:

    1. 串口属性设置

      • 确保单片机和上位机的串口设置完全匹配。这包括波特率、数据位、停止位和奇偶校验。从您提供的属性截图来看,这些设置似乎都是正确的。
    2. 串口号

      • 您在代码中使用的串口号是 COM1,但根据您提供的截图,单片机可能连接到了 COM22。请确保您在代码中使用的串口号与实际连接的串口号相匹配。
    3. 发送和接收数据

      • 您的代码中发送数据的部分看起来是正确的。但是,接收数据部分可能需要一些调整。您当前的 serialPort1_DataReceived 方法中,尝试以ASCII和UTF-8编码显示数据,但后来被注释掉了。如果您期望接收的是16进制数据,那么您当前的实现(将接收到的数据转换为16进制字符串)是正确的。
    4. 异常处理

      • serialPort1_DataReceived 方法中,您已经添加了异常处理,这是很好的实践。确保异常信息能够正确地显示在 textBoxStatus 中,这样可以帮助您诊断问题。
    5. 单片机端的实现

      • 确保单片机端的代码能够正确地处理接收到的命令,并发送预期的响应。如果可能,请检查单片机端的串口中断服务程序或相关的通信处理代码。
    6. 调试和日志记录

      • 在发送和接收数据的方法中添加更多的日志记录,这可以帮助您跟踪数据流动和识别问题所在。
    7. 硬件连接

      • 检查物理连接,确保串口线没有损坏,并且连接正确。
    8. 串口助手软件

      • 您提供的截图中显示了使用其他串口助手软件时的通信情况。这表明单片机能够响应某些命令。尝试使用相同的命令格式在您的VS上位机中发送,看看是否能够得到响应。

    如果以上检查都没有发现问题,您可以尝试以下步骤:

    • 使用串口调试助手

      • 使用其他串口调试软件(如PuTTY、Tera Term等)来测试单片机的响应,以确保问题不是出在单片机端。
    • 简化代码

      • 简化您的发送和接收代码,只发送和接收最简单的数据(例如,只发送一个字节,然后检查是否能够接收到)。
    • 检查电源和干扰

      • 确保单片机的电源稳定,检查是否有可能的电磁干扰影响通信。
    • 更新驱动程序

      • 检查并更新计算机的串口驱动程序。
    • 查看串口助手的文档

      • 如果您使用的是第三方的串口助手库,请查看其文档以确保您正确地使用了库中的所有功能。

    希望这些建议能够帮助您解决问题。如果问题仍然存在,请提供更多的信息,例如单片机端的代码实现,以便进一步分析。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月5日