源码:
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
SerialPort sp = new SerialPort(this.txtPort.Text, 9600, Parity.None, 8, StopBits.One);
//SerialPort sp = new SerialPort(this.txtPort.Text);
byte[] m = new byte[13];
m[0] = 0x42;
byte[] cardnoArr = System.Text.Encoding.ASCII.GetBytes(this.txtMsg.Text);
for (int i = 1; i <= 10; i++ )
{
if (i <= cardnoArr.Length)
{
m[i] = cardnoArr[i - 1];
}
else
{
m[i] = 0x20;
}
}
int v = 0;
for (int i = 0; i < 11; i++ )
{
v += m[i];
}
m[12] = (byte)(v);
m[11] = (byte)(v >> 8);
//打开新的串行端口连接
sp.Open();
//丢弃来自串行驱动程序的接受缓冲区的数据
sp.DiscardInBuffer();
//丢弃来自串行驱动程序的传输缓冲区的数据
sp.DiscardOutBuffer();
//使用缓冲区的数据将指定数量的字节写入串行端口
sp.Write(m, 0, m.Length);
//关闭端口连接
sp.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private string StringToHexString(string s, Encoding encode)
{
byte[] b = encode.GetBytes(s);//按照指定编码将string编程字节数组
string result = string.Empty;
for (int i = 0; i < b.Length; i++)//逐字节变为16进制字符,以%隔开
{
result += "%" + Convert.ToString(b[i], 16);
}
return result;
}
代码:
public Form1()
{
InitializeComponent();
}
private ILog logger = LogManager.GetLogger(typeof(Form1));
///
/// 接收串口数据线程
///
private Thread recMsgThread;
///
/// 解析数据处理队列
///
private WorkQueue parseDataProcQueue = new WorkQueue();
///
/// 刷卡事件处理队列
///
private WorkQueue creditCardEventProcQueue = new WorkQueue();
private SerialPort sp = null;
private bool shouldStop = false;
private void Form1_Load(object sender, EventArgs e)
{
parseDataProcQueue.WorkSequential = true;
parseDataProcQueue.UserWork += new UserWorkEventHandler(ParsedData_UserWork);
creditCardEventProcQueue.UserWork += new UserWorkEventHandler(CreditCardEvent_UserWork);
}
///
/// 接收串口数据
///
private void RecPortMsg()
{
byte[] b;
byte[] recArr;
while (!shouldStop)
{
try
{
sp = new SerialPort(txtPort.Text, 9600, Parity.None, 8, StopBits.One);
//sp = new SerialPort(txtPort.Text);
//打开新的串行端口连接
sp.Open();
logger.Info(string.Format("SerialPort open success.{0}", txtPort.Text));
//丢弃来自串行驱动程序的接受缓冲区的数据
sp.DiscardInBuffer();
//丢弃来自串行驱动程序的传输缓冲区的数据
sp.DiscardOutBuffer();
StringBuilder sb = new StringBuilder();
while (!shouldStop)
{
b = new byte[32];
//从串口输入缓冲区读取一些字节
int n = sp.Read(b, 0, b.Length);
if(n > 0)
{
recArr = new byte[n];
for (int i = 0; i < n; i++ )
{
recArr[i] = b[i];
}
//放入解析队列
parseDataProcQueue.EnqueueItem(recArr);
}
//当前线程挂起200毫秒
System.Threading.Thread.Sleep(200);
}
}
catch (Exception ex)
{
logger.Error(string.Format("RecPortMsg error.{0}", ex.Message));
}
System.Threading.Thread.Sleep(2000);
}
if (null != sp)
{
//关闭端口连接
sp.Close();
}
}
//10进制卡号按以下格式编码(16进制):42 xx xx xx xx xx xx 20 20 20 20 HH LL
//注:通信包定长13bytes,包头以'B'开始,16进制0x42;
//后跟10位卡号,以16进制ASCII码值发送;
//卡号不满10位时,后补0x20(空格);
//校验码计算:前11位的16进制值累加,2bytes,高位bytes+低位bytes。
//数据包
private byte[] dataPacket = new byte[13];
private int i_data = 0;
private bool hasFind = false;
///
/// 解析数据-工作处理
///
private void ParsedData_UserWork(object sender, WorkQueue.EnqueueEventArgs e)
{
byte bStart = 0x42; //通讯包头部
byte[] recArr = e.Item;
try
{
foreach (byte b in recArr)
{
if (b == bStart)
{
hasFind = true;
dataPacket = new byte[13];
i_data = 0;
}
if (hasFind)
{
if (i_data <= 12)
{
dataPacket[i_data++] = b;
if (i_data == 13) //完整包
{
//校验数据有效性
if (CheckDataValid(dataPacket))
{
//解析获取卡号
long cardno = parseCardNo(dataPacket);
logger.InfoFormat("Rec CardNo:{0}", cardno);
//回复
if (null != sp)
{
byte[] postdata = new byte[2];
//返回成功
postdata[0] = 0x44;
postdata[1] = 0x59;
sp.Write(postdata, 0, postdata.Length);
}
//放入刷卡事件处理队列
creditCardEventProcQueue.EnqueueItem(cardno);
}
hasFind = false;
}
}
}
}
}
catch (Exception ex1)
{
logger.Error(string.Format("Parse data error.{0}", ex1.Message));
}
}
///
/// 校验数据包是否是有效的
/// 校验码计算:前11位的16进制值累加,2bytes,高位bytes+低位bytes。
///
///
///
private bool CheckDataValid(byte[] dataPacket)
{
bool valid = false;
int v = 0;
for (int i = 0; i < 11; i++)
{
v += dataPacket[i];
}
byte LL = (byte)(v);
byte HH = (byte)(v >> 8);
if (dataPacket[11] == HH && dataPacket[12] == LL)
{
valid = true;
}
return valid;
}
//解析获取卡号
private long parseCardNo(byte[] dataPacket)
{
byte bSpace = 0x20; //空格
//获取卡号
string s_cardno = "";
long cardno = 0;
for (int i = 1; i < 11; i++)
{
if (dataPacket[i] != bSpace)
{
s_cardno += (char)dataPacket[i];
}
}
cardno = long.Parse(s_cardno);
return cardno;
}
///
/// 刷卡事件-工作处理
///
private void CreditCardEvent_UserWork(object sender, WorkQueue.EnqueueEventArgs e)
{
long cardno = e.Item;
ShowCardNo(cardno.ToString());
}
///
/// 显示卡号
///
///
private void ShowCardNo(string msg)
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(delegate { ShowCardNo(msg); }));
return;
}
txtMsg.Text = msg;
}
private void button1_Click(object sender, EventArgs e)
{
recMsgThread = new Thread(new ThreadStart(RecPortMsg));
recMsgThread.Start();
button1.Enabled = false;
button2.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
Stop();
button2.Enabled = false;
button1.Enabled = true;
}
private void Stop()
{
this.shouldStop = true;
if (null != recMsgThread)
{
recMsgThread.Abort();
}
if (null != sp)
{
//关闭端口连接
sp.Close();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Stop();
}