第12週 タイマ割り込みを使う
せっかちです、山とんぼ。トイレでションベン終わるの、待てません。いきなり水洗の栓、ひねってしまいます。でも、水洗タンクと山とんぼの膀胱と比較すると水洗タンクの方が容量少ないらしく(んな!)、こっちが気分良く出してるうちタンクは終わってしまいます。だらしないじゃないか、水洗タンク。
しかたなし、タンクがいっぱいになるまでイライラじっと待ってもう一度流すから、結局、余計時間かかってしまうことになるわけです。うちのタンク、給水の出が悪くて時間かかるんだ、これが。ええい、じれったい!
急がば回れ。んーん、こんなケースで使うことわざじゃないか。(^^;
いっそ公共のトイレみたいにタンク式でなく水道直結で時間管理する水洗トイレに変えようかとも考えています。でも、そのまえにせっかちな性格を変える方が安上がり、だよな。



 タイマ割り込みを使う

前週、割り込みをやってみましたが、このときはBR0/INTピンの外部割り込みでした。一方タイマ割り込みも手軽に使えるようにしておく必要がありそうです。今週は割り込みついでにタイマ割り込みやってみます。
出力は前週と同じ波形発生ですが前週が外部指令パルスに沿った周波数だったのに対し今週のはパルス発生も自分でやってしまおうという回路です。
先週のままとしてパルス入力は使用せず代わりにタイマ割り込みで出力パターンの移行をさせます。




■タイマ0割り込み

1.TMR0割り込みとします。
   そのために初期設定から変更を必要とするのは
     INTCONレジスタ bit5(T0IE)=1 TMR0オーバーフロー割り込み許可
                bit7(GIE)=1  割り込み発生許可
     OPTIONレジスタbit3(PSA)=0  プリスケーラTMR0割り当て
                bit5(T0CS)=0内部クロック
                bit0−2      プリスケーラレート 110で1:128

  INTCONレジスタ (bit7から) (初期0000000X) 
GIE bit7 グローバル割り込みイネーブル 1:許可
EE1E bit6 EEライト完了割り込みイネーブル 1:許可
T0IE bit5 TMR0オーバーフロー割り込みイネーブル 1:許可
INTE bit4 RB0/INT割り込みイネーブル 1:許可
RBIE bit3 RBポート変化割り込みイネーブル 1:許可
T0IF bit2 TMR0オーバーフロー割り込みフラグ 1:割り込み
INTF bit1 RB0/INT割り込みフラグ 1:割り込み
RBIF bit0 Bポート変化割り込フラグ 1:割り込み
  OPTIONレジスタ bit7から(初期11111111)
/RBPU bit7 PORTBプルアップイネーブル 1:使用
INTEDG bit6 RB0/INT割り込みエッジ選択 1:立ち上がりエッジ
T0CS bit5 TMR0クロックソース選択 1:RA4/T0CKI 0:内部クロック
T0SE bit4 TMR0ソースエッジ選択 1:立ち上がりエッジ
PSA bit3 プリスケーラ割り当て 1:WDT 2:TMR0
PS2 bit2 以下プリスケーラレート 例:000=1:2
PS1 bit1    110=1:128
PS0 bit0    111=1:256
2.ほかは前回の割り込みと類似
3.タイマ0は加算タイマなので設定値はオーバーフローまでの残数を書き込まなければならない。
  100Hから目的の値をマイナスして設定値とする
  

せっかくソフト的に処理するのだからちょっと遊んでみました。
最初は低速でスタートして一定回転数まで上げていくようにします。
こうすればステッピングモータは脱調することなく高速回転できます。
初めに100Hzでスタートし2KHzまで上げて一定回転となります。
プリスケーラ1:128としたので
  CPUクロック周期(0.1μsec)×4×128=51.2μsec
が基本カウント周期です。タイマ0は加算タイマなので
  100Hz -> 195カウント -> C3H -> 100H−C3H=3DH
  1KHz  -> 約10カウント-> 0AH -> 100H−0AH=F6H
として設定値を書き込みます。
;PMM8713ステッピングモータコントローラ代替(タイマ割り込みを使う)
;*********************************************
        LIST        P=PIC16F84    ;
        __CONFIG    _HS_OSC & _PWRTE_ON & _WDT_OFF
        INCLUDE     "P16f84.inc"  ;標準ヘッダ定義ファイル
                                  ;のインクルード
;*********************************************
CNT     EQU     0CH             ;出力パターン用カウンタ
TIMCNT  EQU     0DH             ;タイマ用カウンタ
WTEMP   EQU     0EH             ;Wレジスタ待避
STTEMP  EQU     0FH             ;STATUSレジスタ待避
INTTMCT EQU     010H            ;割り込みタイマ設定値
;***********************
;  メインルーチン
;***********************
        ORG     0               ;Reset Start
        GOTO    MAIN
        ORG     04H
        GOTO    INTR
        
MAIN                            ;Initialize        
        BSF     STATUS,RP0      ;バンク1へ切替
        BCF     INTCON,GIE      ;割り込み禁止
        MOVLW   06H             ;
        MOVWF   OPTION_REG      ;内部クロック、プリスケーラ1:128
        CLRF    TRISA           ;ポートAを出力モードに設定
        CLRF    TRISB           ;ポートBを出力モードに設定
        BCF     STATUS,RP0      ;バンク0に戻す
        
        MOVLW   B'00000000'     ;初期出力(実際は使用しない)
        MOVWF   PORTA
        MOVLW   B'10010000'     ;初期出力
        MOVWF   PORTB
        MOVLW   0H              ;COUNTER初期出力
        MOVWF   CNT
        
        MOVLW   03DH            ;タイマ値ロード
        MOVWF   TMR0            ;約100Hz
        MOVWF   INTTMCT         ;タイマ値記憶
        BSF     INTCON,T0IE     ;TMR0オーバーフロー割り込み発生許可
        BSF     INTCON,GIE      ;割り込み許可

LOOP1
        CALL    TIM             ;適当に回っている割り込み待ちのループ
        CALL    TIM
        GOTO    LOOP1
        
TABLE                           ;Wに波形パターンを載せてリターンするテーブル処理

        ADDWF   PCL,F
        RETLW   B'10010000'
        RETLW   B'00010000'
        RETLW   B'00110000'
        RETLW   B'00100000'
        RETLW   B'01100000'
        RETLW   B'01000000'
        RETLW   B'11000000'
        RETLW   B'10000000'
        
;*********************************************************
;割り込み処理
INTR
        BCF     INTCON,T0IF     ;割り込みフラグクリア                            
        MOVF    INTTMCT,W       ;タイマ値ロード
        SUBLW   0F6H            ;◎タイマ値F6(2KHz)まではINCしていく
        BTFSS   STATUS,Z        ; タイマ値と比較して同じならスキップ
        INCF    INTTMCT,F       ; 違うなら(大きいなら)INC
        MOVF    INTTMCT,W
        MOVWF   TMR0            ;
        MOVWF   WTEMP           ;レジスタ待避
        SWAPF   STATUS,W
        MOVWF   STTEMP
FWD                             ;正転カウント処理
        MOVF    CNT,W
        SUBLW   07H
        BTFSC   STATUS,2
        GOTO    SET0            ;カウンタ値 7 なら 0 に
        INCF    CNT,F
        GOTO    INCED
SET0    MOVLW   0H
        MOVWF   CNT
INCED   

PATTERN
        MOVF    CNT,W
        CALL    TABLE
        MOVWF   PORTB

        SWAPF   STTEMP,W        ;レジスタ復帰
        MOVWF   STATUS
        SWAPF   WTEMP,F
        SWAPF   WTEMP,W
        
        RETFIE
;*********************************************************
;サブルーチン
TIM                             ;0.4mSECタイマ
        MOVLW   0F9H
        MOVWF   TIMCNT
TIMLP   DECFSZ  TIMCNT,F
        GOTO    TIMLP
        RETURN

        END


起動時ゆっくりで加速して高速回転になります。
単純に+1づつ加算(パルス幅減算)したので加速の具合がはじめのうち徐々にしか加速がつかず、高速になるにつれ一気上がるようになってしまいます。数値加算処理にちょっと工夫があればさらになめらかになるかもしれません。面倒だから今回はこれで良しとして一応上々の結果と言うことに。(^^;





今週のなるほど

タイマ0は加算カウンタ。割り込みはオーバーフロー。これがちょっと面倒くさい。
設定する数値はFFHをオーバーフローする数値、つまり100Hからタイマ値を減算した値ということになります。