【GX Works3】DMOV命令の使い方|32ビットデータ転送とワード構造

概要

「位置決めユニットへ送る目標パルス数」「生産数の積算カウンタ」——現場でMOVを使い続けていると、ある日「範囲を超えています」というエラーに突き当たります。MOVが扱えるのは-32768〜32767のBIN16ビットまでで、位置決めのパルス数や大きな積算値はこの範囲をあっさり超えてしまうためです。そこで使うのがDMOV(DMOVP)です。DMOVはBIN32ビットデータを1命令で転送できるため、±32767を超える大きな数値を扱うときはMOVではなくDMOVを使う、これが基本の切り分けです。

MOVの動作イメージがつかめている人なら、DMOVは「同じ転送を32ビット幅でやるだけ」と考えて問題ありません。ただし32ビット幅を実現するために内部でワードデバイスを2つ使う構造になっているため、そこだけは意識して使う必要があります。

書式

出典: MELSEC iQ-R プログラミングマニュアル(CPUユニット用命令/汎用FUN/汎用FB編)SH-081226 / ops/refs/instructions/08_data-transfer.md より転記。

命令記号実行条件主なオペランド/データ型動作
DMOV / DMOVP常時実行/立上り(s) 転送元 / (d) 転送先(符号付きBIN32/ANY32)BIN32ビットデータを転送(デバイス2点使用)

範囲 -2147483648〜2147483647。D0指定でD0(下位16bit)+D1(上位16bit)を使用。奇数番号始まりは避ける。

動作

X0 → DMOVP K100000 D0 のラダー図(32bit定数をD0,D1へ転送)
図1:X0がONした瞬間だけDMOVPが実行され、32ビット定数100000がD0・D1の2ワードへ一括転送されます。
D0(下位16bit) + D1(上位16bit) で32bitを構成する図。デバイスモニタ画面キャプチャでも可
図2:D0を32bit転送の先頭に指定すると、下位16ビットはD0、上位16ビットはD1に格納され、2つのワードで1つの32bit値を構成します。

DMOVは「(s)で指定されたBIN32ビットデータを、(d)で指定されたデバイスへ転送する」命令です。ここで現場が必ず押さえておきたいのが、(d)にD0を指定した場合の実際の消費デバイス数です。書式のオペランド欄では(d)は1つのデバイスとして書かれていますが、32ビットデータを格納するには16ビットのワードデバイス2つ分の領域が必要になるため、D0を指定すると実際にはD0(下位16ビット)とD1(上位16ビット)の2ワードが使われます。デバイス一覧やコメント一覧でD0だけを見て「1ワードしか使っていない」と判断すると、隣のD1が別の用途で使われていた場合に値が衝突する事故につながります。

また(s)にK1X0のような桁指定したビットデバイスを指定した場合、指定した桁数分のビットだけが転送対象になり、それ以外のビットは0が指定されているものとして扱われます。MOVと同じ考え方ですが、対象が32ビット分に広がるぶん、意図せず広い範囲が0クリアされるリスクも大きくなります。なお、DMOV/DMOVPともに演算エラーは発生しません。

サンプルコード

① 位置決めユニットへ目標パルス数をセットする

[X0  DMOVP  K100000  D0 ]

位置決め軸の目標位置を100000パルスにセットする例です。X0(位置決め開始条件)が立ち上がった瞬間だけD0・D1へ32ビット定数を転送します。MOVでは32767までしか扱えないため、パルス数が大きくなる位置決め用途ではDMOVが標準になります。

② 32ビット積算値を別デバイスへ退避コピーする

[X1  DMOVP  D200  D300 ]

D200・D201に格納されている32ビット積算値(生産数カウンタなど)を、X1が立ち上がった瞬間にD300・D301へコピーします。リセット前に現在値を退避しておきたい、といった場面でよく使う型です。

③ 2ワードを一括でゼロクリアする

[SM400  DMOV  K0  D100 ]

D100・D101をまとめてゼロクリアする例です。RSTやMOV K0を2回に分けて書く代わりに、DMOV K0で1命令・2ワード分を一括初期化できます。SM400(常時ON)を条件にしているので、電源投入直後の初期化処理などに組み込む形です。

よくある誤解

①「D0だけ使ってるつもり」で隣のデバイスを潰す

DMOVの(d)をD0だけの1個のデバイスとして扱ってしまうと事故ります。実際にはD0(下位16ビット)とD1(上位16ビット)の2ワードを消費するため、D1を別の用途(例えば別のタイマ設定値など)に割り付けていると、DMOVを実行した瞬間にその値が上書きされてしまいます。デバイス一覧表ではDMOVの(d)に指定したデバイスの「次の番号」まで予約済みとして扱うのが安全です。DMOV/DMOVP絡みのトラブルで最も多いのが、実はこの1点です。

②MOVで32ビット値を扱おうとして値が壊れる/逆に小さい値でもDMOVで統一する

32767を超える値をMOVで転送しようとすると正しく転送できません。逆に、値そのものは小さくてもデバイスコメントや用途上32ビットとして扱うと決めているデータ(積算値・パルス数など)は、あえて全部DMOVで統一しておくと、あとから桁数が大きくなったときに命令を書き換える手間を防げます。

③デバイス割付を1個ずつ進めて重複させてしまう

DMOVで32ビットデバイスを使うと決めたら、次のDMOVで使うデバイスはD0,D2,D4…のように2個飛ばしで割り付ける必要があります。D0,D1,D2…と1個ずつ順番に割り付けてしまうと、2本目のDMOVの下位ワードが1本目の上位ワードと重なってしまい、片方の値が壊れます。デバイス割付表を作るときは、32ビットデバイスは最初から「2個1組」で予約しておきましょう。

関連命令

関連記事