private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
bool Rec_Flag = true;
bool UpdateData = false;
byte[] bytestemp = new byte[4];
ushort AckResult=0;
byte[] Data = new byte[serialPort1.BytesToRead]; //定义缓冲区,因为串口接收事件触发时字节数不固定
//单设备,如果是接收的数据字节长度小于13,接收标记等于假
//帧头0+帧头1+------功能码+器件码+数据码1+数据码2+数据码3+数据码4+数据码5+数据码6+校验码CSUM+帧尾0+帧尾1。(0-12)
if (Data.Length < 13)
{
Rec_Flag = false;
}
//接收到一帧数据
if (Rec_Flag == true)
{
try
{
//将缓冲区的数据读取,放在data数组中
serialPort1.Read(Data, 0, Data.Length);
//在文本框中显示信息
textBox15.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "收 <- ");
foreach (byte Member in Data) //遍历用法
{
string str = Convert.ToString(Member, 16).ToUpper();//转换成16进制的字符
textBox15.AppendText((str.Length == 1 ? "0" + str : str) + " ");
}
textBox15.AppendText("\r\n");
}
catch { }
//数据校验
if (Data.Length == 13) //单设备模式
{
//帧头0+帧头1+------功能码+器件码+数据码1+数据码2+数据码3+数据码4+数据码5+数据码6+校验码CSUM+帧尾0+帧尾1。
//校验和
//判断帧头0和帧头1是不是相等,是的话,进行后面的处理,否则退出
if (Data[0] == Head[0])
{
if (Data[1] == Head[1])
{
int csum = CheckSumAction(Data, 13);
if (Data[10] == csum) //校验正确
{
UpdateData = true;
}
else //校验错误
{
textBox15.AppendText("\r\n和校验值错误,请检查校验算法!!\r\n");
}
}
else
return;
}
else
return;
}
else
{
textBox15.AppendText("\r\n返回的字节数不对!!\r\n");
}
数据解析,校验正确,那么显示在文本框中
if (UpdateData == true)
{
UpdateChanData(textBox1, Data, 1);
UpdateChanData(textBox2, Data, 2);
UpdateChanData(textBox3, Data, 3);
UpdateChanData(textBox4, Data, 4);
UpdateChanData(textBox5, Data, 5);
UpdateChanData(textBox6, Data, 6);
UpdateChanData(textBox7, Data, 7);
UpdateChanData(textBox8, Data, 8);
UpdateChanData(textBox9, Data, 9);
UpdateChanData(textBox10, Data, 10);
UpdateChanData(textBox11, Data, 11);
UpdateChanData(textBox12, Data, 12);
UpdateChanData(textBox13, Data, 13);
//接收的数据OK,判断是什么信息
//根据接收到的设备号进行判断,
switch (Data[2])
{
//应答信号处理,3秒内进行处理,超过3秒没有收到应答,进行应答错误提示-------------------
case 0x00://X电机
switch (Data[3])//功能码
{
//---------------------------------------------------------------------------
case 0x00://mm,浮点数
AckResult = SendAckToSerialPort(serialPort1,0x00,0xDD, 0xf0,5,200);//发送应答号码,没有超时间界定,只有连续发N次
//成功应答
//将浮点数运动位移(直线位移或者角位移)获取,赋值给下位机的Xmm
//将xmm转换成脉冲数
bytestemp[0] = Data[4];
bytestemp[1] = Data[5];
bytestemp[2] = Data[6];
bytestemp[3] = Data[7];
float fdata = BitConverter.ToSingle(bytestemp, 0);;
textBox16.Text = Convert.ToString(fdata);
textBox17.Text ="xxx";
textBox18.Text = "XMNC";
break;
//---------------------------------------------------------------------------------
case 0x01://pul,整数
AckResult = SendAckToSerialPort(serialPort1,0x00,0xDD, 0xf0,5,200);//发送应答号码
//if (AckResult == 0)//不成功应答,退出程序
//{
// return;
//}
//成功应答
//将浮点数运动位移(直线位移或者角位移)获取,赋值给下位机的Xmm
//将xmm转换成脉冲数
bytestemp[0] = Data[4];
bytestemp[1] = Data[5];
bytestemp[2] = Data[6];
bytestemp[3] = Data[7];
Int32 intdata = BitConverter.ToInt32(bytestemp,0);
textBox16.Text = "xxx";
textBox17.Text = Convert.ToString(intdata);
textBox18.Text = "XMNC";
break;
//----------------------------------------------------------------
case 0xDD://应答
Program.USART1_RecAckFlag = 1;
textBox18.Text = "XMACK";
break;
}
break;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
case 0x80://第一个IO口D2=0x80,D3=0xDD/0x00,
switch (Data[3])//功能码---IO口的话,D3=0xDD/0x00,D4=0xf0/(0x00-0x01)
{
case 0x00://IO状态
if(Data[4]==0x00)
{
button17.BackColor = Color.Red;
SendAckToSerialPort(serialPort1, 0x80, 0xDD, 0xF0,3, 1000);//发送应答号码
label27.Text = Convert.ToString( Program.USART1_RecAckFlag);
}
else if(Data[4]==0x01)
{
button17.BackColor = Color.Green;
SendAckToSerialPort(serialPort1, 0x80, 0xDD, 0xF0,3, 1000);//发送应答号码
label27.Text = Convert.ToString(Program.USART1_RecAckFlag);
}
break;
//--------------------------------
case 0xDD://收到应答信号
Program.USART1_RecAckFlag = 1;
button17.BackColor = Color.Yellow;
break;
//-------------------------------
default: break;
}
break;
default:break;
}
}
}
}
//------------------------------------------------------校验和计算
private int CheckSumAction(byte[] Data, byte DataLEN)
{
int csum = 0x0000;//UInt16
//计算帧头0,帧头1后面的数据的校验码,长度=13
//帧头0+帧头1+------功能码+器件码+数据码1+数据码2+数据码3+数据码4+数据码5+数据码6+校验码CSUM+帧尾0+帧尾1。
for (byte i = 2; i < DataLEN-3; i++)
{
csum += Data[i];
}
csum = csum % 256;
return csum;
}
//在文本框中显示接收的数据,用十六进制显示
c#chuankou232接收32或者51处理
最新推荐文章于 2023-08-23 13:49:22 发布