新的更新:我们只是对外部框进行了一些调整以允许他接收,但不发送。当外部盒子静音,并且所讨论的串行端口没有接收数据时,此处描述的问题就消失了;也就是说,只要我们没有收到,我们就可以发送。那么,,这是我应该处理的错误或特征还是“已知问题”?
就此事项(非常)欢迎提供建议和指导。我在三个句子中的问题是......
我可以从串口发送一组字节。
串口开始接收,并继续接收。
我无法发送另一组字节。
我得到的系统似乎没有响应。我告诉Visual Studio 2010打破所有。我的代码总是在一条线上点着一个弯曲的绿色箭头指向它。我将鼠标悬停在它上面,我看到的东西就是这样......
无法计算表达式,因为当前线程处于休眠,等待或加入
如果有任何专家阅读能够将这种复杂性扩散到更简单的英语解释中,那么这些人将长期成为我的朋友。
这是停滞不前的方法......
public static void Tell_Box_To_Stop_Sending()
{
int Length;
int StartingPosition;
byte[] TheBytesToSend;
Length = TheseBytesAreThe.Command_06_Stop_Data_Flood.Length;
StartingPosition = 0;
TheBytesToSend = TheseBytesAreThe.Command_06_Stop_Data_Flood;
OurSpecificPorts.TheActivePortWeAreUsing.Write(TheBytesToSend, StartingPosition, Length); ////// The green arrow is on this line
}
这是用于打开端口的类。我应该把这个开放的端口带出这个类吗?
/**********************************************************************************
* Class Name: UART
*
* Constructor: Takes the string name, stores it, and does nothing else
*
* Methods: -- Open_TheActivePortWeWillUse --
*
**************************************************************************************/
class UART
{
public SerialPort OurMainActiveSerialPort;
public byte[] The_Immediate_Rx_Buffer;
String The_Name_Of_The_Serial_Port;
public UART(String ThePortNameTheCallerGaveUs)
{
The_Name_Of_The_Serial_Port = ThePortNameTheCallerGaveUs;
}
public static void send_command(byte[] The_Byte_Array, int Starting_Place, int Length)
{
///OurMainActiveSerialPort.Write(The_Byte_Array, Starting_Place, Length);
OurSpecificPorts.TheActivePortWeAreUsing.Write(The_Byte_Array, Starting_Place, Length);
}
/*****************************************************************
* Method: Open_TheActivePortWeWillUse
*
* On Entry: Caller gives us a name, in a string. C# and
* Windows almost probably always use a format
* like "COM1" or "COM37" or some such scheme.
*
* Class: OurSpecificPorts
* Item: .TheActivePortWeAreUsing
* Has been defined as a serial port in the RegularVariables.cs file
*
*
* Actions: That serial port will be opened
*
*
* On Exit: The port will be connected, doing 8-N-1.
*
*
* We will store the port in a variable that's
* widely available to just about everybody.
*
* It will be in the class: OurSpecificPorts
*
* Its name will be: TheActivePortWeAreUsing
*
* Another method, in this class, will take on
* the Event Handler which will respond to new
* bytes in the buffer. (Don't be misled, this
* is not the UART FIFO buffer that you may be
* thinking; but a buffer that Windows and C#
* arrange for us.)
*
* The name of that method will be...
*
* OurBackGroundSerialPortReceiver
*
*
* Be Aware: If this is a bluetooth connection, we get
* 921600 bps irrespective of what we
* say we want for speed.
*
*
*****************************************************************/
public static void Open_TheActivePortWeWillUse(String Drone_StringNameFromUser)
// First, open the port
SerialPort TempSerialPort = new SerialPort (Drone_StringNameFromUser, int) SerialPortParameter.TheSerialPortSpeed);
OurSpecificPorts.TheActivePortWeAreUsing = TempSerialPort; // Now we have a name that anybody can see and use
OurSpecificPorts.TheActivePortWeAreUsing.DataBits = 8;
OurSpecificPorts.TheActivePortWeAreUsing.Parity = Parity.None;
OurSpecificPorts.TheActivePortWeAreUsing.StopBits = StopBits.One;
OurSpecificPorts.TheActivePortWeAreUsing.DataReceived += new SerialDataReceivedEventHandler(OurBackGroundSerialPortReceiver);
OurSpecificPorts.TheActivePortWeAreUsing.Open();
}
/*************************************************************************************************
* Method Name: OurBackGroundSerialPortReceiver
*
* Called By: Windows internal things
*
* Root Cause: The UART generates an event
*
* On Entry: There is hopefully some data in the Uart's buffer
*
* Windows and C# will set up two calling arguments
* -- object sender
* -- SerialDataReceivedEventArgs e
*
* Actions: This method sets flags and semaphores to alert other parts of our code
* of what we are doing, then it moves data out of the latest buffer that
* the serial port provides, into another buffer. We'll use a trailer and
* header scheme, much like our own box uses its interrupt handler with a
* background/foreground scheme.
*
* On Exit: Whatever was in the buffer is moved to the trailer/leader buffer which
* other parts of the code will take and use
*
* Other References: http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived
*
* http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx
*
* http://msdn.microsoft.com/en-us/library/ms143549.aspx
*
* Microsoft actually has example code there which makes sense.
*
*
* ***********************************************************************************************/
public static void OurBackGroundSerialPortReceiver(object sender, SerialDataReceivedEventArgs e )
{
SerialPort CurrentPort = (SerialPort)sender; // Int routine gave is this in the arguments
int LastByteInUartBuffer = CurrentPort.ReadBufferSize;
int TheNumberOfBytes = CurrentPort.BytesToRead;
byte[] inputData = new byte[TheNumberOfBytes];
int WeGotThisMany = CurrentPort.Read(inputData, 0, TheNumberOfBytes);
int Dest;
Dest = UartPlaceHolders.RxBufferLeader; // Will index into buffer for Chief dispatch
int Source; // Will index into Uart buffer to fish it out
Source = 0; // therefore, we start at zero
int TopEdge; // We'll calculate this here once instead of in the loops below
TopEdge = (int)TheSizeOf.OneSecondsWorthOfData; // This will tell us when to wrap around
if (Dest < UartPlaceHolders.RxBufferTrailer) // Half the time we'll have wrap-around
{ // If that's the case, then the trailer > the leader
while (
(Dest < UartPlaceHolders.RxBufferTrailer) // If we are wrapped, make sure we don't
&& // overtake either the trailer or
(Dest < TopEdge) // go over the top edge
&& // At the same time, make sure that
(Source <= LastByteInUartBuffer) // we don't fish out more than is there
)
{ // Move bytes into buff for chief
UartData.TheImmediateSecondOfData[Dest] = inputData[Source];
Dest = Dest + 1;
Source = Source + 1;
}
if (Source >= LastByteInUartBuffer) // Have we done all the bytes for this event ?
{ // Yes, therefore we will update the leader
UartPlaceHolders.RxBufferLeader = Dest; // This tells us where to start next time
aUartSemaphoreThatTells.WhatTheUartBackgroundRxIsDoing = (int)aValueWhichIndicatesThat.WeHaveReceivedSomeData;
return; // and we are done
}
// // Else no, more bytes so...
else if (Dest >= TopEdge) // Did we wrap around ?
{ // Yes, so
Dest = 0; // wrap around to the start
while ( // Now we do the same thing again
Dest < UartPlaceHolders.RxBufferTrailer // C# and windows keep buffers at 4K max,
&& // so we will wrap only once
Source < LastByteInUartBuffer // May not even need that other test
) // This will finish the rest of the bytes
{
UartData.TheImmediateSecondOfData[Dest] = inputData[Source]; // There they go
Dest = Dest + 1;
Source = Source + 1;
}
UartPlaceHolders.RxBufferLeader = Dest; // This tells us where to start next time
return;
}
else // Dest is neither <, >, nor =, we have logic error
{
ErrorFlags.SerialPortErrorDescription = (int)AnError.ExistsInTheSerialPortBufferPointers;
return;
}
}
// We now take this case when the leader is up
// ahead of, or equal to, the trailer. In that
// case, we change the while loop to check for
// the leader overtaking the top edge, but not
// the trailer. Since the buffer will be about
// 4x the size of what we get from the Uart it
// is approximately guaranteed not to overtake
// the trailer; do the arithmetic and you will
// probably agree.
// I am purposely using to large, similar, but
// not completely identical schemes instead of
// another "else" appended to the previous bag
// of code. This will greatly improve debug.
if (Dest >= UartPlaceHolders.RxBufferTrailer) // Now, if the Trailer is ahead of the leader, here we go
{
while (
(Dest < TopEdge) // We still want to stop before we hit the top edge
&& // At the same time, make sure that we don't go past...
(Source < LastByteInUartBuffer) // ... the end of the Uart buffer
&& // Nor do we want to go past...
(Source < TheNumberOfBytes) // ...the last byte the Uart gave us
)
{
UartData.TheImmediateSecondOfData[Dest] = inputData[Source]; // Move bytes into buff for chief
Dest = Dest + 1;
Source = Source + 1;
}
if (Source >= LastByteInUartBuffer) // Have we done all the bytes for this event ?
{ // Yes, therefore we will update the leader
UartPlaceHolders.RxBufferLeader = Dest; // This tells us where to start next time
aUartSemaphoreThatTells.WhatTheUartBackgroundRxIsDoing = (int)aValueWhichIndicatesThat.WeHaveReceivedSomeData;
return; // and we are done
} // // Else no, we have more bytes to move, so...
else if (Dest >= TopEdge) // Did we wrap around ?
{ // Yes, so...
Dest = 0; // wrap around to the start
while ( // Now we do the same thing again
Dest < UartPlaceHolders.RxBufferTrailer // C# and windows keep buffers at 4K max,
&& // so we will wrap only once
Source < LastByteInUartBuffer
)
{
UartData.TheImmediateSecondOfData[Dest] = inputData[Source];
Dest = Dest + 1;
Source = Source + 1;
}
UartPlaceHolders.RxBufferLeader = Dest; // This tells us where to start next time
aUartSemaphoreThatTells.WhatTheUartBackgroundRxIsDoing = (int)aValueWhichIndicatesThat.WeHaveReceivedSomeData;
return;
}
else // Dest is neither <, >, nor =, we have logic error, so debug this
{
ErrorFlags.SerialPortErrorDescription = (int)AnError.ExistsInTheSerialPortBufferPointers;
return;
}
}
}
}
我希望我没有包含太多代码。我在这里的前几个问题似乎总是导致人们要求查看更多代码。我想我已经在这里待了2周了,所以,感谢理解我糟糕的协议。