目次

Solid State Relay 処理

 ワンチップマイコンのPIC12F1501を利用した
 Solid State Relayで家電品の電源を入切する
 装置を作成したことがあります。



 スイッチを使って、次のように状態遷移します。



 使うSolid State Relayは、以下。



 ワンチップマイコンの元祖である、8048を使い
 同じことができると考えて、ファームウエアを
 作成しました。

 8048には、入力専用ピンにT0、T1があるので
 スイッチを接続して、入切の指定を確認して
 みればよいでしょう。

 仕様を満足するために、シーケンスを考えます。
  1. T0の状態値入力
  2. 状態値が'1'ならば4に遷移
  3. T0に対する状態値を反転
  4. T1の状態値入力
  5. 状態値が'1'ならば7に遷移
  6. T1に対する状態値を反転
  7. 状態値をポート1に出力
  8. 時間待ち
  9. 1に戻る
 シーケンスをコードにすると、以下。 MAIN: ; get T0 state jt0 MAIN1 ; update right state xch a,r0 xrl a,#1 xch a,r0 MAIN1: ; get T1 state jt1 MAIN2 ; update left state xch a,r0 xrl a,#2 xch a,r0 MAIN2: ; impress call SND_P1 ; delay call DELAY MAINX: ; jmp MAIN  シーケンスを実現するのに、必要となるソフトウエア  の部品をリスト。  これら2つの部品をサブルーチンで用意します。  論理値出力   レジスタr0に2ビットの論理値が含まれていると   すれば、次のようにコード化すればよいはず。 SND_P1: ; get code mov a,r0 ; impress outl P1,a ; ret  無駄時間生成   内蔵のタイマーカウンタの値を利用すればよいでしょう。   6MHzでシステムクロックを利用しているときは   T0に与えられるクロックは、12.5kHzになります。   カウンタで250分周としておけば、タイマーカウンタで   生成する周波数は50Hz。   タイマー割込みが50Hzで発生するたびに、別途用意した   カウンタで50カウントし、50になったなら終了すれば   1秒生成ができます。   50をカウントするレジスタをr5としておき、タイマー割込みで   インクリメントして対応。 DELAY: ; set value mov r1,#0 ; loop DELAYL: mov a,#50 xrl a,r1 jz DELAYX jmp DELAYL ; DELAYX: ret   タイマーの初期化は、以下。 TZERO equ 6 INIT_TIM: ; stop counter stop tcnt ; initialize mov a,#TZERO mov t,a ; start timer strt t ; ret   タイマー割込みが発生したときは、内蔵カウンタの   初期化と、レジスタr1のインクリメントで対応。 E_TIMX: ; push mov r2,a ; stop counter stop tcnt ; initialize mov a,#TZERO mov t,a ; increment inc r1 ; pop mov a,r2 ; retr  まとめます。 ; SSR ; INCLUDE 8048.LIB ;******************* ; value and address ;******************* TZERO equ 6 TFLAG equ 20h ;**************** ; define symbols ;**************** ENTRY equ 0h E_INT equ 3h E_TIM equ 7h ;******************* ; interrupt vectors ;******************* org ENTRY jmp START ; external interrupt org E_INT retr ; timer interrupt org E_TIM jmp E_TIMX org 10h ;************** ; sub routines ;************** E_TIMX: ; push mov r2,a ; stop counter stop tcnt ; initialize mov a,#TZERO mov t,a ; increment inc r1 ; pop mov a,r2 ; retr INIT: ; disable external interrupt dis i ; disable timer interrupt dis tcnti ; initialize I/O clr a outl p1,a outl p2,a ; enable timer start t ; clear clr a ; copy mov r0,a mov r1,a mov r2,a mov r3,a mov r4,a mov r5,a mov r6,a mov r7,a ; ret INIT_TIM: ; stop counter stop tcnt ; initialize mov a,#TZERO mov t,a ; start timer strt t ; ret DELAY: ; set value mov r1,#0 ; loop DELAYL: mov a,#50 xrl a,r1 jz DELAYX jmp DELAYL ; DELAYX: ret INIT_P1: ; zero clear clr a ; impress outl P1,a ; ret SND_P1: ; get code mov a,r0 ; impress outl P1,a ; ret ;************** ; main routine ;************** org 100h START: call INIT call INIT_TIM call INIT_P1 ; enable en TCNTI MAIN: ; get T0 state jt0 MAIN1 ; update right state xch a,r0 xrl a,#1 xch a,r0 MAIN1: ; get T1 state jt1 MAIN2 ; update left state xch a,r0 xrl a,#2 xch a,r0 MAIN2: ; impress call SND_P1 ; delay call DELAY MAINX: ; jmp MAIN end  リストにすると、次のようになります。 0000 ; SSR 0000 ; 0000 INCLUDE 8048.LIB 0000 list 0000 0000 ;******************* 0000 ; value and address 0000 ;******************* 0006 TZERO equ 6 0020 TFLAG equ 20h 0000 0000 ;**************** 0000 ; define symbols 0000 ;**************** 0000 ENTRY equ 0h 0003 E_INT equ 3h 0007 E_TIM equ 7h 0000 0000 ;******************* 0000 ; interrupt vectors 0000 ;******************* 0000 org ENTRY 0000 2400 + jmp START 0002 0002 ; external interrupt 0002 org E_INT 0003 93 + retr 0004 0004 ; timer interrupt 0004 org E_TIM 0007 0410 + jmp E_TIMX 0009 0009 org 10h 0010 ;************** 0010 ; sub routines 0010 ;************** 0010 E_TIMX: 0010 ; push 0010 AA + mov r2,a 0011 ; stop counter 0011 65 + stop tcnt 0012 ; initialize 0012 2306 + mov a,#TZERO 0014 62 + mov t,a 0015 ; increment 0015 19 + inc r1 0016 ; pop 0016 FA + mov a,r2 0017 ; 0017 93 + retr 0018 0018 INIT: 0018 ; disable external interrupt 0018 15 + dis i 0019 ; disable timer interrupt 0019 35 + dis tcnti 001A ; initialize I/O 001A 27 + clr a 001B 39 + outl p1,a 001C 3A + outl p2,a 001D ; enable timer 001D 55 + start t 001E ; clear 001E 27 + clr a 001F ; copy 001F A8 + mov r0,a 0020 A9 + mov r1,a 0021 AA + mov r2,a 0022 AB + mov r3,a 0023 AC + mov r4,a 0024 AD + mov r5,a 0025 AE + mov r6,a 0026 AF + mov r7,a 0027 ; 0027 83 + ret 0028 0028 INIT_TIM: 0028 ; stop counter 0028 65 + stop tcnt 0029 ; initialize 0029 2306 + mov a,#TZERO 002B 62 + mov t,a 002C ; start timer 002C 55 + strt t 002D ; 002D 83 + ret 002E 002E DELAY: 002E ; set value 002E B900 + mov r1,#0 0030 ; loop 0030 DELAYL: 0030 2332 + mov a,#50 0032 D9 + xrl a,r1 0033 C637 + jz DELAYX 0035 0430 + jmp DELAYL 0037 ; 0037 DELAYX: 0037 83 + ret 0038 0038 INIT_P1: 0038 ; zero clear 0038 27 + clr a 0039 ; impress 0039 39 + outl P1,a 003A ; 003A 83 + ret 003B 003B SND_P1: 003B ; get code 003B F8 + mov a,r0 003C ; impress 003C 39 + outl P1,a 003D ; 003D 83 + ret 003E 003E ;************** 003E ; main routine 003E ;************** 003E org 100h 0100 START: 0100 1418 + call INIT 0102 1428 + call INIT_TIM 0104 1438 + call INIT_P1 0106 ; enable 0106 25 + en TCNTI 0107 MAIN: 0107 ; get T0 state 0107 360D + jt0 MAIN1 0109 ; update right state 0109 28 + xch a,r0 010A D301 + xrl a,#1 010C 28 + xch a,r0 010D 010D MAIN1: 010D ; get T1 state 010D 5613 + jt1 MAIN2 010F ; update left state 010F 28 + xch a,r0 0110 D302 + xrl a,#2 0112 28 + xch a,r0 0113 0113 MAIN2: 0113 ; impress 0113 143B + call SND_P1 0115 ; delay 0115 142E + call DELAY 0117 0117 MAINX: 0117 ; 0117 2407 + jmp MAIN 0119 0119 end

目次

inserted by FC2 system