買了一個優利德UT61-E系列的數顯萬用表想進行二次開發,用串口助手可以收到萬用表發送過來的資料,自己寫的串口助手收不到! 求大神幫助
uj5u.com熱心網友回復:
//資料接收函式void serialPort1_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
if (closing) return;//如果正在關閉,忽略操作,直接回傳,盡快的完成串口監聽執行緒的一次回圈
try
{
listening = true;//設定標記,說明我已經開始處理資料,一會兒要使用系統UI的。
int n = serialPort1.BytesToRead;//先記錄下來,避免某種原因,人為的原因,操作幾次之間時間長,快取不一致
byte[] buf = new byte[n];//宣告一個臨時陣列存盤當前來的串口資料
receiveCount += n;//增加接收計數
serialPort1.Read(buf, 0, n);//讀取緩沖資料
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//<協議決議>
bool data_1_catched = false;//快取記錄資料是否捕獲到
//1.快取資料
buffer.AddRange(buf);
//2.完整性判斷
while (buffer.Count >= 4)//至少要包含頭(2位元組)+長度(1位元組)+校驗(1位元組)
{
//請不要擔心使用>=,因為>=已經和>,<,=一樣,是獨立運算子,并不是決議成>和=2個符號
//2.1 查找資料頭
if (buffer[0] == 0xAA && buffer[1] == 0x44)
{
//2.2 探測快取資料是否有一條資料的位元組,如果不夠,就不用費勁的做其他驗證了
//前面已經限定了剩余長度>=4,那我們這里一定能訪問到buffer[2]這個長度
int len = buffer[2];//資料長度
//資料完整判斷第一步,長度是否足夠 . //len是資料段長度,4個位元組是while行注釋的3部分長度
if (buffer.Count < len + 4) break;//資料不夠的時候什么都不做
//這里確保資料長度足夠,資料頭標志找到,我們開始計算校驗
//2.3 校驗資料,確認資料正確
//異或校驗,逐個位元組異或得到校驗碼
byte checksum = 0;
for (int i = 0; i < len + 3; i++)//len+3表示校驗之前的位置
{
checksum ^= buffer[i];
}
if (checksum != buffer[len + 3]) //如果資料校驗失敗,丟棄這一包資料
{
buffer.RemoveRange(0, len + 4);//從快取中洗掉錯誤資料
continue;//繼續下一次回圈
}
//至此,已經被找到了一條完整資料。我們將資料直接分析,或是快取起來一起分析
//我們這里采用的辦法是快取一次,好處就是如果你某種原因,資料堆積在快取buffer中
//已經很多了,那你需要回圈的找到最后一組,只分析最新資料,過往資料你已經處理不及時
//了,就不要浪費更多時間了,這也是考慮到系統負載能夠降低。
buffer.CopyTo(0, binary_data_1, 0, len + 4);//復制一條完整資料到具體的資料快取
data_1_catched = true;
buffer.RemoveRange(0, len + 4);//正確分析一條資料,從快取中移除資料。
}
else
{
//這里是很重要的,如果資料開始不是頭,則洗掉資料
buffer.RemoveAt(0);
}
}
//分析資料
if (data_1_catched)
{
//我們的資料都是定好格式的,所以當我們找到分析出的資料1,就知道固定位置一定是這些資料,我們只要顯示就可以了
string data = binary_data_1[3].ToString("X2") + " " + binary_data_1[4].ToString("X2") + " " +
binary_data_1[5].ToString("X2") + " " + binary_data_1[6].ToString("X2") + " " +
binary_data_1[7].ToString("X2");
//更新界面
this.Invoke((EventHandler)(delegate { txtReceive.Text = data; }));
}
//如果需要別的協議,只要擴展這個data_n_catched就可以了。往往我們協議多的情況下,還會包含資料編號,給來的資料進行
//編號,協議優化后就是: 頭+編號+長度+資料+校驗
//</協議決議>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
builder.Clear();//清除字串構造器的內容
//因為要訪問ui資源,所以需要使用invoke方式同步ui。
this.Invoke((EventHandler)(delegate
{
//判斷是否是顯示為16禁止
if (chbHEXPlay.Checked)
{
//依次的拼接出16進制字串
foreach (byte b in buf)
{
builder.Append(b.ToString("X2") + " ");
}
}
else
{
//直接按ASCII規則轉換成字串
builder.Append(Encoding.ASCII.GetString(buf));
}
//追加的形式添加到文本框末端,并滾動到最后。
this.txtReceive.AppendText(builder.ToString());
//修改接收計數
lblReceiveCount.Text = "Get:" + receiveCount.ToString();
}));
}
finally
{
listening = false;//我用完了,ui可以關閉串口了。
}
}
uj5u.com熱心網友回復:
跪求大神幫忙啊!感激不盡。。。。uj5u.com熱心網友回復:
串口接收跟波特率資料校驗位等配置也都有關的,看你的完整配置uj5u.com熱心網友回復:
把協議資料簡單的放在text里面,直接發送看看,一般協議都是有校驗的,串口設定要和儀表一樣。uj5u.com熱心網友回復:
你要給4口供電,5接地uj5u.com熱心網友回復:
用device-monitoring-studio.7.25這個串口軟體監控看一下,串口的打開,關閉,發送接收資料都能看得到的。很有用
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/138676.html
標籤:C#
上一篇:整型資料轉到陣列中
下一篇:各位大佬,這個題應該選A還是B啊
