请教一个串口的问题:我现在读串口的函数是这样的:
/// <summary>
/// 接收地址数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void DataReceivedAddress(object sender, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[_com.BytesToRead];
_com.Read(data, 0, data.Length);
if (data.Length != 0)
{ DisposeRecvDataAddress(data); }
}
处理接收地址数据:
/// </summary>
/// <param name="strReceive"></param>
public void DisposeRecvDataAddress(byte[] data)
{
string strReceive = "";
for (int i = 0; i < data.Length; i++)
{
strReceive += TenToHex(data[i].ToString());
}
Receive_Data += strReceive;
if (Receive_Data.Length >= 48)
{
nFlag1 = Receive_Data.IndexOf("68");
strZC = Receive_Data.Substring(nFlag1 + 16, 2);
}
}
我现在想通过strZC这个来判断,如果等于9C,此时就向串口中写数据,向串口中写数据的函数是这样的:
void write ()
{
if (strZC == "9C")
{
if (hh == number - 1)
{
hh = 0;
}
else
{
hh++;
}
_strStationAdd = strStationNew[hh];
string[] SendData = new string[12];
SendData[0] = "68";
SendData[1] = _strStationAdd.Substring(0, 2);
SendData[2] = _strStationAdd.Substring(2, 2);
SendData[3] = _strStationAdd.Substring(4, 2);
SendData[4] = _strStationAdd.Substring(6, 2);
SendData[5] = _strStationAdd.Substring(8, 2);
SendData[6] = _strStationAdd.Substring(10, 2);
SendData[7] = "68";
SendData[8] = "1C";
SendData[9] = "00";
SendData[10] = MeGetCrc(SendData, 10);//计算校验码CRC
SendData[11] = "16";
byte[] send = new byte[12];
send[0] = Convert.ToByte(SendData[0], 16);
send[1] = Convert.ToByte(SendData[1], 16);
send[2] = Convert.ToByte(SendData[2], 16);
send[3] = Convert.ToByte(SendData[3], 16);
send[4] = Convert.ToByte(SendData[4], 16);
send[5] = Convert.ToByte(SendData[5], 16);
send[6] = Convert.ToByte(SendData[6], 16);
send[7] = Convert.ToByte(SendData[7], 16);
send[8] = Convert.ToByte(SendData[8], 16);
send[9] = Convert.ToByte(SendData[9], 16);
send[10] = Convert.ToByte(SendData[10], 16);
send[11] = Convert.ToByte(SendData[11], 16);
_com.Write(send, 0, 12);
}
}
如果我把这个write函数直接加在
strZC = Receive_Data.Substring(nFlag1 + 16, 2);这个语句后面串口就读不到数据了,请高人指点下,看这是为什么?以及如何解决?
/// <summary>
/// 接收地址数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void DataReceivedAddress(object sender, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[_com.BytesToRead];
_com.Read(data, 0, data.Length);
if (data.Length != 0)
{ DisposeRecvDataAddress(data); }
}
处理接收地址数据:
/// </summary>
/// <param name="strReceive"></param>
public void DisposeRecvDataAddress(byte[] data)
{
string strReceive = "";
for (int i = 0; i < data.Length; i++)
{
strReceive += TenToHex(data[i].ToString());
}
Receive_Data += strReceive;
if (Receive_Data.Length >= 48)
{
nFlag1 = Receive_Data.IndexOf("68");
strZC = Receive_Data.Substring(nFlag1 + 16, 2);
}
}
我现在想通过strZC这个来判断,如果等于9C,此时就向串口中写数据,向串口中写数据的函数是这样的:
void write ()
{
if (strZC == "9C")
{
if (hh == number - 1)
{
hh = 0;
}
else
{
hh++;
}
_strStationAdd = strStationNew[hh];
string[] SendData = new string[12];
SendData[0] = "68";
SendData[1] = _strStationAdd.Substring(0, 2);
SendData[2] = _strStationAdd.Substring(2, 2);
SendData[3] = _strStationAdd.Substring(4, 2);
SendData[4] = _strStationAdd.Substring(6, 2);
SendData[5] = _strStationAdd.Substring(8, 2);
SendData[6] = _strStationAdd.Substring(10, 2);
SendData[7] = "68";
SendData[8] = "1C";
SendData[9] = "00";
SendData[10] = MeGetCrc(SendData, 10);//计算校验码CRC
SendData[11] = "16";
byte[] send = new byte[12];
send[0] = Convert.ToByte(SendData[0], 16);
send[1] = Convert.ToByte(SendData[1], 16);
send[2] = Convert.ToByte(SendData[2], 16);
send[3] = Convert.ToByte(SendData[3], 16);
send[4] = Convert.ToByte(SendData[4], 16);
send[5] = Convert.ToByte(SendData[5], 16);
send[6] = Convert.ToByte(SendData[6], 16);
send[7] = Convert.ToByte(SendData[7], 16);
send[8] = Convert.ToByte(SendData[8], 16);
send[9] = Convert.ToByte(SendData[9], 16);
send[10] = Convert.ToByte(SendData[10], 16);
send[11] = Convert.ToByte(SendData[11], 16);
_com.Write(send, 0, 12);
}
}
如果我把这个write函数直接加在
strZC = Receive_Data.Substring(nFlag1 + 16, 2);这个语句后面串口就读不到数据了,请高人指点下,看这是为什么?以及如何解决?
_com.Read(data, 0, data.Length);
这样是不保证完全读取你的数据帧的内容,不信你自己可以测试,在上面代码后面添加
int number=1;System.Dialognose.Debug.WriteLine(++number,data.Length);然后你发一帧,只发一帧数据,看看到底是分几次才接收完成的。这个也是调试过程中发现的问题 :)
Console.WriteLine(strZC); 看是否存在 9C , 如果不存在,那说
明你根本就没有捕获到相应的数据。
2. 你的串口通讯协议是怎样的? 一般情况下接收之间有一个应答机制,
也就是说设备发送数据出来会有一个超时时间,在指定的超时时间内你
若没有发送数据到设备,那么设备就不再等待接收数据,而是继续发
送数据。这样你就永远发送不了数据到设备。
建议看一下串口协议中超时时间的设置,也很有可能是由这里引起的。
private void btnBegin_Click(object sender, EventArgs e)
{
switch (((Button)sender).Text)
{
case "开 始":
mycom1.PortNum = this.cbCom.SelectedIndex + 1; //串口号
if (!OpenCom())
{
return;
}
((Button)sender).Text = "结 束";
this.thGetCard = new Thread(SendData);
this.thGetCard.Start();
break;
case "结 束":
if (mycom1.Opened)
{
mycom1.Close(); //关闭串口
}
if (this.thGetCard.IsAlive)
this.thGetCard.Abort();
((Button)sender).Text = "开 始";
break;
}
} private void SendData() //发送数据
{
bool bSign;
int sendnumb;
while (true)
{
bSign = false;
sendnumb = 0;
try
{
sendnumb = mycom1.Write(G_SendHead); // 发送读数据指令
for (int i = 0; i < 3; i++)
{
G_RecvData = mycom1.Read(1); // 取数据
if (G_RecvData[0].ToString("X2").Equals("CF"))
{ //如果取得想要的数据,则继续,否则循环发送读数据指令
bSign = true;
break;
}
} if (!bSign) continue; DateTime dt = DateTime.Now;
while (true)
{
TimeSpan tSpan = DateTime.Now - dt;
if (2000 < tSpan.Ticks) break; //超时 sendnumb = mycom1.Write(G_GetCard); //继续发送读数据指令
G_RecvData = mycom1.Read(7); //继续取数据 //this.BeginInvoke(this.showResult, new object[] { this.txtMsg,
// "\r\n接收到数据包:" + dis_package(G_RecvData) }); if (GetCard(G_RecvData, ref CardNo))
{
this.BeginInvoke(this.showResult, new object[] { this.txtMsg,
CardNo.ToString()+"\r\n" });
}
} }
catch //(Exception ex)
{
//this.BeginInvoke(this.showResult, new object[] { this.txtMsg,
// "\r\n捕获导常:" + ex.Message });
}
}
}