關(guān)于PID閉環(huán)控制中上位機(jī)與下位機(jī)通訊代碼的解析分享(一)


下位機(jī)接收數(shù)據(jù)代碼(以STM32單片機(jī)為例)與上位機(jī)發(fā)送數(shù)據(jù)C#代碼分享
1、下位機(jī)代碼:
這段代碼是一個(gè)接收數(shù)據(jù)并進(jìn)行處理的函數(shù)。函數(shù)名為receiving_process,返回類型為int8_t,參數(shù)為空。函數(shù)的作用是接收數(shù)據(jù)并根據(jù)接收到的命令類型進(jìn)行相應(yīng)的處理。如果沒有找到正確的命令,函數(shù)返回-1。
在函數(shù)內(nèi)部,定義了一些變量用于存儲(chǔ)接收到的數(shù)據(jù)和命令類型。frame_data是一個(gè)長度為128的uint8_t數(shù)組,用于存儲(chǔ)接收到的數(shù)據(jù)幀。frame_len是一個(gè)uint16_t類型的變量,用于記錄數(shù)據(jù)幀的長度。cmd_type是一個(gè)uint8_t類型的變量,用于存儲(chǔ)命令類型。
接下來是一個(gè)無限循環(huán),用于不斷接收并處理數(shù)據(jù)。
循環(huán)內(nèi)部首先調(diào)用了一個(gè)名為protocol_frame_parse的函數(shù),該函數(shù)用于解析數(shù)據(jù)幀并返回命令類型。解析過程將接收到的數(shù)據(jù)幀存儲(chǔ)在frame_data中,并將數(shù)據(jù)幀的長度保存在frame_len中。解析結(jié)果保存在cmd_type中。
接下來通過switch語句對cmd_type進(jìn)行判斷,根據(jù)不同的命令類型進(jìn)行相應(yīng)的處理。
如果命令類型為CMD_NONE,表示沒有找到正確的命令,返回-1。
如果命令類型為SET_P_I_D_CMD,表示接收到了設(shè)置PID參數(shù)的命令。接下來通過COMPOUND_32BIT宏將frame_data中的字節(jié)轉(zhuǎn)換為32位整數(shù),然后再通過強(qiáng)制類型轉(zhuǎn)換將32位整數(shù)轉(zhuǎn)換為float類型。將轉(zhuǎn)換后的參數(shù)傳遞給set_p_i_d函數(shù),用于設(shè)置PID參數(shù)。
如果命令類型為SET_TARGET_CMD,表示接收到了設(shè)置目標(biāo)值的命令。通過COMPOUND_32BIT宏將frame_data中的字節(jié)轉(zhuǎn)換為32位整數(shù),然后將轉(zhuǎn)換后的參數(shù)傳遞給set_pid_target函數(shù),用于設(shè)置目標(biāo)值。
如果命令類型為START_CMD,表示接收到了啟動(dòng)電機(jī)的命令。調(diào)用set_motor_enable函數(shù),用于啟動(dòng)電機(jī)。
如果命令類型為STOP_CMD,表示接收到了停止電機(jī)的命令。調(diào)用set_motor_disable函數(shù),用于停止電機(jī)。
如果命令類型為RESET_CMD,表示接收到了復(fù)位系統(tǒng)的命令。調(diào)用HAL_NVIC_SystemReset函數(shù),用于復(fù)位系統(tǒng)。
如果命令類型為SET_PERIOD_CMD,表示接收到了設(shè)置定時(shí)器周期的命令。通過COMPOUND_32BIT宏將frame_data中的字節(jié)轉(zhuǎn)換為32位整數(shù),然后將轉(zhuǎn)換后的參數(shù)傳遞給SET_BASIC_TIM_PERIOD函數(shù),用于設(shè)置定時(shí)器周期。
最后,如果命令類型不在上述情況中,默認(rèn)返回-1。
總結(jié)起來,這段代碼是一個(gè)接收數(shù)據(jù)并進(jìn)行處理的函數(shù)。函數(shù)通過解析數(shù)據(jù)幀獲取命令類型,并根據(jù)命令類型進(jìn)行相應(yīng)的處理操作。
2、上位機(jī)代碼:
導(dǎo)入命名空間:
using System;:引入System命名空間,包含了一些常用的系統(tǒng)類型和功能。
using System.IO.Ports;:引入System.IO.Ports命名空間,提供了與串口通信相關(guān)的類和方法。
using System.Threading;:引入System.Threading命名空間,提供了多線程編程相關(guān)的類和方法。
定義UpperComputer類:
private SerialPort serialPort;:定義一個(gè)私有變量serialPort,用于串口通信。
public UpperComputer():構(gòu)造方法,用于初始化串口。
Connect()方法:
serialPort.Open();:打開串口連接。
Console.WriteLine("成功連接下位機(jī)。");:在控制臺(tái)輸出連接成功的提示信息。
Disconnect()方法:
serialPort.Close();:關(guān)閉串口連接。
Console.WriteLine("已斷開下位機(jī)連接。");:在控制臺(tái)輸出斷開連接的提示信息。
SendCommand()方法:
serialPort.Write(command, 0, command.Length);:發(fā)送命令給下位機(jī)。
Console.WriteLine("發(fā)送命令成功。");:在控制臺(tái)輸出發(fā)送命令成功的提示信息。
Main()方法:
UpperComputer upperComputer = new UpperComputer();:創(chuàng)建一個(gè)UpperComputer對象。
upperComputer.Connect();:調(diào)用Connect()方法連接下位機(jī)。
示例代碼:
發(fā)送設(shè)置PID參數(shù)的命令:
byte[] setPIDCommand = new byte[25];:定義一個(gè)長度為25的byte數(shù)組,用于存儲(chǔ)設(shè)置PID參數(shù)的命令。
setPIDCommand[0] = 1;:設(shè)置命令類型為設(shè)置PID參數(shù)。
Buffer.BlockCopy(BitConverter.GetBytes(1.23f), 0, setPIDCommand, 1, 4);:將浮點(diǎn)數(shù)1.23轉(zhuǎn)換為字節(jié)數(shù)組,并復(fù)制到setPIDCommand數(shù)組的指定位置,用于設(shè)置P參數(shù)。
Buffer.BlockCopy(BitConverter.GetBytes(4.56f), 0, setPIDCommand, 5, 4);:將浮點(diǎn)數(shù)4.56轉(zhuǎn)換為字節(jié)數(shù)組,并復(fù)制到setPIDCommand數(shù)組的指定位置,用于設(shè)置I參數(shù)。
Buffer.BlockCopy(BitConverter.GetBytes(7.89f), 0, setPIDCommand, 9, 4);:將浮點(diǎn)數(shù)7.89轉(zhuǎn)換為字節(jié)數(shù)組,并復(fù)制到setPIDCommand數(shù)組的指定位置,用于設(shè)置D參數(shù)。
upperComputer.SendCommand(setPIDCommand);:調(diào)用SendCommand()方法發(fā)送設(shè)置PID參數(shù)的命令。
發(fā)送設(shè)置目標(biāo)值的命令:
byte[] setTargetCommand = new byte[9];:定義一個(gè)長度為9的byte數(shù)組,用于存儲(chǔ)設(shè)置目標(biāo)值的命令。
setTargetCommand[0] = 2;:設(shè)置命令類型為設(shè)置目標(biāo)值。
Buffer.BlockCopy(BitConverter.GetBytes(100), 0, setTargetCommand, 1, 4);:將整數(shù)100轉(zhuǎn)換為字節(jié)數(shù)組,并復(fù)制到setTargetCommand數(shù)組的指定位置,用于設(shè)置目標(biāo)值。
upperComputer.SendCommand(setTargetCommand);:調(diào)用SendCommand()方法發(fā)送設(shè)置目標(biāo)值的命令。
發(fā)送啟動(dòng)電機(jī)的命令:
byte[] startCommand = new byte[1];:定義一個(gè)長度為1的byte數(shù)組,用于存儲(chǔ)啟動(dòng)電機(jī)的命令。
startCommand[0] = 3;:設(shè)置命令類型為啟動(dòng)電機(jī)。
upperComputer.SendCommand(startCommand);:調(diào)用SendCommand()方法發(fā)送啟動(dòng)電機(jī)的命令。
發(fā)送停止電機(jī)的命令:
byte[] stopCommand = new byte[1];:定義一個(gè)長度為1的byte數(shù)組,用于存儲(chǔ)停止電機(jī)的命令。
stopCommand[0] = 4;:設(shè)置命令類型為停止電機(jī)。
upperComputer.SendCommand(stopCommand);:調(diào)用SendCommand()方法發(fā)送停止電機(jī)的命令。
發(fā)送復(fù)位系統(tǒng)的命令:
byte[] resetCommand = new byte[1];:定義一個(gè)長度為1的byte數(shù)組,用于存儲(chǔ)復(fù)位系統(tǒng)的命令。
resetCommand[0] = 5;:設(shè)置命令類型為復(fù)位系統(tǒng)。
upperComputer.SendCommand(resetCommand);:調(diào)用SendCommand()方法發(fā)送復(fù)位系統(tǒng)的命令。
發(fā)送設(shè)置定時(shí)器周期的命令:
byte[] setPeriodCommand = new byte[5];:定義一個(gè)長度為5的byte數(shù)組,用于存儲(chǔ)設(shè)置定時(shí)器周期的命令。
setPeriodCommand[0] = 6;:設(shè)置命令類型為設(shè)置定時(shí)器周期。
Buffer.BlockCopy(BitConverter.GetBytes(500), 0, setPeriodCommand, 1, 4);:將整數(shù)500轉(zhuǎn)換為字節(jié)數(shù)組,并復(fù)制到setPeriodCommand數(shù)組的指定位置,用于設(shè)置周期。
upperComputer.SendCommand(setPeriodCommand);:調(diào)用SendCommand()方法發(fā)送設(shè)置定時(shí)器周期的命令。
upperComputer.Disconnect();:調(diào)用Disconnect()方法斷開下位機(jī)連接。