我正在与DPS5020电源通信以获取电压和电流。 SMPS数据输出在数据包的末尾不包含任何定界符,因此我认为这引起了问题。当我使用串行终端程序查询SMPS时,每次都会得到正确的数据包,但是当我使用c#程序查询时,大约70%的时间没有数据。输入数据包的大小为9个字节长。我使用了serial_port.Read(buffer,0,9),但是即使那样,还是有错误。有人可以帮我吗?我的代码在下面。
主要功能
private void ovcRead_Click(object sender, EventArgs e)
{
byte[] sendbyte = power2.PowerSupply_GetOVC(); // get over current value
try
{ serial_pow2.Write(sendbyte, 0, sendbyte.Length);
SMPS2_timer.Enabled = true;
textBox2.Text = "";
}
catch
{ MessageBox.Show(serial_pow2.PortName + " port error"); }
}
private void ser_AVDD_DataRx(object sender, SerialDataReceivedEventArgs e)
{
//if (SMPS2_Tick == false)
// return;
//SMPS2_Tick = true;
byte[] readb = new byte[9];
int s = serial_pow2.Read(readb, 0, 9);
Action Receive = () =>
{
if (power2.getOutCur == true)
{
decimal volt, cur;
power2.processOCP(readb, out volt, out cur); // process over current raw data
power2.getOutCur = false;
if (volt != 99.99m && cur != 99.99m)
textBox2.Text = volt + " V, " + cur + " A." + "; " + readb[0].ToString("X2") + " " + readb[1].ToString("X2") + " " + readb[2].ToString("X2") + " " + readb[3].ToString("X2") + " " + readb[4].ToString("X2") + " " + readb[5].ToString("X2") + " " + readb[6].ToString("X2") + " " + readb[7].ToString("X2") + " " + readb[8].ToString("X2");
}
};
this.Invoke(new Action(Receive));
serial_pow2.DiscardInBuffer();
}
private void SMPS2_timer_Tick(object sender, EventArgs e)
{
SMPS2_timer.Enabled = false;
SMPS2_Tick = true;
}
Power2类功能。
public byte[] PowerSupply_GetOVC()
{
UInt16 CRC_high = 0;
UInt16 CRC_low = 0;
int i = 0;
getOutCur = true;
int[] supplySet = { 0x01, 0x03, 0x00, 0x02, 0x00, 0x02 }; // get output volt, current
byte[] sendbyte = new byte[supplySet.Length + 2];
Modbus_CRC_Check(supplySet, out CRC_high, out CRC_low);
for (i = 0; i < supplySet.Length; i++)
sendbyte[i] = Convert.ToByte(supplySet[i]);
sendbyte[i++] = Convert.ToByte(CRC_low);
sendbyte[i++] = Convert.ToByte(CRC_high);
return sendbyte;
}
public void processOCP(byte[] readb, out decimal volt, out decimal cur)
{
try
{
int t = readb[3];
t <<= 8;
int y = readb[4];
int vol = (t + y);
volt = (decimal)vol / 100;
t = readb[5];
t <<= 8;
y = readb[6];
int curr = (t + y);
cur = (decimal)curr / 100;
}
catch
{
volt = 99.99m;
cur = 99.99m;
}
}
void Modbus_CRC_Check(int[] data_array, out UInt16 CRC_high, out UInt16 CRC_low)
{
UInt16 crc = 65535;
for (int i = 0; i < data_array.Length; i++)
{
crc ^= (ushort)data_array[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 1) != 0)
{
crc >>= 1;
crc ^= 0xA001;
}
else
{
crc >>= 1;
}
}
}
CRC_low = (ushort)(crc & 0x00FF);
CRC_high = (ushort)(crc >> 8);
}
使用端子时,输入和输出数据是:
输入命令:01 03 00 02 00 02 65 CB
输出数据:01 03 04 00 62 00 00 5B ED
当值不正确时使用c#:
输入命令:01 03 00 02 00 02 65 CB
输出数据1:01 03 04 00 62 00 00 5B ED
输出数据2:01 03 04 00 00 00 00 00 00
输出数据3:01 00 00 00 00 00 00 00 00] >>
我尝试设置ReadTimeout值并在开始时对串行接收事件使用计时器检查,但结果相同。
我正在与DPS5020电源通信以获取电压和电流。 SMPS数据输出在数据包的末尾不包含任何定界符,因此我认为这引起了问题。当我查询...
该问题可能是由serial_pow2.DiscardInBuffer()
引起的。
我想我解决了。我一直怀疑程序正在接收片段数据。如果数据长度不为9,我将数据存储在临时缓冲区中。在下一次读取中,最新的数据在串行端口事件处理中连接到临时缓冲区。现在我得到正确的数据。