c#串口接收程序 , ReceivedBytesThreshold设为1 阮丁远20251110
说明:请自行严格验证本代码的准确性,本人不对此做任何保证和负责!!!
本代码里,ReceivedBytesThreshold设为1
串口数据处理用的线程:
System.Threading.Thread SP_DataReceived1_timeout_t1 = new System.Threading.Thread(new System.Threading.ThreadStart(SP_DataReceived1_timeout));
SP_DataReceived1_timeout_t1.Start(); :
public class OP_with_com_name
{
public int recv_ok1 = 0;
public OpenSP OP_s = new OpenSP();
//public int botelv_for_recv_delay = 0;
public string com_name1 = "";
public string cur_Cmd;
public AutoResetEvent AutoResetEvent1 = new AutoResetEvent(false);
public byte[] recv_bytes = new byte[0];
// public int is_ret_notok_once = 0;
public int recv_length_for_delay = 70;
public int is_scan_packet = 0;
public object lock_obj1 = new object();
public DateTime last_recv_time=DateTime.Now;
public List<byte> recv_bytes_for_addon=new List<byte>();
public int is_have_recv_bytes = 0;
}
public OP_with_com_name prod_comm_obj = new OP_with_com_name();
public void conn_prod_comm1() //打开串口
{
try
{
if (prod_comm_obj.OP_s.SP.IsOpen)
{
return;
}
prod_comm_obj.com_name1 = "prod_comm";
prod_comm_obj.OP_s.SP.DataReceived -= SP_DataReceived1;
//comport1.Open(int.Parse(libcls.get_ini_set("sets.ini", "com1").Trim().ToLower().Replace("com", "")), int.Parse(libcls.get_ini_set("sets.ini", "com1_botelv").Trim()));
if (prod_comm_obj.OP_s.OpenPort(G_jiaozhun_canshuo_input_t.prod_comm, G_jiaozhun_canshuo_input_t.prod_botelv, G_jiaozhun_canshuo_input_t.stopBits.ToString() , 8, G_jiaozhun_canshuo_input_t.parity.ToString()))
{
prod_comm_obj.OP_s.SP.ReadTimeout=220;
prod_comm_obj.OP_s.SP.ReceivedBytesThreshold = 1;
prod_comm_obj.OP_s.SP.DataReceived += SP_DataReceived1;
}
}
catch (Exception eee)
{
}
}
//串口数据处理用的线程:
public void SP_DataReceived1_timeout()
{
OP_with_com_name rttobj = prod_comm_obj;// get_op_obj_by_com_name(get_comname_by_index(0));
while (isrunning == 1)
{
System.Threading.Thread.Sleep(20);
try
{
if (prod_comm_obj.is_have_recv_bytes == 1)
{
//120ms没收到新数据则认为一帧结束:
if ((DateTime.Now - prod_comm_obj.last_recv_time).TotalMilliseconds >= 120)
{
prod_comm_obj.is_have_recv_bytes = 0;
try
{
int count = prod_comm_obj.recv_bytes_for_addon.Count;// rttobj.OP_s.SP.Read(recvbuf, 0, 600);
byte[] recvbuf = new byte[count];
Array.Copy(prod_comm_obj.recv_bytes_for_addon.ToArray(), 0, recvbuf, 0, count);
prod_comm_obj.recv_bytes_for_addon.Clear();
string tempStr = string.Empty;
for (int i = 0; i < count; i++)
{
tempStr += recvbuf[i].ToString("X2") + " ";
}
if (button10opencomms.Text == "关闭串口")
{
if (textBox2recv_485.Text.Length >= 1024 * 2048)
{
textBox2recv_485.Clear();
}
if (prod_comm_obj.is_scan_packet != 1)
{
textBox2recv_485.AppendText(">>" + tempStr + "\r\n");
textBox2recv_485.ScrollToCaret();
}
}
// rttobj.recv_ok1 = 1;
// libcls.MessageBoxw(tempStr);
if (count <= 3)
{
continue;
// return;
}
int crc16 = recvbuf[count - 1] * 256 + recvbuf[count - 2];
byte[] recvbuf_withnocrc = new byte[count - 2];
for (int i = 0; i < (count - 2); i++)
{
recvbuf_withnocrc[i] = recvbuf[i];
}
byte[] ssdata_Crc = CRC16Helper.CRC16_a(recvbuf_withnocrc);
int ssdata_Crcint = ssdata_Crc[1] + ssdata_Crc[0] * 256;
if (ssdata_Crcint == crc16)//rttobj.cur_Cmd == "Q" || , cur_Cmd=='Q'时表示切换相时crc有点问题
{
rttobj.recv_bytes = new byte[count - 4];
Array.Copy(recvbuf, 2, rttobj.recv_bytes, 0, count - 4);
rttobj.recv_ok1 = 1;
rttobj.AutoResetEvent1.Set();
}
else
{
//crc 16 错误不记录,只有最终重试发送且提示发送失败时的才记录:
//MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err", tempStr+ " crc16 err \r\n");
}
}
catch (Exception eee)
{
// MessageBox.Show(eee.Message);
//MuNiuMaLib.fvdou_append_error_to_log_txt(eee.Message + " in SP_DataReceived1 com1" + eee.StackTrace);
MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err", eee.Message + eee.StackTrace + "\r\n");
}
}
}
}
catch { }
}
}
//串口收到数据时的回调函数:
private void SP_DataReceived1(object sender, SerialDataReceivedEventArgs e)
{
OP_with_com_name rttobj = prod_comm_obj;// get_op_obj_by_com_name(get_comname_by_index(0));
try
{
rttobj.last_recv_time = DateTime.Now;
byte[] recvbuf = new byte[rttobj.OP_s.SP.BytesToRead];
int count = rttobj.OP_s.SP.Read(recvbuf, 0, rttobj.OP_s.SP.BytesToRead);//这个可能报错,所以加try
for (int i = 0; i < count; i++)
{
rttobj.recv_bytes_for_addon.Add(recvbuf[i]);
}
}
catch(Exception eee)
{
MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err2", eee.Message + eee.StackTrace + "\r\n");
// RestartSerialPort();
}
try
{
rttobj.is_have_recv_bytes = 1;
}
catch (Exception eee)
{
MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err2", eee.Message + eee.StackTrace + "\r\n");
}
//Sleep(70+6* prod_comm_obj.recv_length_for_delay)还是偶尔分包,改为Sleep(70+8* prod_comm_obj.recv_length_for_delay)后正常:
//System.Threading.Thread.Sleep(70+8* prod_comm_obj.recv_length_for_delay);//等待串口包收完!!!!40ms时读继电器状态有时不准?
}
public List<byte> send_data_to_prod(byte comm_dev_addr,string cmd_name,byte modbus_cmd_code, byte[] sendbuf,int is_in_auto_jiaozhuan_ing_t,int is_only_send_sendbuf_bytes,int is_scan_packet,int not_need_huifu)
{
conn_prod_comm1();
List<byte> ret_data = new List<byte>();
int is_recv_fail_count = 0;
int max_resend_1 = 5;//4 偶尔发失败,5把!
string tempStr = string.Empty;
lock (prod_comm_obj.lock_obj1)
{
int max_resend_ccc = 0;
prod_comm_obj.is_scan_packet = is_scan_packet;
while (max_resend_ccc <= max_resend_1 )
{
max_resend_ccc++;
prod_comm_obj.cur_Cmd = cmd_name;
prod_comm_obj.recv_ok1 = 0;
prod_comm_obj.AutoResetEvent1.Reset();
if (is_only_send_sendbuf_bytes == 0)
{
byte[] dataSend = new byte[2 + sendbuf.Length + 2];
dataSend[0] = comm_dev_addr;
dataSend[1] = modbus_cmd_code;
Array.Copy(sendbuf, 0, dataSend, 2, sendbuf.Length);
byte[] recvbuf_withnocrc = new byte[2 + sendbuf.Length];
for (int i = 0; i < (2 + sendbuf.Length); i++)
{
recvbuf_withnocrc[i] = dataSend[i];
}
byte[] ssdata_Crc = CRC16Helper.CRC16_a(recvbuf_withnocrc);
//int ssdata_Crcint = ssdata_Crc[0] + ssdata_Crc[1] * 256;
dataSend[2 + sendbuf.Length] = ssdata_Crc[1];
dataSend[3 + sendbuf.Length] = ssdata_Crc[0];
prod_comm_obj.OP_s.SP.Write(dataSend, 0, dataSend.Length);
tempStr = "";
for (int i = 0; i < dataSend.Length; i++)
{
tempStr += dataSend[i].ToString("X2") + " ";
}
}
if (is_only_send_sendbuf_bytes == 1)
{
byte[] dataSend = new byte[sendbuf.Length + 2];
Array.Copy(sendbuf, 0, dataSend, 0, sendbuf.Length);
byte[] ssdata_Crc = CRC16Helper.CRC16_a(sendbuf);
//int ssdata_Crcint = ssdata_Crc[0] + ssdata_Crc[1] * 256;
dataSend[0 + sendbuf.Length] = ssdata_Crc[1];
dataSend[1 + sendbuf.Length] = ssdata_Crc[0];
if (not_need_huifu == 1)
{
prod_comm_obj.OP_s.SP.Write(dataSend, 0, dataSend.Length);
Thread.Sleep(80);
prod_comm_obj.OP_s.SP.Write(dataSend, 0, dataSend.Length);
}
tempStr = "";
for (int i = 0; i < dataSend.Length; i++)
{
tempStr += dataSend[i].ToString("X2") + " ";
}
}
if (not_need_huifu == 1)
{
break;
}
if (is_in_auto_jiaozhuan_ing_t == 1 && G_is_Run1_or_Pause2_or_Stop0 == 0)
{
break;
}
if(is_scan_packet==1&& G_pasue_scan == 1)
{
break;
}
bool is_recv_oked = prod_comm_obj.AutoResetEvent1.WaitOne(500 + 8 * prod_comm_obj.recv_length_for_delay);//Sleep(70+6* prod_comm_obj.recv_length_for_delay)还是偶尔分包,改为Sleep(70+8* prod_comm_obj.recv_length_for_delay)后正常:
//MessageBox.Show(is_recv_oked.ToString());
if (is_recv_oked && prod_comm_obj.recv_ok1 == 1&& prod_comm_obj.recv_bytes.Length>0)
{
ret_data.AddRange(prod_comm_obj.recv_bytes);
break;
}
else
{
is_recv_fail_count++;
}
//只有最终重试发送且提示发送失败时的才记录,recv_ok1==0时不记录
System.Threading.Thread.Sleep(240 + 8 * prod_comm_obj.recv_length_for_delay);//Sleep(70+6* prod_comm_obj.recv_length_for_delay)还是偶尔分包,改为Sleep(70+8* prod_comm_obj.recv_length_for_delay)后正常:
}
}
if (is_recv_fail_count>=(max_resend_1-1))
{
//只有最终重试发送且提示发送失败时的才记录:
MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err", " send or recv not ok:"+ tempStr + " \r\n");
}
return ret_data;
}
public List<byte> write_prod(string cmd_name, int is_in_auto_jiaozhuan_ing_t,int modbus_reg_addr,int val)
{
prod_comm_obj.recv_length_for_delay = 1;
List<byte> ret_dat = send_data_to_prod((byte)G_jiaozhun_canshuo_input_t.prod_addr, cmd_name, 0x06, new byte[] {
(byte)((modbus_reg_addr>>8)&0xff),
(byte)((modbus_reg_addr)&0xff),
(byte)((val>>8)&0xff),
(byte)((val)&0xff)
}, is_in_auto_jiaozhuan_ing_t,0,0,0);
return ret_dat;
}
public List<byte> read_prod(string cmd_name, int is_in_auto_jiaozhuan_ing_t, int modbus_reg_addr)
{
prod_comm_obj.recv_length_for_delay = 1;
List<byte> ret_dat = send_data_to_prod((byte)G_jiaozhun_canshuo_input_t.prod_addr, cmd_name, 0x03, new byte[] {
(byte)((modbus_reg_addr>>8)&0xff),
(byte)((modbus_reg_addr)&0xff),
(byte)(0),
(byte)(1)
}, is_in_auto_jiaozhuan_ing_t,0,0, 0);
return ret_dat;
}
更多推荐



所有评论(0)