田舎の組み込みプログラマーがわざわざ趣味でも色々開発してみようとあがく様を綴るブログです。
DMM.makeのクリエイターズマーケットに出品しています。
投げ技炸裂 ― 2018年05月07日
昨日の状態遷移図とソースコードには、よく見るとものすごい無駄があります。
それは、遷移先が違うだけで全く同じタイマー処理を3カ所でやっていることです。
そこで、今回はタイマー処理を一つにまとめてみます。
サブルーチン呼び出しなんかを使うとこれまでの苦労が台無しですので、オブジェクト指向風にいきます。
と言うわけで
まずは状態遷移図です。
外部からの指令はまず LED_CONTROL で受けますので、ここに _TIMER の処理を書いておけばアクティブなステートに関わりなくタイマー処理を行えます。
そして、タイムアップしたらおもむろに _TIMER を投げます。
で、アクティブなステートが受け取り可能なら受け取ってくれますし、そうでなければスルーされます。
最後にアクティブなコンディションに向かうわけですが、そこでも受け取ってもらえなければ投げっぱなしになってしまうわけですね。
今回の状態遷移図では _TIMER を受け取ることができるステートが3つあり、それ以外のステートとコンディションではスルーされます。
それではコーディングいきます
今回はパート処理の部分だけ掲載します。
;==========================================================
PART$ LED_CONTROL
;----------------------------------------------------------
blink_timer: .blkw 1
blink_limit: .blkw 1
;==========================================================
; コンディション定義
CONDITION$_DEFINE C_LED_OFF ;[消灯中]
CONDITION$_DEFINE C_LED_ON ;[点灯中]
CONDITION$_DEFINE C_LED_BLINK ;[点滅中]
; ステータス定義
STATE$_DEFINE LED_STATIC_OFF ; 消灯<[消灯中]
STATE$_DEFINE LED_OFF_DELAY ; 消灯遅延<[消灯中]
STATE$_DEFINE LED_STATIC_ON ; 点灯<[点灯中]
STATE$_DEFINE LED_BLINK_OFF ; 点滅(OFF)<[点滅中]
STATE$_DEFINE LED_BLINK_ON ; 点滅(ON)<[点滅中]
;=======================================
;[消灯中]
;=======================================
CONDITION$ C_LED_OFF
_ON
TRANS LED_STATIC_ON ; → 点灯<[点灯中]
_UNIQUE
TRANS LED_BLINK_ON ; → 点滅(ON)<[点滅中]
_END
;-----------------------------------
; 消灯<[消灯中]
;-----------------------------------
STATE$ LED_STATIC_OFF, C_LED_OFF
[ LED_PORT_BIT ] = OFF
_END
;-----------------------------------
; 消灯遅延<[消灯中]
;-----------------------------------
STATE$ LED_OFF_DELAY, C_LED_OFF
_TIMER
TRANS LED_STATIC_OFF ; → 消灯<[消灯中]
_END
;=======================================
;[点灯中]
;=======================================
CONDITION$ C_LED_ON
_OFF
TRANS LED_STATIC_OFF ; → 消灯<[消灯中]
_UNIQUE
TRANS LED_BLINK_OFF ; → 点滅(OFF)<[点滅中]
_END
;-----------------------------------
; 点灯<[点灯中]
;-----------------------------------
STATE$ LED_STATIC_ON, C_LED_ON
[ LED_PORT_BIT ] = ON
_END
;=======================================
;[点滅中]
;=======================================
CONDITION$ C_LED_BLINK
_OFF
NOP
TRANS LED_OFF_DELAY ; → 消灯遅延<[消灯中]
_ON
TRANS LED_STATIC_ON ; → 点灯<[点灯中]
_END
;-----------------------------------
; 点滅(OFF)<[点滅中]
;-----------------------------------
STATE$ LED_BLINK_OFF, C_LED_BLINK
[ LED_PORT_BIT ] = OFF
[ blink_timer ].w = [ blink_limit ].w
_TIMER
TRANS LED_BLINK_ON ; → 点滅(ON)<[点滅中]
_END
;-----------------------------------
; 点滅(ON)<[点滅中]
;-----------------------------------
STATE$ LED_BLINK_ON, C_LED_BLINK
[ LED_PORT_BIT ] = ON
[ blink_timer ].w = [ blink_limit ].w
_TIMER
TRANS LED_BLINK_OFF ; → 点滅(OFF)<[点滅中]
_END
;==========================================================
_TIMER
if [ blink_timer ].w > [ PARAMETER ].w
[ blink_timer ].w = [ blink_timer ].w - [ PARAMETER ].w
else ; タイムアップ
[ blink_timer ].w = 0 ; blink_limit が割り切れないときの保険
THROW ; おもむろに _TIMER を投げる
endif
_INIT
[ blink_limit ].w = 1000
_SET
[ blink_limit ].w = [ PARAMETER ].w
;----------------------------------------------------------
_END
;==========================================================
そう、投げるコマンドは "THROW" です。
このおかげでタイマー更新処理をまとめることができ、コードがスッキリします。
ただ、哀しいことにここまでやってもコードサイズはほとんど変わらなかったりします。
アセンブラなので元々効率がいいんですよね。
そんなこんなで
ようやくミドルウェア部分が出来上がってきましたが、まだ一つ重要な仕組みができていないのと、マイコン周辺機能処理の見直し、LCDなどの周辺機器ドライバやシリアル通信機能などなど、やることが山積みで、またしばらく更新が滞ってしまうかもしれません。
では、今回はこの辺で。
コメント
トラックバック
このエントリのトラックバックURL: http://trident.asablo.jp/blog/2018/05/07/8846537/tb
コメントをどうぞ
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。
※投稿には管理者が設定した質問に答える必要があります。