【dsPIC33FJ128MC802】タイマー機能を使ってみる。(LEDピカピカ)

2020年4月4日


◆dsPIC33FJ128MC802でタイマー機能を使ってみます。
delay関数の元になってもらいたいと思います。
1)タイマー機能
リファレンスマニュアル70205C参考にトライしました。
dsPIC33FJ128MC802は、それぞれA,B,Cの3種類のタイマー機能をもってます。
Aタイプ:TIMER1
Bタイプ:TIMER2、TIMER4
Cタイプ:TIMER3、TIMER5
いずれも16bitタイマーですが、BとCは連結し32bitにすることが出来ます。
32bitタイマーの組み合わせは下記の通りです。
・TIMER2+TIMER3
・TIMER4+TIMER5
2)レジスター設定
制御レジスターTxCON、カウンタレジスタTMRx、周期レジスタPRxの3つを設定します。
PR1とTMR1が一致したらT1IFbitがセットされことを利用したいと思います。
・T1CON1レジスタの設定
・PS(プリスケーラー)を1:1で設定しました。
長い時間をカウントさせたい場合はより多くの分周が必要になりますね。
・TMR1レジスタの設定
TMR1には0を代入しました。
・PR1レジスタの設定
周期レジスターPR1に代入する値を検討したいと思います。
生成したい時間1μsecまでTMR1には何カウントしてもらえばよいのでしょうか?
39.61MPISの場合、1サイクルにかかる時間は「0.025μsec」なので
1μsec=0.025μsec×PS×カウント数  という式が導けますね。
変形して・・・
カウント数=(1μsec/0.025μsec×1)-1※
(※カウンターは「0」からなので-1する。)
これをPR1に代入します。
3)プログラム例
プログラムの例はこちら↓
1sec毎にLEDがピカピカです。

//=========================================================
//  TEST
//=========================================================
//== ヘッダファイル ============================================
#include <p33fj128mc802.h>
#include <stdio.h>
//== define ===========================================================
//== configuration ======================================================
_FBS(BSS_NO_FLASH & BWRP_WRPROTECT_OFF);
_FGS(GSS_OFF & GCP_OFF & GWRP_OFF);
_FOSCSEL(FNOSC_FRCPLL & IESO_OFF);
_FOSC(FCKSM_CSDCMD & IOL1WAY_ON & OSCIOFNC_ON  & POSCMD_NONE);
_FWDT(FWDTEN_OFF);
_FPOR(FPWRT_PWR128 & ALTI2C_OFF);
_FICD(JTAGEN_OFF & ICS_PGD1);
//== interrupt_function_prototype ================================================
//== MyTimer =====================================================================
void delay_us(unsigned int usec);   //Timer1を利用したusec関数
void delay_ms(unsigned int msec);   //msec関数
//== main ==================================================================
int main(void)
{
//== クロックの設定 ======================================================
//== Fcy=Fosc/2=7.37M*((PLLFBD+2)/(N2*N1))/2=39.61MHz ================
CLKDIVbits.PLLPOST = 0;   //N2=2
CLKDIVbits.PLLPRE  = 0;   //N1=2
PLLFBDbits.PLLDIV = 41;   //M=PLLFBD+2
//== ウォッチドック設定 ====================================================
RCONbits.SWDTEN = 0;    //OFF
//== AD切り替え ==========================================================
AD1PCFGL = 0xffff;      //全digital
//=== TRISA ===========================================================
TRISA = 0x0000;            //initial_
//== TRISB =============================================================
TRISB = 0x0000;            //input:
//== TIMER1設定 =========================================================
T1CONbits.TON = 0;      //15_Timer1_OFF
T1CONbits.TSIDL = 1;        //13_アイドルモード:Sleep中は停止
T1CONbits.TGATE = 0;        //6_ゲート積算時間:OFF
T1CONbits.TCKPS = 0B00;      //5-4_PS1:1
T1CONbits.TCS = 0;      //2_クロックソース:内部
IEC0bits.T1IE = 0;      //割り込み拒否
IPC0bits.T1IP = 0;      //優先レベル0
//== 前処理 ======================================================
//== while文 ===========================================================
while(1)
{
//== 前段デバック =======================================================
LATAbits.LATA3 = !LATAbits.LATA3;
delay_ms(1000);
//== 前段デバック =======================================================
}//while(1)
}//int main(void)
//== delay_us関数 =================================================================
void delay_us(unsigned int usec)
{
TMR1 = 0;     //TMR1=0
T1CONbits.TON = 1;      //Timer1_start
PR1 = 39;     //PR1値:((目的値1usec)/(1サイクル:0.0025usec*PS)-1)=39
unsigned int i;
for(i=0; i<usec; i++)
{ //タイマーフラグ待ち
while(!IFS0bits.T1IF);    //Timer1一致フラグチェック(IFS0bits.T1IF==0)
IFS0bits.T1IF = 0;      //一致フラグ下ろす
}//for(i=0; i<usec; i++)
}//void delay_usec();
//== delay_ms関数 ==================================================================
void delay_ms(unsigned int msec)
{
unsigned int i;
for(i=0; i<msec; i++)
{
delay_us(1000);      //call:1000usec
}//for
}//void delay_ms
//=================================================================================

4)回路図はこちら
RA3にLEDをつければピカピカですね。
3e3e90a7.png

よろしければバナーをクリックお願いします!