VS上位机开发——串口助手

article/2025/9/26 18:06:20

VS上位机开发——串口助手

目录

  • VS上位机开发——串口助手
    • 一、新建项目
    • 二、控件布局
    • 三、编写程序
      • 1、端口更新函数
      • 2、启动窗口加载函数
      • 3、"打开串口"按键回调函数
      • 4、"清除接收"按键回调函数
      • 5、"发送"按键回调函数
      • 6、串口接收函数
      • 7、定时器中断回调函数
    • 四、运行
    • 五、结束语

第一次接触上位机的开发,单纯是为了玩一下,浅度学习,参考了一下其他文章,做了一个简单的串口助手,算是迈出了第一步。写博客记录一下学习的过程。

一、新建项目

第1步:创建一个Window窗体应用(.NET Framework)
我安装的是vs2019版本。
在这里插入图片描述

第2步:配置项目
提示:框架要选.NET Framework 4以上,如果没有,先确认项目选的是不是Window窗体应用,再确认是否安装NET Framework。
在这里插入图片描述

二、控件布局

我们先利用控件把串口助手的界面搭建出来。
提示:我们用到的控件都在工具箱里面。
在这里插入图片描述

我这里主要用了以下几个控件:

提示:控件名称是一个比较关键的参数,因为后面的代码要根据名称来写。

控件类型控件名称Text说明
TextBoxTextBox1TextBox1接收显示窗口
TextBoxTextBox2TextBox2发送输入窗口
labellabel1端口号文本提示
labellabel2波特率文本提示
comboBoxcomboBox1comboBox1端口号下拉菜单
comboBoxcomboBox2comboBox2波特率下拉菜单
buttonbutton1打开串口打开串口按键
buttonbutton2清除接收清除接收按键
buttonbutton3发送发送按键
checkBoxcheckBox1hex发送切换发送格式
checkBoxcheckBox2hex接收切换接收格式
serialPortserialPort1serialPort1串口通信控件
TimeTiime1Tiime1定时器,用于定时刷新端口

先把控件从工具箱里面拉出来,调整好大小和布局。
提示:TextBox要自由调整窗口大小的话需要把属性里面的MultiLine设置为True。
在这里插入图片描述

修改控件属性里面的Text,串口助手的界面就出来了。
在这里插入图片描述
再添加serialPort和Time控件,这两个是隐藏的控件,在窗口下方,实际运行的时候是看不见的。
在这里插入图片描述
选择波特率对应的comboBox控件,在Items属性里面添加常用的波特率。
在这里插入图片描述

三、编写程序

提示:可以双击控件窗口打开代码,也可以选中From,右键,选中查看代码
在这里插入图片描述

在实际应用中,最常用到的代码在Form1.cs和Form1.Designer.cs两个文件中。
注:Form1是新建窗体默认的名称,实际使用也可能不是这个名字。

Form1.cs是应用部分的代码,也就是我后面要编写的代码所在的文件。
Form1.Designer.cs里面存放各种控件的参数定义,在我们双击某一个控件的时候,实际上这个文件会在相应的生成一行代码,意思是在这个控件里面添加一个事件。

1、端口更新函数

这个函数是自定义的,需要自己添加进去

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

引用命名空间System.IO.Ports:
因为上面调用了SerialPort.GetPortNames()函数,需要引用这个命名空间才能使用

using System.IO.Ports;

在这里插入图片描述

2、启动窗口加载函数

双击设计界面窗口的空白区域,会自动生成一个Form1_Load空函数。
在Form1_Load函数里面添加以下代码:

Updata_Serialport_Name(comboBox1); // 调用更新可用串口函数,comboBox1为端口号组合框的名称

在默认启动函数里添加以下代码:

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//设置该属性 为false

在这里插入图片描述
提示:函数名不一定是Form1,这个函数名和自己的使用的窗体名称是一致的

3、"打开串口"按键回调函数

双击“打开串口”按键,会自动生成一个空函数。
在函数里面添加以下代码:

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

4、"清除接收"按键回调函数

双击“清除接收”按键,会自动生成一个空函数。
在函数里面添加以下代码:

textBox1.Text = "";

5、"发送"按键回调函数

双击“发送”按键,会自动生成一个空函数。
在函数里面添加以下代码:

if (serialPort1.IsOpen)            // 如果串口设备已经打开了
{if (!checkBox1.Checked)        // 如果是以字符的形式发送数据{char[] str = new char[1];  // 定义一个字符数组,只有一位try{for (int i = 0; i < textBox2.Text.Length; i++){str[0] = Convert.ToChar(textBox2.Text.Substring(i, 1));  // 取待发送文本框中的第i个字符serialPort1.Write(str, 0, 1);                            // 写入串口设备进行发送}}catch{MessageBox.Show("串口字符写入错误!", "错误");   // 弹出发送错误对话框serialPort1.Close();                          // 关闭串口button1.BackColor = Color.Lime;               // 将串口开关按键的颜色,改为青绿色button1.Text = "打开串口";                    // 将串口开关按键的文字改为“打开串口”}}else                                                  // 如果以数值的形式发送{byte[] Data = new byte[1];                        // 定义一个byte类型数据,相当于C语言的unsigned char类型int flag = 0;                                     // 定义一个标志,标志这是第几位try{for (int i = 0; i < textBox2.Text.Length; i++){if (textBox2.Text.Substring(i, 1) == " " && flag == 0)                // 如果是第一位,并且为空字符{continue;}if (textBox2.Text.Substring(i, 1) != " " && flag == 0)                // 如果是第一位,但不为空字符{flag = 1;                                                         // 标志转到第二位数据去if (i == textBox2.Text.Length - 1)                                // 如果这是文本框字符串的最后一个字符{Data[0] = Convert.ToByte(textBox2.Text.Substring(i, 1), 16);  // 转化为byte类型数据,以16进制显示serialPort1.Write(Data, 0, 1);                                // 通过串口发送flag = 0;                                                     // 标志回到第一位数据去}continue;}else if (textBox2.Text.Substring(i, 1) == " " && flag == 1)           // 如果是第二位,且第二位字符为空{Data[0] = Convert.ToByte(textBox2.Text.Substring(i - 1, 1), 16);  // 只将第一位字符转化为byte类型数据,以十六进制显示serialPort1.Write(Data, 0, 1);                                    // 通过串口发送flag = 0;                                                         // 标志回到第一位数据去continue;}else if (textBox2.Text.Substring(i, 1) != " " && flag == 1)           // 如果是第二位字符,且第一位字符不为空{Data[0] = Convert.ToByte(textBox2.Text.Substring(i - 1, 2), 16);  // 将第一,二位字符转化为byte类型数据,以十六进制显示serialPort1.Write(Data, 0, 1);                                    // 通过串口发送flag = 0;                                                         // 标志回到第一位数据去continue;}}}catch{MessageBox.Show("串口数值写入错误!", "错误");serialPort1.Close();button1.BackColor = Color.Lime;   // 将串口开关按键的颜色,改为青绿色button1.Text = "打开串口";        // 将串口开关按键的文字改为  “打开串口”}}
}

6、串口接收函数

点击serialPort控件,在该控件的事件里面有一个DataReceived事件,双击它会生成一个数据接收的空函数
在这里插入图片描述

在函数里面添加以下代码:

if (!checkBox2.Checked)                        // 如果以字符串形式读取
{string str = serialPort1.ReadExisting();   // 读取串口接收缓冲区字符串textBox1.AppendText(str + "");             // 在接收文本框中进行显示
}
else                                           // 以数值形式读取
{int length = serialPort1.BytesToRead;      // 读取串口接收缓冲区字节数byte[] data = new byte[length];            // 定义相同字节的数组serialPort1.Read(data, 0, length);         // 串口读取缓冲区数据到数组中for (int i = 0; i < length; i++){string str = Convert.ToString(data[i], 16).ToUpper();                          // 将数据转换为字符串格式textBox1.AppendText("0X" + (str.Length == 1 ? "0" + str + " " : str + " "));   // 添加到串口接收文本框中}
}

7、定时器中断回调函数

在timer控件的属性里面打开使能,设置定时时间为500ms
在这里插入图片描述
双击timer控件,会自动生成一个空函数
在函数里面添加以下代码:

Updata_Serialport_Name(comboBox1);   // 定时刷新可用串口,可以保证在程序启动之后连接的设备也能被检测到

最后再贴一个完整的代码:
提示:不能直接跳过前面的步骤直接把完整的代码拷贝过去,因为前面双击控件的操作不仅仅是生成空函数,也会在Designer里面添加对应的事件,如果直接拷贝就不会产生事件。当然,如果非要这样操作也不是不行,只要在Form1.Designer.cs文件里面把每个控件对应的事件加上即可。

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 Form1 : Form{public Form1(){InitializeComponent();System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//设置该属性 为false}/* 新增自定义函数:更新可用串口 */private void Updata_Serialport_Name(ComboBox MycomboBox){string[] ArryPort;                               // 定义字符串数组,数组名为 ArryPortArryPort = SerialPort.GetPortNames();            // SerialPort.GetPortNames()函数功能为获取计算机所有可用串口,以字符串数组形式输出MycomboBox.Items.Clear();                        // 清除当前组合框下拉菜单内容                  for (int i = 0; i < ArryPort.Length; i++){MycomboBox.Items.Add(ArryPort[i]);           // 将所有的可用串口号添加到端口对应的组合框中}}/* 启动窗口加载函数 */private void Form1_Load(object sender, EventArgs e){Updata_Serialport_Name(comboBox1);               // 调用更新可用串口函数,comboBox1为端口号组合框的名称}/* "打开串口"按键回调函数 */private void button1_Click(object sender, EventArgs e){if (button1.Text == "打开串口")                                  // 如果当前是串口设备是关闭状态{try                                                          // try 是尝试部分,如果尝试过程中出现问题,进入catch部分,执行错误处理代码  {serialPort1.PortName = comboBox1.Text;                   // 将串口设备的串口号属性设置为comboBox1复选框中选择的串口号serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);  // 将串口设备的波特率属性设置为comboBox2复选框中选择的波特率serialPort1.Open();                                      // 打开串口,如果打开了继续向下执行,如果失败了,跳转至catch部分comboBox1.Enabled = false;                               // 串口已打开,将comboBox1设置为不可操作comboBox2.Enabled = false;                               // 串口已打开,将comboBox2设置为不可操作button1.BackColor = Color.Red;                           // 将串口开关按键的颜色,改为红色button1.Text = "关闭串口";                               // 将串口开关按键的文字改为“关闭串口”}catch{MessageBox.Show("打开串口失败,请检查串口", "错误");     // 弹出错误对话框}}else                                             // 如果当前串口设备是打开状态{try{serialPort1.Close();                     // 关闭串口comboBox1.Enabled = true;                // 串口已关闭,将comboBox1设置为可操作comboBox2.Enabled = true;                // 串口已关闭,将comboBox2设置为可操作button1.BackColor = Color.Lime;          // 将串口开关按键的颜色,改为青绿色button1.Text = "打开串口";               // 将串口开关按键的文字改为“打开串口”}catch{MessageBox.Show("关闭串口失败,请检查串口", "错误");   // 弹出错误对话框}}}/* "清除接收"按键回调函数 */private void button2_Click(object sender, EventArgs e){textBox1.Text = "";}/* "发送"按键回调函数 */private void button3_Click(object sender, EventArgs e){if (serialPort1.IsOpen)            // 如果串口设备已经打开了{if (!checkBox1.Checked)        // 如果是以字符的形式发送数据{char[] str = new char[1];  // 定义一个字符数组,只有一位try{for (int i = 0; i < textBox2.Text.Length; i++){str[0] = Convert.ToChar(textBox2.Text.Substring(i, 1));  // 取待发送文本框中的第i个字符serialPort1.Write(str, 0, 1);                            // 写入串口设备进行发送}}catch{MessageBox.Show("串口字符写入错误!", "错误");   // 弹出发送错误对话框serialPort1.Close();                          // 关闭串口button1.BackColor = Color.Lime;               // 将串口开关按键的颜色,改为青绿色button1.Text = "打开串口";                    // 将串口开关按键的文字改为“打开串口”}}else                                                  // 如果以数值的形式发送{byte[] Data = new byte[1];                        // 定义一个byte类型数据,相当于C语言的unsigned char类型int flag = 0;                                     // 定义一个标志,标志这是第几位try{for (int i = 0; i < textBox2.Text.Length; i++){if (textBox2.Text.Substring(i, 1) == " " && flag == 0)                // 如果是第一位,并且为空字符{continue;}if (textBox2.Text.Substring(i, 1) != " " && flag == 0)                // 如果是第一位,但不为空字符{flag = 1;                                                         // 标志转到第二位数据去if (i == textBox2.Text.Length - 1)                                // 如果这是文本框字符串的最后一个字符{Data[0] = Convert.ToByte(textBox2.Text.Substring(i, 1), 16);  // 转化为byte类型数据,以16进制显示serialPort1.Write(Data, 0, 1);                                // 通过串口发送flag = 0;                                                     // 标志回到第一位数据去}continue;}else if (textBox2.Text.Substring(i, 1) == " " && flag == 1)           // 如果是第二位,且第二位字符为空{Data[0] = Convert.ToByte(textBox2.Text.Substring(i - 1, 1), 16);  // 只将第一位字符转化为byte类型数据,以十六进制显示serialPort1.Write(Data, 0, 1);                                    // 通过串口发送flag = 0;                                                         // 标志回到第一位数据去continue;}else if (textBox2.Text.Substring(i, 1) != " " && flag == 1)           // 如果是第二位字符,且第一位字符不为空{Data[0] = Convert.ToByte(textBox2.Text.Substring(i - 1, 2), 16);  // 将第一,二位字符转化为byte类型数据,以十六进制显示serialPort1.Write(Data, 0, 1);                                    // 通过串口发送flag = 0;                                                         // 标志回到第一位数据去continue;}}}catch{MessageBox.Show("串口数值写入错误!", "错误");serialPort1.Close();button1.BackColor = Color.Lime;   // 将串口开关按键的颜色,改为青绿色button1.Text = "打开串口";        // 将串口开关按键的文字改为  “打开串口”}}}}/* 串口接收函数 */private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e){if (!checkBox2.Checked)                        // 如果以字符串形式读取{string str = serialPort1.ReadExisting();   // 读取串口接收缓冲区字符串textBox1.AppendText(str + "");             // 在接收文本框中进行显示}else                                           // 以数值形式读取{int length = serialPort1.BytesToRead;      // 读取串口接收缓冲区字节数byte[] data = new byte[length];            // 定义相同字节的数组serialPort1.Read(data, 0, length);         // 串口读取缓冲区数据到数组中for (int i = 0; i < length; i++){string str = Convert.ToString(data[i], 16).ToUpper();                          // 将数据转换为字符串格式textBox1.AppendText("0X" + (str.Length == 1 ? "0" + str + " " : str + " "));   // 添加到串口接收文本框中}}}/* 定时器中断回调函数 */private void timer1_Tick(object sender, EventArgs e){Updata_Serialport_Name(comboBox1);   // 定时刷新可用串口,可以保证在程序启动之后连接的设备也能被检测到}}
}

四、运行

在vs里面调试运行结果如下:
在这里插入图片描述
我这里连接了一个树莓派,数据收发测试正常

如果需要在其他PC端运行,可以把工程目录下bin文件里面的Debug拷贝出来,运行exe文件即可,不需要再安装vs
在这里插入图片描述

五、结束语

简单的做了一个串口助手,总体来说其实不难,不熟悉C#语法也没关系,我也是第一次接触C#,根据C语言的经验去摸索,代码基本都能看的懂,有些语法也是即学即用的。好了,关于这一讲的内容就到这里,如果有什么问题,欢迎在评论区留言讨论,谢谢。

源码下载:https://download.csdn.net/download/ShenZhen_zixian/21712034


http://chatgpt.dhexx.cn/article/BVb8Ia1x.shtml

相关文章

C++刷题笔记(4)——leetcode209、904

题目1&#xff1a;209.长度最小的子数组 暴力解法 解题思路&#xff1a; 用两个for循环&#xff0c;外层for循环负责做子序列的起点&#xff0c;内层for循环负责遍历数组&#xff0c;寻找符合条件的子序列 然后外层for循环移动子序列的起点&#xff0c;继续再数组中寻找新的符…

904. 水果成篮(c++)

滑动窗口&#xff1a; class Solution { public:int totalFruit(vector<int>& fruits) {int max_len 0;int left 0;unordered_map<int,int>mp;for(int right 0; right < fruits.size();right){mp[fruits[right]];while(mp.size() > 2){mp[fruits[lef…

904-线程池项目死锁问题分析

死锁问题 1、在ThreadPool的资源回收&#xff0c;等待线程池所有线程退出时&#xff0c;发生死锁问题&#xff0c;导致进程无法退出 我们的资源回收代码如下&#xff1a; //线程池析构 ThreadPool::~ThreadPool() {isPoolRunning_ false;notEmpty_.notify_all();//等待线程…

ORACLE 错误 904

错误原因&#xff1a; Oracle 版本中IMP和EXP的兼容问题。 我这里是因为本机上的oracle版本高于服务器上的oracle版本 解决办法&#xff1a; 安装和服务器同版本的10g客户端&#xff0c;在命令窗口化中切换到10g客户端的bin目录下面进行导入就ok了。 为什么要切换呢&#xf…

leetcode:904. 水果成篮

题目来源 leetcode&#xff1a;904. 水果成篮 题目描述 题目解析 题意 题意从任意位置开始&#xff0c;若最多只能收集两种水果&#xff0c;问最多能收集多少个水果。 这道题目可以理解为求只包含两种元素的最长连续子序列&#xff0c;和leetcode&#xff1a;159.最多有两个…

2022-7-8 Leetcode 904.水果成篮

错误的代码&#xff1a; class Solution { public:int totalFruit(vector<int>& fruits) {int start 0;int end 0;set<int> myset;int len 0;for (; end < fruits.size(); end){myset.insert(fruits[end]);if (myset.size() > 2 && start &l…

【LeetCode】图解 904. 水果成篮

904. 水果成篮 904. 水果成篮 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xf…

LeetCode_904 水果成篮

1、题目&#xff1a;水果成篮 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xff0c…

力扣第904题

一、题目&#xff1a;904. 水果成篮 二、题目解析&#xff1a; 题目解析&#xff1a;题目不太好理解&#xff0c;通俗解释一下&#xff0c;可以把数组中的每个元素理解成一个树&#xff0c;元素值理解成那种类型的果树&#xff0c;比如:[3,3,3,1,2,1,1,2,3,3,4] 我们可以认为1…

LeetCode 904. 水果成篮

904. 水果成篮 题目&#xff1a;你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xf…

力扣(LeetCode)904. 水果成篮(C语言)

一、环境说明 本文是 LeetCode 904题 : 水果成篮&#xff0c;使用c语言实现滑动窗口哈希集合。测试环境:Visual Studio 2019 二、代码展示 //滑动窗口哈希表&#xff0c;一次遍历O(n) //难点&#xff1a;如何用判断边界的移动时机,应该可以自己实现。 //right和left不一定相…

(解决方案) Visual Studio 2019 连接 SQL Server 2019 数据库时,数据库版本为904无法打开,此服务器支持852版及更低版本的问题

我在做课设程序时连不上数据库&#xff0c;提示数据库版本太高。即使在数据库设置里把兼容性改到2016(852版)仍然无法连接&#xff0c;网上找的解决方法也不成功&#xff0c;自己摸索了一番找到了解决方法。具体是直接连接数据库的服务器&#xff0c;而不是连接数据库本身&…

【Linux】make的工作原理和makefile文件

● makefile文件 make是一个命令&#xff0c;makefile是一个文件。make命令执行时&#xff0c;需要一个 Makefile 文件&#xff0c;以告诉make命令需要怎么样的去编译和链接程序。一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;ma…

简单的makefile文件编写

习惯了windows下ide创建工程已经代码的编写&#xff0c;然后一键运行&#xff0c;很简单&#xff0c;因为很多事ide都帮我们做了&#xff0c;但是linux下不一样&#xff0c;需要手动编译&#xff0c;执行一条条的命令&#xff0c;一般工程都是由于很多文件组成的&#xff0c;比…

如何编写一个简单的Makefile文件

在c语言学习的初级阶段&#xff0c;我们所写的代码量较少&#xff0c;分装的文件也很少&#xff0c;直接使用gcc编译便能满足我们的大部分需求&#xff0c;然而随着我们学习的深入&#xff0c;代码量越来越多&#xff0c;已经开始做一些工程项目了&#xff0c;项目中包含多个c文…

Linux下编写makefile文件

首先在vi编辑器下编写add.c #include "test.h" #include <stdio.h> int add(int a, int b) { return a b; } int main() { printf(" 2 3 %d\n", add(2, 3)); printf(" 5 - 3 %d\n", sub(5, 3)); return 1; } 再编写sub.c…

如何创建 makefile文件

在学习 任哲《嵌入式实时操作系统 uCOS-II 原理及应用》中如何创建makefile文件呢&#xff1f; 1&#xff0c;创建一个名为makefile的文件&#xff08;取消扩展名&#xff09; 输入下面命令示例内容 target1: md 11 target2: md 22 target3: rd 11 rd 22 2&am…

Makefile文件的简单编写

参考&#xff1a; MakeFile文件是什么——内容、工作原理、作用、使用 嵌入式操作系统linux篇&#xff08;书&#xff09; Makefile伪目标 GNU make中文手册.pdf 在嵌入式开发中&#xff0c;一个工程中的源文件是非常多的&#xff0c;如果一个个编译会很麻烦&#xff0c;Makefi…

带你去了解什么是makefile文件

GNU make命令是用来控制从源文件生成可执行文件或非可执行文件的方式。那么make命令又是通过makefile文件来控制了。所以了解makefile文件就显得很有必要了。 makefile文件由许多规则组成&#xff0c;这些规则的形式一般是这样的&#xff1a; 目标 ... : 先决条件 ...命令目标…

linux下制作makefile文件

1.最简单的一种当然也是最麻烦的一种(makefile 中的代码如下&#xff0c;其中hello.cpp是文件名&#xff0c;hello是编译后的命名。使用方法是直接输入 make) hello:hello.cpp …