写这篇内容,不是因为有什么技术或者什么难题要说,而是因为我在开始的时候没有搜到网络上有相关的好用的资料,所以把我自己简单弄的一个例子发上来,帮助初学的人对整个技术有个了解,快速使用,我方便你,你也方便我。
本文内容实现的是通过web页面远程操作服务端的串口,具体功能有打开关闭串口,串口发送,串口接收刷新显示(使用UpdatePanel实现局部刷新)。
我这个人不怎么会说话,所以直接上干货,由于没有加css,现在的最终界面是这样的
先上页面xml代码,下面再上后台代码。
xml代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MainForm.aspx.cs" Inherits="TestSerialPort.MainForm" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>简易串口远程控制器</title>
</head>
<body>
<form id="form1" runat="server">
<h1>简易串口控制器</h1>
<div>
<label>串口号:</label>
<select id="portName" runat="server">
<option value="COM1">COM1</option>
<option value="COM2">COM2</option>
</select>
</div>
<div>
<label>波特率:</label>
<select id="baudRate" runat="server">
<option value="4800">4800</option>
<option value="9600">9600</option>
<option value="115200">115200</option>
</select>
</div>
<div>
<asp:Button ID="openBtn" runat="server" Text="打开串口" OnClick="openBtn_Click" />
<asp:Button ID="closeBtn" runat="server" Text="关闭串口" OnClick="closeBtn_Click" />
</div>
<div>
<input type="text" id="sendText" runat="server" />
<asp:Button ID="sendBtn" runat="server" Text="发送" OnClick="sendBtn_Click" />
</div>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" ChildrenAsTriggers="False" UpdateMode="Conditional">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="500" OnTick="Timer1_Tick" >
</asp:Timer>
<textarea id="receiveText" runat="server" cols="30" name="S1" rows="10"></textarea>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
后台代码如下
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.ModelBinding;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TestSerialPort
{
public partial class MainForm : System.Web.UI.Page
{
private static readonly SerialPort serailPort = new SerialPort();
protected void Page_Load(object sender, EventArgs e)
{
}
protected string GetComNums()
{
var nums = SerialPort.GetPortNames();
StringBuilder sb = new StringBuilder();
foreach(var item in nums)
{
sb.Append(string.Format("<option value='{0}'>{1}</option>",item,item));
}
return sb.ToString();
}
protected void openBtn_Click(object sender, EventArgs e)
{
if (IsPostBack)
{
PortConfig rsvp = new PortConfig();
if (TryUpdateModel(rsvp, new FormValueProvider(ModelBindingExecutionContext)))
{
if (!serailPort.IsOpen)
{
serailPort.PortName = rsvp.PortName;
serailPort.BaudRate = rsvp.BaudRate;
serailPort.DataReceived += SerailPort_DataReceived;
serailPort.Open();
}
}
}
}
static string receiveStr="";
private void SerailPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if(serailPort.BytesToRead>0)
{
var count = serailPort.BytesToRead;
byte[] buffer = new byte[count];
serailPort.Read(buffer,0,count);
receiveStr = System.Text.Encoding.Default.GetString(buffer);
}
}
protected void closeBtn_Click(object sender, EventArgs e)
{
if (serailPort.IsOpen)
{
serailPort.DataReceived-= SerailPort_DataReceived;
serailPort.Close();
}
}
protected void sendBtn_Click(object sender, EventArgs e)
{
if (IsPostBack)
{
PortConfig rsvp = new PortConfig();
if (TryUpdateModel(rsvp, new FormValueProvider(ModelBindingExecutionContext)))
{
if (serailPort.IsOpen)
{
serailPort.WriteLine(rsvp.SendText);
}
}
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
if (serailPort.IsOpen)
{
receiveText.InnerText = receiveStr;
UpdatePanel1.Update();
}
}
}
}
这里还有个坑,你把类静态全局变量receiveStr去掉static修饰符就不能刷新显示了。就是下面我要说的问题。
因为我也是新手,我在后台类里面定义了一个非静态全局变量receiveStr(现在上传的代码中是静态的),我在串口接收方法中去修改变量值,定时器里面去定时显示变量receiveStr的值,问题来了,定时器中获取到receiveStr的值始终是初始的默认值,可是串口有数据来的时候的确修改了此值,我怀疑是不是因为这个Timer是在Updatepanel中定义的有关,于是我把该变量修改成静态的就可以获取到最新的值了,不知道为什么,希望有知道的网友帮忙解惑。