RSフリップフロップ回路をラダー言語とアセンブリ言語の2通りで表現する

 以下に、**RSフリップフロップ回路**をラダー言語(ラダー図)とアセンブリ言語(x86)の2通りで実装する方法を詳細に解説します。RSフリップフロップは、Set(設定)とReset(リセット)入力で状態を保持する基本メモリ回路です。


---


### 1. ラダー言語(ラダー図)での実装

#### 標準的な自己保持回路

```

|-----|-----[SET]-----( )--|

|  S  |             Q      |

|-----|-----[RST]-----( )--|

|  R  |             !Q     |

```

**真理値表**:

| S | R | Q | !Q |

|---|---|---|----|

| 1 | 0 | 1 | 0  |

| 0 | 1 | 0 | 1  |

| 0 | 0 | 保持 | 保持 |

| 1 | 1 | 禁止状態 |


#### 機種依存実装(三菱PLC例)

```

|--[SET Q]--|  (S入力)

|--[RST Q]--|  (R入力)

```


---


### 2. x86アセンブリ言語での実装

#### メモリマップドI/O版

```assembly

section .data

    S    db 0       ; Set入力

    R    db 0       ; Reset入力

    Q    db 0       ; 出力Q

    notQ db 1       ; 反転出力!Q


section .text

    global _start


_start:

    ; Set入力チェック

    cmp  byte [S], 1

    jne  check_reset

    mov  byte [Q], 1     ; Q=1

    mov  byte [notQ], 0  ; !Q=0

    jmp  io_update


check_reset:

    ; Reset入力チェック

    cmp  byte [R], 1

    jne  io_update

    mov  byte [Q], 0     ; Q=0

    mov  byte [notQ], 1  ; !Q=1


io_update:

    ; 出力ポートへの反映

    mov  al, [Q]

    out  0x20, al        ; Qをポート0x20へ

    mov  al, [notQ]

    out  0x21, al        ; !Qをポート0x21へ


    ; 入力リセット(ラッチ動作の場合不要)

    mov  byte [S], 0

    mov  byte [R], 0


    jmp  _start          ; 無限ループ

```


#### 最適化版(ビット操作)

```assembly

_start:

    ; 入力状態をALに統合

    in   al, 0x30       ; ポート0x30から入力(S=bit0, R=bit1)

    and  al, 0x03       ; 下位2ビットのみ取得


    ; 状態更新

    cmp  al, 0b01       ; S=1, R=0

    je   set_q

    cmp  al, 0b10       ; S=0, R=1

    je   reset_q

    jmp  io_update      ; それ以外は保持


set_q:

    or   byte [Q], 0b00000001  ; Q=1

    and  byte [Q], 0b11111110  ; !Q=0

    jmp  io_update


reset_q:

    and  byte [Q], 0b11111110  ; Q=0

    or   byte [Q], 0b00000010  ; !Q=1


io_update:

    mov  al, [Q]

    out  0x20, al        ; Q出力

    shr  al, 1

    out  0x21, al        ; !Q出力

    jmp  _start

```


---


### 3. 動作比較表

| 特性               | ラダー言語                     | アセンブリ言語                   |

|--------------------|-------------------------------|---------------------------------|

| **状態保持**       | 内部リレー自動保持            | メモリ変数で明示的保持          |

| **禁止状態処理**   | 機種依存(通常は無視)        | 分岐処理でエラー検出可能        |

| **リアルタイム性** | スキャンサイクルに依存        | 割り込み処理と組み合わせ可能    |

| **リソース使用**   | 内部リレー2点                 | メモリ変数2-4バイト             |


---


### 4. 重要な注意点

1. **PLCのスキャン順序**:  

   ラダー図では「上→下、左→右」の評価順のため、`SET`と`RST`が同じスキャンでONの場合、後方の命令が優先されます。


2. **アセンブリの原子性**:  

   マルチスレッド環境では状態更新に`LOCK`プレフィックスが必要:

   ```assembly

   lock or byte [Q], 0b01  ; アトミック操作

   ```


3. **ハードウェア構成**:  

   実際のハードウェアRS-FF(例:74HC279)とソフトウェア実装の違い:

   - ハードウェア: ゲート遅延ナノ秒級

   - ソフトウェア: マイクロ秒~ミリ秒級


---


### 5. 応用パターン

#### ラダー言語での優先権付きRS-FF(Reset優先)

```

|-----|-----( )-----[RST Q]--|

|  R  |                     |

|-----|-----[SET Q]----------|

|  S  |                     |

```


#### アセンブリでの割り込み駆動版

```assembly

isr_s_button:

    mov  byte [Q], 1     ; 割り込みで強制SET

    iret


isr_r_button:

    mov  byte [Q], 0     ; 割り込みで強制RESET

    iret

```


---


### 6. エラー処理の実装

#### 禁止状態(S=R=1)検出

```assembly

    cmp  al, 0b11       ; S=1かつR=1

    jne  normal_op

    mov  byte [Error], 1 ; エラーフラグ設定

    jmp  error_handler

normal_op:

    ; 通常処理

```


このように、RSフリップフロップは「状態記憶」の基本要素として、PLCではリレーシーケンスの基盤に、アセンブリでは低レベル制御の状態管理に活用されます。実際の実装では、用途に応じて優先権やエラー処理を追加することが重要です。

コメント

このブログの人気の投稿

Pydroid用ピアノアプリ+ラフマニノフピアノ協奏曲第2番1楽章デモ音源付き

最高裁での上告理由書受理・却下の判断基準について

訴えの変更(追加的変更)申立