第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からタイマ値を減算した値ということになります。