VS上位机开发——串口助手
目录
第一次接触上位机的开发,单纯是为了玩一下,浅度学习,参考了一下其他文章,做了一个简单的串口助手,算是迈出了第一步。写博客记录一下学习的过程。
一、新建项目
第1步:创建一个Window窗体应用(.NET Framework)
我安装的是vs2019版本。
第2步:配置项目
提示:框架要选.NET Framework 4以上,如果没有,先确认项目选的是不是Window窗体应用,再确认是否安装NET Framework。
二、控件布局
我们先利用控件把串口助手的界面搭建出来。
提示:我们用到的控件都在工具箱里面。
我这里主要用了以下几个控件:
提示:控件名称是一个比较关键的参数,因为后面的代码要根据名称来写。
控件类型 | 控件名称 | Text | 说明 |
---|---|---|---|
TextBox | TextBox1 | TextBox1 | 接收显示窗口 |
TextBox | TextBox2 | TextBox2 | 发送输入窗口 |
label | label1 | 端口号 | 文本提示 |
label | label2 | 波特率 | 文本提示 |
comboBox | comboBox1 | comboBox1 | 端口号下拉菜单 |
comboBox | comboBox2 | comboBox2 | 波特率下拉菜单 |
button | button1 | 打开串口 | 打开串口按键 |
button | button2 | 清除接收 | 清除接收按键 |
button | button3 | 发送 | 发送按键 |
checkBox | checkBox1 | hex发送 | 切换发送格式 |
checkBox | checkBox2 | hex接收 | 切换接收格式 |
serialPort | serialPort1 | serialPort1 | 串口通信控件 |
Time | Tiime1 | Tiime1 | 定时器,用于定时刷新端口 |
先把控件从工具箱里面拉出来,调整好大小和布局。
提示: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; // 定义字符串数组,数组名为 ArryPort
ArryPort = SerialPort.GetPortNames(); // SerialPort.GetPortNames()函数功能为获取计算机所有可用串口,以字符串数组形式输出
MycomboBox.Items.Clear(); // 清除当前组合框下拉菜单内容
for (int i = 0; i < ArryPort.Length; i++)
{
MycomboBox.Items.Add(ArryPort[i]); // 将所有的可用串口号添加到端口对应的组合框中
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
引用命名空间System.IO.Ports:
因为上面调用了SerialPort.GetPortNames()函数,需要引用这个命名空间才能使用
using System.IO.Ports;
- 1
2、启动窗口加载函数
双击设计界面窗口的空白区域,会自动生成一个Form1_Load空函数。
在Form1_Load函数里面添加以下代码:
Updata_Serialport_Name(comboBox1); // 调用更新可用串口函数,comboBox1为端口号组合框的名称
- 1
在默认启动函数里添加以下代码:
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//设置该属性 为false
- 1
提示:函数名不一定是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("关闭串口失败,请检查串口", "错误"); // 弹出错误对话框
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
4、"清除接收"按键回调函数
双击“清除接收”按键,会自动生成一个空函数。
在函数里面添加以下代码:
textBox1.Text = "";
- 1
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 = “打开串口”; // 将串口开关按键的文字改为 “打开串口”
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
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 + ” ")); // 添加到串口接收文本框中
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
7、定时器中断回调函数
在timer控件的属性里面打开使能,设置定时时间为500ms
双击timer控件,会自动生成一个空函数
在函数里面添加以下代码:
Updata_Serialport_Name(comboBox1); // 定时刷新可用串口,可以保证在程序启动之后连接的设备也能被检测到
- 1
最后再贴一个完整的代码:
提示:不能直接跳过前面的步骤直接把完整的代码拷贝过去,因为前面双击控件的操作不仅仅是生成空函数,也会在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; // 定义字符串数组,数组名为 ArryPort
ArryPort = 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); // 定时刷新可用串口,可以保证在程序启动之后连接的设备也能被检测到
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
四、运行
在vs里面调试运行结果如下:
我这里连接了一个树莓派,数据收发测试正常
如果需要在其他PC端运行,可以把工程目录下bin文件里面的Debug拷贝出来,运行exe文件即可,不需要再安装vs
五、结束语
简单的做了一个串口助手,总体来说其实不难,不熟悉C#语法也没关系,我也是第一次接触C#,根据C语言的经验去摸索,代码基本都能看的懂,有些语法也是即学即用的。好了,关于这一讲的内容就到这里,如果有什么问题,欢迎在评论区留言讨论,谢谢。
源码下载:https://download.csdn.net/download/ShenZhen_zixian/21712034
欢迎使用Markdown编辑器
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC
语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
设定内容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" | “Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
创建一个自定义列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎