{
public SerialPort comport = new SerialPort();
public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };
#region 定义公共变量
public int o = -1, c = -1, cp = -1, sp = -1, rp = -1, m = 1;
string rStr = "";
string sendCmd = "";
int length = 15;
//密码键盘
bool f = false;
int op = 0;
bool fprint = false;
#endregion
public demoControl()
{
InitializeComponent();
comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}
private void demoControl_Load(object sender, EventArgs e)
{
printDXHM.PrintController = new System.Drawing.Printing.StandardPrintController();
printJJFK.PrintController = new System.Drawing.Printing.StandardPrintController();
}
public void GetInterfacceSafyOptions(Int32 riid, out Int32 pdwSupportedOptions, out Int32 pdwEnabledOptions)
{
// TODO: 添加 demoControl.GetInterfacceSafyOptions 实现
pdwSupportedOptions = 1;
pdwEnabledOptions = 2;
}
public void SetInterfaceSafetyOptions(Int32 riid, Int32 dwOptionsSetMask, Int32 dwEnabledOptions)
{
// TODO: 添加 demoControl.SetInterfaceSafetyOptions 实现
}
//-----------------------------------------------------------------向密码键盘对应的COM2串口发送接收数据--开始--↓↓↓↓↓---------------------------------
#region 向--密码键盘--对应的COM2串口---发送数据
/// <summary>
/// 向--密码键盘--对应的COM2串口发送数据
/// </summary>
/// <param name="sendstr"></param>
/// <returns></returns>
public int SendDateToCom2(string sendstr)
{
int i;
try
{
byte[] data = HexStringToByteArray(sendstr);
comport.DiscardInBuffer();
comport.Write(data, 0, data.Length);
i = 0;//成功
}
catch
{
i = 1;//失败
}
return i;
}
#endregion
#region 向--密码键盘--对应的COM2串口---接收数据
/// <summary>
/// 向--密码键盘--对应的COM2串口接收数据
/// </summary>
/// <param name="sendstr"></param>
/// <returns></returns>
public string ReadDateToCom2()
{
string readStr = "";
if (sendCmd == "1B 47 0D 0A")//在取密码问题上 害我一天加一夜
{
Thread.Sleep(25);
}
int bytes = comport.BytesToRead;
byte[] buffer = new byte[bytes];
comport.Read(buffer, 0, bytes);
readStr = ByteArrayToHexString(buffer);
return readStr;
}
#endregion
#region 读取密码:1B 47 0D 0A
/// <summary>
/// 读取密码:1B 47 0D 0A
/// </summary>
public string ReadKeyPwd()
{
string pwd = "";
try
{
if (sp == 0)
{
string str = "1B 47 0D 0A";
sendCmd = "1B 47 0D 0A";
int sendrts = SendDateToCom2(str);
if (sendrts == 0)
{
//Thread.Sleep(100);//害我一天加一夜
Thread.Sleep(300);
pwd = rStr.Trim();
rp = 0;
}
}
}
catch (Exception ex)
{
pwd = "";
}
return pwd;
}
#endregion
#region 缓冲区存储的数据
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string str = "";
rStr = ReadDateToCom2();
rStr = rStr.Replace(" ", "");
if (m == 0)
{
if (rStr == "02024F4B")
{
str = "";
}
else if (rStr == "2A")
{
str = rStr.Replace("2A", "*");
}
else if (rStr == "0D")
{
str = "";
op = 1;
f = true;
}
else if (rStr == "1B" || rStr == "80")
{
str = "";
op = 2;
f = true;
}
else if (rStr == "08")
{
str = "";
op = 3;
f = true;
}
}
else
{
str = HexToTenString(rStr);
}
Log(LogMsgType.Incoming, str);
}
#endregion
#region 数据显示区
private void Log(LogMsgType msgtype, string msg)
{
textBox1.Invoke(new EventHandler(delegate
{
if (textBox1.Text.Length < length)
{
textBox1.AppendText(msg);
if (m == 0)
{
if (textBox1.Text.Length == 6)
{
op = 1;
f = true;
}
}
}
}));
下面是要问题的问题:
在这个程序中 读取密码时 我一直用Thread.Sleep(300);时间去等 要不返回来的值不对, 但是这样子做是很不科学的,有些速度快有些慢 所以导致最后返回的数据不一致~~~ 我想用委托的方法来实现 希望有会的朋友帮帮我,给我贴出实现的代码,谢谢~~~
3 个解决方案
#1
异步串口是好的,提高效率有用。你用得着么?会不会吧问题复杂化?
#2
串口通讯使用一般有两种模式:
1 问答,就是你提到的定时读取.比如200豪秒返回不是我指定字节长度就当出错处理.开始下次通讯.
否则就接收读取回来解析数据
2 触发接收,缓冲区有数据就触发datarecive事件,你要不断接收处理,比较被动.
你所提到的委托也可以,其实比较方便可以直接开启一个后台BackgroundWorker线程来完成通讯,只要将数据共享就可以了,不影响界面线程
1 问答,就是你提到的定时读取.比如200豪秒返回不是我指定字节长度就当出错处理.开始下次通讯.
否则就接收读取回来解析数据
2 触发接收,缓冲区有数据就触发datarecive事件,你要不断接收处理,比较被动.
你所提到的委托也可以,其实比较方便可以直接开启一个后台BackgroundWorker线程来完成通讯,只要将数据共享就可以了,不影响界面线程
#3
rStr = ReadDateToCom2();
问题出在这句上面,rStr 是全局变量,你应该将每次收到的字符串雷加到rStr,而不是重新赋值。这样rStr里面只是大约在300ms内收到的内容,所以可能要好久;
你改为rStr+= ReadDateToCom2();就可以了
也不需要调用 Thread.Sleep(300);
问题出在这句上面,rStr 是全局变量,你应该将每次收到的字符串雷加到rStr,而不是重新赋值。这样rStr里面只是大约在300ms内收到的内容,所以可能要好久;
你改为rStr+= ReadDateToCom2();就可以了
也不需要调用 Thread.Sleep(300);
#1
异步串口是好的,提高效率有用。你用得着么?会不会吧问题复杂化?
#2
串口通讯使用一般有两种模式:
1 问答,就是你提到的定时读取.比如200豪秒返回不是我指定字节长度就当出错处理.开始下次通讯.
否则就接收读取回来解析数据
2 触发接收,缓冲区有数据就触发datarecive事件,你要不断接收处理,比较被动.
你所提到的委托也可以,其实比较方便可以直接开启一个后台BackgroundWorker线程来完成通讯,只要将数据共享就可以了,不影响界面线程
1 问答,就是你提到的定时读取.比如200豪秒返回不是我指定字节长度就当出错处理.开始下次通讯.
否则就接收读取回来解析数据
2 触发接收,缓冲区有数据就触发datarecive事件,你要不断接收处理,比较被动.
你所提到的委托也可以,其实比较方便可以直接开启一个后台BackgroundWorker线程来完成通讯,只要将数据共享就可以了,不影响界面线程
#3
rStr = ReadDateToCom2();
问题出在这句上面,rStr 是全局变量,你应该将每次收到的字符串雷加到rStr,而不是重新赋值。这样rStr里面只是大约在300ms内收到的内容,所以可能要好久;
你改为rStr+= ReadDateToCom2();就可以了
也不需要调用 Thread.Sleep(300);
问题出在这句上面,rStr 是全局变量,你应该将每次收到的字符串雷加到rStr,而不是重新赋值。这样rStr里面只是大约在300ms内收到的内容,所以可能要好久;
你改为rStr+= ReadDateToCom2();就可以了
也不需要调用 Thread.Sleep(300);