JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

MPLABアセンブラ PIC16F648A タイマー割り込みテスト

2024-11-04 15:22:29 | MPLAB アセンブラ
  MPLAB IDE v8.92 MPASM v5.51 PICKit3の環境で、PIC16F648Aのタイマー割り込みの使い方を勉強します。 

 PIC16F648Aは、8bitタイマーを2個(TMR0とTMR2)と16bitタイマー1個(TMR1)持っています。今回は、TMR2を使ってなるべく正確な1秒を発生させて、LEDを点滅させてみます。

 正確性を上げるためには、外部のクリスタルオシレータからクロックを供給します。今回は20MHzのクリスタルオシレータ(SG-8002)を使い、TMR2のオーバーフロー割り込みを利用して1秒を発生させます。(正確な1秒を発生させることができれば、周波数カウンタや時計などに利用することができます。)

 回路図です。



 今回もICSPでテストします。クリスタルオシレータは、RA7に接続します。RB0に接続したLEDを1秒ごとに点滅させます。

 外部クロックを利用する場合、__CONFIGには、_EXTCLK_OSCと記載します。他の設定は、これまでと同じです。

 TMR2のブロックダイアグラムです。TMR2はPWMにも利用されますので、このような形になっています。

 Prescalerは 1:16,Postscalerは1:1とします。
 Fosc=20MHz=20000000Hzですので、Prescalerを通過すると20MHz/4=5MHz=5000000Hzが、5000000/16=312500Hz(周期3.2us)となり、TMR2に供給されます。

 TMR2は8BITですから、さらに256分の1されます。Postscalerは、1:1ですので、312500/256=1220.703125Hz、つまり1秒間に約1220回割り込みが発生します。周期にすると3.2us×256=819.2usごとに1回の割り込みが発生します。割り込み回数をカウントするカウンタを設定して、1220回または1221回カウントすれば良いことになります。

 時間の精度を上げるために更に工夫します。カウンタ初期値を1221とし、割り込みがあるたびにデクリメントします。3.2us周期の割り込みですから、カウンタが0になった時、時間経過は1221×819.2=1000243.2us=1.0002432sとなり、1秒を超えてしまいます。そこでTMR2に256から、243.2us/3.2=76を引いた値、256-76=180をセットしておくことにより、最初の割り込みの時に243.2us早く割り込みを発生させます。これでカウンタが0になった時に、正確な1秒を得ることができます。

 各レジスタの設定です。
TMR21のPrescalerとPostscalerの設定は、T2CONレジスタで行います。

 Prescalerの設定は、T2CKPS1とT2CKPS0で行い、1:16の場合は、1Xです。(Xは0でも1でもよい)
 Postscalerの設定は、TOUTPS3~TOUTPS0で行い、1:1の場合は、0000です。
 
 割り込み関係設定をします。PIE1レジスタのbit1 TMR2IEを1として、TMR2への割り込みを許可します。


 また、全割り込み、汎用割り込みをINTCONレジスタのGIEとPEIEを1にして割り込みを有効にします。



 割り込みが発生した時は、PIR1レジスタのTMR2IFが1になります。



 プログラムです。
 割り込みが発生した時の入り口は0X04番地です。
 割り込み処理ルーチンで、最初にWレジスタとSTATUSレジスタの内容を待機させ、最後に復帰させます。割り込みフラッグTMR2IFは最初にクリアしておきます。
-----------------------------------------------
              LIST      P=PIC16F648A
              INCLUDE           P16F648A.INC
              
              __CONFIG _EXTCLK_OSC & _CP_OFF & _CPD_OFF & _WDTE_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _MCLRE_OFF
              ERRORLEVEL -302

;レジスタ
              CBLOCK             020h
              CNTH
              CNTL
              SAVE_W
              SAVE_ST
              ENDC
              
              ORG      0x00                    ;電源ON,RESET入口
              GOTO   SETUP
              
              ORG      0x04                    ;割り込み時の入口
INTR
;WレジスタとSTATUSレジスタの内容を保存
              MOVWF              SAVE_W
              SWAPF  STATUS,W
              MOVWF              SAVE_ST
              
              BANKSEL           PIR1
              BCF                     PIR1,TMR2IF      ;TMR2割り込みフラッグクリア
              DECFSZ              CNTL
              GOTO   INTEXIT                                         ;COUNTERL!=0なら割り込み処理終了
              MOVFW              CNTH
              IORLW  00h
              BTFSC   STATUS,Z                         ;ゼロでないならスキップ
              GOTO   LEDTOGGLE
              DECF    CNTH,F
              GOTO   INTEXIT
              
LEDTOGGLE
              BANKSEL PORTB
              BTFSS   PORTB,0
              GOTO   LED_ON
LED_OFF
              BCF                     PORTB,0                          ;LED OFF
              GOTO   TOGGLE_END
LED_ON
              BSF                      PORTB,0                          ;LED ON
TOGGLE_END

;TMR2に初期値セット
              BANKSEL           TMR2
              MOVLW              0B4h                    ;0B4h=180
              MOVWF              TMR2                  ;TMR2初期値セット
;COUNTERに1221=04C5hをセット          
              MOVLW              04h
              MOVWF              CNTH
              MOVLW              0C5h
              MOVWF              CNTL

INTEXIT
;STATUSレジスタとWレジスタの内容を復帰
              SWAPF  SAVE_ST,W
              MOVWF              STATUS
              SWAPF  SAVE_W,F
              SWAPF  SAVE_W,W

              RETFIE
              
SETUP
;入出力設定
              BANKSEL           TRISA
              CLRF     TRISA                 ;PORTAは全て出力(RA5は入力に設定される)
              CLRF     TRISB                 ;PORTBは全て出力
              BANKSEL           CMCON
              MOVLW              07h
              MOVWF              CMCON                            ;コンパレータは使わない
              BANKSEL           PORTB
              CLRF     PORTB
              
;TMR2設定
              BANKSEL           T2CON
              MOVLW              B'00000110'        ;
              MOVWF              T2CON               ;postscalere 1:1,prescaler 1:16,TMR2ON
              BANKSEL           PIE1
              BSF                      PIE1,TMR2IE      ;TIMER2割り込み許可
;割り込み設定
              BANKSEL INTCON
              BSF                      INTCON,GIE                    ;全割り込み許可
              BSF                      INTCON,PEIE                  ;汎用割り込み許可
              
MAIN
              GOTO   MAIN

              END
----------------------------------------------- 

 ブレッドボードです。LEDが1秒ごとに点灯、消灯を繰り返します。


 クリスタルオシレータの精度やプログラムにより、数us程度の誤差がでると思います。周波数カウンタなどのタイムベースに使う場合は、更に誤差を少なくする工夫が必要になります。

最新の画像もっと見る

コメントを投稿