我正在尝试在Visual Studio 2010中编写一个c#程序,它通过串行连接与微控制器通信。我可以很好地读取和写入端口,我只是不确定如何让send方法等待,直到执行前收到上一个send命令的所有数据。我已经实现了数据接收事件处理程序,以便确定何时在串行端口上接收到所请求的适当数据量。我只需要知道如何让它告诉send方法端口是免费的。
我曾计划使用互斥锁,但我认为问题不在于多线程。同一个线程一个接一个地在串口发送字符串,响应第一个请求而收到的数据与第二个请求冲突。
此外,如果通信是由一个线程完成的,那么该线程会等待导致数据接收事件处理程序不执行吗?
(两种方法属于同一类)
我的发送数据方法:
//method for sending data
public void send(String s)
{
sp.Write(s + "\r");
}
我的数据收到了事件处理程序:
//data received event handler
private void dataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string tmp;
tmp = sp.ReadExisting();
//put all received data into the read buffer
readBuffer += tmp;
//add various flag checks to determine end of transmission
if (firmwareFlag)
{
if (readBuffer.EndsWith("\n"))
{
firmwareFlag = false;
//trigger event to tell object owner data is ready
dataReady(this, new CustomEventArgs(readBuffer, "firmware"));
readBuffer = "";
}
}
else if (parameterFlag)
{
if (System.Text.RegularExpressions.Regex.IsMatch(readBuffer, "K90", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
parameterFlag = false;
dataReady(this, new CustomEventArgs(readBuffer, "parameters"));
readBuffer = "";
}
}
else
{
dataReady(this, new CustomEventArgs(readBuffer, null));
readBuffer = "";
}
}
答案 0 :(得分:0)
我会在类中使用一个bool变量和一个计时器。当计时器滴答时,你检查bool并在允许的情况下发送数据。
boolean isAllowed;
DispatcherTimer tmr1;
//...etc
答案 1 :(得分:0)
我过去也有同样的问题,我这样解决了:
我添加了SendAndWaitResponse方法,该方法接收端口发送的缓冲区,响应的预期长度,以秒为单位的超时(以防万一),以及收到预期响应时的回调:
//System.IO.Ports.SerialPort port;
//port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived);
void SendAndWaitResponse(String buffer, int expectedLenght, int timeoutInSeconds, Action<String> callback)
{
TimeSpan _timeout = new TimeSpan(0, 0, 0, timeoutInSeconds);
//may not be necesary
if (!string.IsNullOrEmpty(buffer) && buffer != "" && port != null)
{
//Remove current dataReceived event handler, as we will manually manage it for now, will restore later!
this.port.DataReceived -= port_DataReceived;
if (!this.port.IsOpen) this.port.Open(); // open the port if it was closed
this.send(buffer); // send buffer, changed port.write(buffer) so it now usses your own send
DateTime startToWait = DateTime.Now; //start timeout
bool isTimeout = false;
int totalRead = 0;
String read = "";
while (!(isTimeout) && totalRead < expectedLenght)
{
do
{
if (port.BytesToRead > 0)
{
read += (char)this.port.ReadByte();
totalRead++;
//you can add a System.Threading.Thread.Sleep(int); if all bytes come in parts
}
} while (port.BytesToRead > 0);
isTimeout = (DateTime.Now.Subtract(_timeout) >= startToWait);
}
this.port.DataReceived += port_DataReceived; // restore listener
callback(read); //invoke callback!!!
}
}
答案 2 :(得分:0)
如果要检查是否有发送到设备的字节(写缓冲区中的字节),那么您可以读取BytesToWrite属性。
SerialPort.BytesToWrite Property