こんにちは、ENGかぴです。
PICマイコンにはタイマー機能があり16ビットタイマとしてTMR1があります。TMR1の初期値を調整することで任意のタイミングでオーバーフローするタイマを作ることができます。MCCを使用してTMR1を実装する方法をまとめています。
PIC16F1827で動作確認したことについてリンクをまとめています。
PICマイコン(PIC16F1827)で実現できる機能と解説リンクまとめ
タイマー1(TMR1)の考え方
PICマイコン(8ビットマイコン)のTMR1の使い方について説明します。TMR1は初期値からスタートして16ビットの最大値である0xFFFF(65535)を超えるとオーバーフローして時間経過を通知します。
動作クロックに対してTMR1の動作を管理するClock Sourceを選択します。内部のクロック使用するためFOSCもしくはFOSC/4を選択します。
TMR1のプリスケーラー(Prescaler)はClock Sourceが生成したパルスを分周します。1:2を選択するとClock Sourceの2パルス分でTMR1のカウントを+1します。
Clock SourceをFOSC/4、プリスケーラが1:2の場合について考えてみます。TMR1のカウントが+1されるタイミングがClock Sourceとプリスケーラによって決まるため1カウント当たり2us経過します。
初期値を設定しない場合は65535カウントを超えるとオーバーフローするため132.072msになります。任意のタイミングでオーバーフローさせるためには初期値を設定します。
例として100[ms]でオーバーフローするタイマーを考えてみます。オーバーフローするまでのカウント値は0xFFFFで変わらないため初期値を変更してオーバーフローまでの時間を作ることになります。
初期値は簡単な対比で計算できます。カウント1つで2usなので100ms(100000us)を作るためのカウント値は2:100000 = 1 : Xになります。
Xは50000になるので初期値は65536から50000を引いた15536になります。
この100msをベースタイマーとして考えて各種のタイマーを構成の例を上げます。
例1)200msタイマで管理したい場合
100msのタイマーのオーバーフローが2回発生すると200ms経過したことになります。
例2)1000msタイマーで管理した場合
100msのタイマーのオーバーフローが10回発生すると1000ms経過したことになります。
TMR1の設定を実装する
PIC16F1827のTMR1の設定をMCCを使って行います。MCCについては下記記事にまとめています。
MPLAB Code Configurator(MCC)の追加と使い方
TMR1をMCCで設定する
最初に共通事項であるSystem Moduleの設定を行います。
内部クロックを使用するためINTOSCを選択しています。Intemal Clockは4MHz(任意でも良い)を選択しています。
TMR1はDevice Resources内のPeripherals欄のTimerを選択しTMR1をクリックして追加します。
Timer Clock内でクロックに関する設定を行います。Clock Sourceは内部クロックを使用しているためFOSC(FOSC/4)を指定します。PrescalerはClock Sourceに対してTMR1のカウントアップする分周比を指定します。
Timer PeriodはTMR1がオーバーフローするタイミングを設定します。指定の仕方は2通りありますがmsで指定する方が分かりやすいためお勧めです。
例では初期値カウント値を計算して②に指定してオーバーフローまでのタイミングを指定しています。②に16進数で指定するとCalculated Periodが100msになっています。
動作確認用の回路
LED1とLED2はHアクティブとLアクティブのハード構成にしているためRA7とPB6をHIGHにしても反対の動きになります。SW1を押したときLED3が点灯するようにします。
RB0はウィークプルアップしているため信号レベルが浮くことはありません。SW1を押すとLED3が点灯し押さない場合はLED3が消灯するようにします。
PB0はINPUTでウィークプルアップ(WPU)設定しています。WPUを有効にするためにはRegistersのnWPUENをenabledにする必要があります。
Easy SetupでWPUにチェックするのみでは有効にならないので注意が必要です。Notificationsにワーニングで通知されます。
TMR1を使ったタイマ管理
TMR1を使用してLEDを点灯/消灯させるためにタイマ管理を行います。MCCが生成したmain.cのwhile(1)部分にmainApp()関数を追加しています。
void mainApp(void){
if(TMR1_HasOverflowOccured() ){
PIR1bits.TMR1IF = 0; //TMR1オーバーフロ時にセットされるクリアが必要
TMR1_StopTimer(); //タイマを一時停止
TMR1_Reload(); //タイマの初期値を設定する
TMR1_StartTimer(); //タイマの動作開始
if( ++cnt >= 2 ){
cnt = 0;
IO_RA7_Toggle();
IO_RB6_Toggle();
}
}
if( IO_RB0_GetValue()){
IO_RA3_SetLow();
}else{
IO_RA3_SetHigh();
}
}
MCCが生成した関数を使用してTMR1に関する設定をしています。TMR1に関する処理はtmr1.cで確認できます。以下に使用した関数についてまとめています。
関数 | 内容 |
---|---|
TMR1_HasOverflowOccured() | TMR1IFの状態を確認する。TMR1がオーバーフローするとTMR1IFがセットさせる。TMR1IFをユーザーでクリアする必要がある。 |
TMR1_StopTimer() | TMR1のカウントを停止する。 |
TMR1_Reload() | TMR1のカウント値にTMR1_Initialize()で設定した初期値をセットする。 |
TMR1_StartTimer() | TMR1のカウントをスタートする。 |
TMR1がオーバーフローしてタイムアップすると初期値をセットしなおし再びTMR1のカウントをスタートします。
オーバーフローまでに100ms経過し、2回オーバーフローしたときにRA7とRA6のDOの出力を反転させているため200ms毎にLEDが点灯/消灯します。
メイン関数内でオーバーフローの確認を行う問題点
メイン関数(while(1))の処理が増えて重たくなった時に問題となる場合があります。処理が少ない間はmain関数を1周する時間は短いため問題になりませんが、ソフトを追加していくにつれてメイン関数(while(1))の1周当たりの時間が長くなってしまいます。
タイマーのタイミングが動作に影響を与えるようなシステムではメイン関数でのタイマーのオーバーフローの確認は採用しないほうが良いと言えます。
割り込み内でLEDを点灯消灯させてもよいですが割り込みの頻度が多くなればメイン関数に戻りにくくなるなどバランスをとった使い方をする必要があります。割り込みの考え方と注意事項については下記記事を参考にしてください。
PICマイコン(PIC12F675)の割り込みの考え方と注意事項
ソースコード全体
以下のソースコードはコンパイルして動作確認をしております。コメントなど細かな部分で間違っていたりやライブラリの更新などにより動作しなくなったりする可能性があります。参考としてお使いいただければと思います。
#include "mcc_generated_files/mcc.h"
//--------------変数定義----------------------------
char cnt;
void mainApp(void);
/* Main application */
void main(void)
{
SYSTEM_Initialize();
while (1)
{
mainApp();
}
}
// Add mainApp
void mainApp(void){
if(TMR1_HasOverflowOccured() ){
PIR1bits.TMR1IF = 0; //TMR1オーバーフロ時にセットされるクリアが必要
TMR1_StopTimer(); //タイマを一時停止
TMR1_Reload(); //タイマの初期値を設定する
TMR1_StartTimer(); //タイマの動作開始
if( ++cnt >= 2 ){
cnt = 0;
IO_RA7_Toggle();
IO_RB6_Toggle();
}
}
if( IO_RB0_GetValue()){
IO_RA3_SetLow();
}else{
IO_RA3_SetHigh();
}
}
/* End of File */
本ソースコードはMPLAB X IDEにMCCのプラグインをインストールしていることが前提となります。MCCをインストールする方法は下記記事を参考にしてください。
MPLAB Code Configurator(MCC)の追加と使い方
関連リンク
関連リンクではPIC16F1827を使ってマイコンの基本動作を確認するために動作確認したことについてまとめています。
PICマイコン(PIC16F1827)で実現できる機能と解説リンクまとめ
PR: わからないを放置せず、あなたにあったスキルを身に着けるコツを教える テックジムPython入門講座の申込
最後まで、読んでいただきありがとうございました。