PICで電飾 割り込み処理 その3 タイマ1の設定方法 | 波動砲口形状研究

PICで電飾 割り込み処理 その3 タイマ1の設定方法

呼び出し呪文と周期のパラメータ

3種類のタイマ機能のうち、前回はタイマ0を使ってみたので、今度は同じ作業をタイマ1を使ってやってみましょう。

 

今回も一番下にプログラムを載せておきます。やっていることは前回と全く同じです。

 

1)赤字がタイマ1を使うのに必要なところです。呪文と同じようなものなのでコピペして使ってください。一応意味は//以降に書いています。

 

2)水色の背景のところが、割り込みの周期を決めるパラメータです。

 

タイマ1でも3つの要素で周期が決まります。

 

①クロック数

②プリスケール

③TMR1初期値

 

ここでも20ミリ秒ごとに割り込み処理をすることにして、計算は「PICとは」に頼りましょう。

 

フォームのプリスケール(赤丸)と、TMR1初期値(緑丸)をいじって、タイマ周期を20ミリ秒にします。

 

このとき、緑丸の数字は、直接入力せずに、かならずフォームについている数字のボタン(緑の枠)のところを押して上下させてください。

 

 

今度はきっちりタイマ周期を20ミリ秒に出来ましたね(オレンジの矢印)。タイマ1の方がタイマ0より緻密にコントロールできるということのようです。ではこれらのパラメータを書き込みましょう。

 

①クロック数の設定

クロック数の設定はタイマ0と同じにしておきます。

 

     OSCCON = 0b01110010 ;//①内部クロック8MHz   

 

②プリスケールの設定

②のプリスケールの設定は、T1CONというレジスタの下から5.6桁目の数字を変えることで設定します。

 

        T1CON=0b00110000;//②プリスケール値8

 

プリスケールの値は8でした。これをレジスタの入れるときは下の表に従って、

11を水色の背景のところに入れるわけです。

 

③TMR1初期値

③のTMR1初期値がちょっと厄介です。これは、フォームの計算では60536と出てきましたが、そのままの数字では使えません。

 

 1)60536という10進数の数値を16進数に直す

 2)できた16進数の数字を上2桁と下2桁に分けて、TMR1HTMR1Lに代入する

 

というめんどくさい作業が必要なのです。

 

10進数を16進数に直すのは、エクセルの関数でも出来ますし、そういう電卓フォームを提供してくださるWebページで計算するのも一手です。お勧めはカシオのページ

 

60536を入れると、 16進数でそれはEC78だと教えてくれます。これを上2桁のECと下2桁の78に分けます。

 

16進数のECと78を10進数にもう一度直すと236と120になります。

 

あー行ったり来たりめんどくさい…。あれ?これって、

 

 

もうすでにここに計算してくれてあるやん。

 

というわけで、タイマー1初期値はフォームが計算してくれるTMR1H:TMR1Lの数値を引いてきて

 

        TMR1H=236;//③タイマ1初期値1
        TMR1L=120;//③タイマ1初期値2

 

こう書けばいいわけです。

 

自分でTMR1初期値を10進で計算し、16進に直して…の作業はうんざりですが、このページのフォームを使えばあっという間。

 

他のどんな本やwebページ見たってこんな初心者に優しいツール、提供してくれません。

いやほんと、このページ、素晴らしいっ…!ありがたいっ…!

 

というわけでプログラムです。コピペしてビルドと書き込みをやってみてください。うまく動くでしょうか?確認してみてください。(動作自体は前回と全く同じなんですけど・・・。)

 

 

 

#include <xc.h>
#define _XTAL_FREQ  8000000     

//コンフィグ設定
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config CLKOUTEN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config WRT = OFF
#pragma config PLLEN = OFF
#pragma config STVREN = ON
#pragma config BORV = HI
#pragma config LVP = OFF


int Event=0;


void main(void)
{
     //特殊レジスタの設定

     OSCCON = 0b01110010 ;//①内部クロック8MHz    
     ANSELA = 0b00000000 ;//RAの足をすべてデジタルI/Oとして使う     
     ANSELB = 0b00000000 ;//RBの足をすべてデジタルI/Oとして使う     
   
     OPTION_REG = 0b00000000 ;//内部プルアップ抵抗を使う
     TRISA  = 0b00000000 ;//RAの足はすべて出力に使う  
     TRISB  = 0b00001100 ;//RBの足のうちRB2,RB3を入力に使う
     WPUB   = 0b00001100 ;//RB2,3に内部プルアップ抵抗をつなぐ
     PORTA  = 0b00000000 ;//RAの初期値はすべてゼロ
     PORTB  = 0b00000000 ;//RBの初期値はすべてゼロ

      
        // タイマー1設定
        T1CON=0b00110000;//②プリスケーラ値8
        TMR1H=236;//③タイマ1初期値1
        TMR1L=120;//③タイマ1初期値2
        TMR1IF=0;//タイマ1割り込みフラグ0にする    
        TMR1IE=1;//タイマ1割り込み許可
        TMR1ON=1;//タイマ1スタート
   
        PEIE=1;//周辺割り込み許可
        GIE=1;//全体割り込み許可
   
    while(1)
    {
        if (Event==0)//平常時
        {  
         RB6=1;  RB7=0;//RB6点灯、RB7消灯
         __delay_ms(1000); //1秒待つ
         RB6=0;  RB7=1;//RB6消灯、RB7点灯
         __delay_ms(1000);//1秒待つ
         }
       
        if (Event==1)//イベント時
        {
         RA1=1;//RA1を点灯
         RB6=0;  RB7=0;//翼端灯消灯
         __delay_ms(5000);//5秒まつ
         RA1=0;//RA1を消灯
         Event=0;//イベント終了
        }
    }
}
void __interrupt() xxx(void)
{
    if(TMR1IF)//タイマ1による呼び出し
        
    {
        TMR1H=236;//タイマ1初期値にもどす
        TMR1L=120;//タイマ1初期値にもどす
        
        if(RB3==0 && Event==0)//もしRB3が押されていて、イベントが起きていなかったら
        {
            Event=1;//イベントフラグ立てる
        }
        TMR1IF=0;//タイマ1による割り込みリセット
    }
}