フリーシリアルポートプロトコル(アクティブ)は、最後の“パッシブ”の進歩です。HMIは、デバイスからアクティブに送信されたデータを受信するだけでなく、クエリフレーム、読み取り応答をデバイスにアクティブに送信HMIはバスの運転手です。コアAPIはuart_recvであり、コルーチン+メタテーブルと非ブロッキングCommunicationフレームワークを備え、XGUSプライベートプロトコルに接続する。HMI MシリーズDxシリーズ対応。
1.新しいAPI(相対パッシブモード)
| 関数の機能 | パラメータ | 説明書は |
|---|---|---|
uart_rxsize(ch) | シリアル番号、通常は0 | クエリ受信バッファの読取り待ちバイト数。NはNバイト、0は新しいデータなしを意味します。 |
uart_recv(ch, size) | size読み取りバイト数は1以上でなければなりません。 | 受信バッファから指定したバイト数をアクティブに読み込みます。{0xAA 0x55,0x01,0x02}のように、1からの添字を持つバイトテーブルを返します。 |
uart_rxclear(ch) | chシリアル番号 | 受信バッファを空にする。通信初期化/エラー復旧/プロトコル同期時の残存 |
calc_crc16(data) | dataバイトテーブル、添字は1から | Modbus CRC-16検証計算は0~ 655 3 5を返します。前の低文字(Modbusリトルエンディアン準拠) |
さらにuart_send ch packetはパッシブモードと同じです。指定されたシリアルチャネルにバイト配列を送信し、packetの添字は1から始まり、要素あたり0~255です。ch=0メインシリアルポート、1/2セカンダリシリアルポート(ハードウェアモデルによる)。チャネルはフリープロトコルモードでなければならない(Modbus/XGUSなどのシステムプロトコルによって占有されていない)。
2.前の記事:受信を無効にする️
アクティブなシリアル読み取りは、まずエンジニアリングプロパティで行う必要があります。シリアルポート設定→受信コールバック→無効(新しいソフトウェアにはこのオプションがあります。この場合、uart_recvとon_uart_recvコールバックはデータを奪い、フレームが乱れます。

3.ケース:XGUSプロトコルをシステムレジスタにマッピング
目標:XGUSプロトコル内のアドレス≥ 0 x 1000の読み書きをHMIシステムレジスタLW1000~LWFFFFにマッピングする。外部デバイスはXGUSフレームを使用してHMI 内部変数を読み書きし、HMIはデバイスに読み書き要求を送信します。
3.1 XGUSフレーム形式
| フィールドフィールド | 長さは | 説明書は |
|---|---|---|
| フレームヘッド | 2バイト。 | 0x5AA5 |
| 長さは | 1バイト目 | Command+データ+検証されたバイト数 |
| Commandは | 1バイト目 | 0 x 82書き込み/0 x 83読み取り(0 x 80/0 x 81も使用) |
| データは | 最大249バイト | アドレス(2バイト)+データ内容(nバイト)、長さ= n+2 |
| CRC | 2バイト(オプション) | CRC-16 (x16+x15+x2+1) |
例:変数アドレス0 x 1000に値2を書き込む(CRCを有効にしない):5A A5 05 82 10 00 00 02※ 05は长さ(Command1+アドレス2+データ2)で、ワードごとに书き込まれる。
3.2初期化XGUS.luaのロード
公式にはコルーチン+メタテーブルに基づいたXGUS.luaフレームワークが提供されている。main.luaでインスタンスを作成する:
function on_init dofile "X.l" xgus = XGUS new 0 0x55AA true true --パラメータ:シリアルポート番号、フレームヘッダ、オープンCRC、オープン書き込み応答 End of Endシングル --on_runでコルーチンを実行、ノンブロッキングポーリング _EN_SET_DATA_ = false function on_run screen _EN_SET_DATA_ = true xgus run _EN_SET_DATA_ = false End of Endシングル
XGUS runはコルーチンで実装されています。シリアルデータのチェック→“フレームヘッダ+Command+長さ+アドレス”6バイトを満たす→ Parse →長さで残りのデータを集める→ CRCチェック→処理。コルーチンは、on_runメインループをブロックせずにタスクを中断/再開でき、時間のかかるプロセスに適しています。
3.3命令解決:アドレスの分割
function XGUS processMsg
ローカルfunc = self.func
if func == XGUSFunction.write then
- 命令書を書く。
もしself.addr = 0 x 1000 then
ユーザレジスタ領域:LWへのデータ書き込みをParseする
ローカルデータ= {}
for i = 1_count do
datas[i] = self.req[5+i*2] 8 self.head 0xFF 0x03 0x82 0x4F 0x4B}
End of Endシングル
elseif c == XGUSFunction.read then
- 指示を読む。
もしself.addr = 0 x 1000 then
グループ応答フレーム:LW値を読み取ります。
local datas = {self.head 8 self.head 0xFF 4+self.req[8]*2
0x83 self.addr 8 self.addr 0xFF self.req[7]*2 0xFF}
for i = 1 self.req[7] do
local num = get_uint16 VT_LW self.addr+ i-1
datas[6+i*2] = 8 0xFF
datas[7+i*2] = num 0 xFF
End of Endシングル
self sendg datas
elseさん
on__resp_xgus self. self.req[8] c {}
End of Endシングル
End of Endシングル
End of Endシングル
システムレジスタ領域の読み書きコールバック(main.luaで定義)
function on__resp_xgus count wr data
WR === 0 x 82の場合
print ""... count
elseif wr === 0 x 83 then
print "read addr num".. count
End of Endシングル
End of Endシングル3.4アクティブ送信XGUS dataSend addr data
デバイスにアクティブに書き込み、データは数値またはテーブルです。
個々の値を書く。
xgus data0x1000 1234
--値のセットを書くtable
xgus dataSend 0x2000 {0x12 0x34 0x56}
--内部 send:CRCをオンにすると、uart_sendを自動的に補正する
function Xsend resp
if self.crc ==真ならば
resp[3] = resp[3] 2 長さとCRC 2バイト
local crc_buff = {}
for i = 4 #resp do crc_buff [i-3] = resp[i] end
local crc_check = calc_crc16 crc_buff
resp[#resp+1] = crc_check 0 0xFF
resp[#resp+1] = crc_check8 0xFF
End of Endシングル
uart_send self.port resp
End of Endシングル広州大彩科技Visual HMI開発ドキュメント(hmi-doc.gz-dc.com)から整理されたLUAチュートリアル“Free Serial Protocol(Active)”、著作権は大彩科技に帰属します。
Leave a Reply