<V.3版>
  タイマ割り込みによる
  LED フリーラン
(コールバック関数 & 16bitタイマ)
(→プロジェクトファイル(Harmony Ver.3版) ダウンロード


   LEDのフリーラン点滅をタイマ割り込みを使って行います。 ここではHarmonyのライブラリ関数(コールバック関数)を使用した例を紹介します。 タイマは 16ビットのタイマを使います。
 尚、PIC32MZは32ビットのマイコンで9個のタイマがありますが タイマ1からタイマ9まですべて16ビットのタイマです。 32ビットのタイマを使う場合は 2つのタイマを連結する必要があります。(使用例 → URL
   
<仕様>
 ・ PIC32MZを使用する
 ・ LEDは1sec ON、1sec OFFを繰り返す
 ・ 動作クロックは外部に24MHzの水晶発振器を接続しこれを使用する    
 ・ 時間制御は、タイマ割り込みを使うこと
 ・ Harmonnyのライブラリ関数(コールバック関数)を使用すること 
<回路図>(→回路図のPDFファイル


 



<外観>
<動作結果>
(画像をクリックすると プログラム動作中の動画がYouTubeで再生します)

     
ディスクリートキバン

(PIC32MZ QFPモジュール組立キット → 購入方法
(QFPモジュール用ユニバーサルキバン → 購入方法

 
PIC32MZ評価ボード(MZ100-A001)

( → 購入方法 )
動作結果の
   動画再生
    







<解説>

 ステップ1:   MHC作成
 
1. [Clock Diagram]タブで、クロックの構成を外付け24MHz水晶発振器用、システムクロック200MHzに設定します。
 POSCMOD: → EC
 FPLLICLK: → POSC
 FPLLIDIV: → DIV_3
2. [Pin Settings]タブで、ピン1のRG15ポートを設定します。
Name: → LED1
Function: → GPIO
Direction(TRIS): → Out
3. [Available Component]タブのコンポーネントリストでPeripheralsのTMR1(タイマ1)をダブルクリックして[Project Graph]に追加します。 TMR1を選択すると[Configuration Option]タブに諸元が表示されるのでPrescalerを 1/256に設定します。 インターバル周期の詳細設定をきめるPeriod Register(PR2)の設定はソースコードの中で設定します。




 ステップ2: MHCから生成したソースコードの変更 
  ■ main.cに青字部を追加します
  ➀ 所要の変数を定義します。
    
  bool LED;
   
   
  ➁  タイマ1のコールバック関数を定義します。 この関数はタイマ1から1秒ごとに呼び出されます。
 
   
void TMR1_Callback_Fn(uint32_t status, uintptr_t context) //コールバック関数      //1秒毎に呼び出される
{
     if(LED == false)
        {
            LED = true;           
            LED1_Set();   //RG15: LED点灯  //plib_gpio.hで定義
            //    GPIO_PinSet(GPIO_PIN_RG15); //Harmonyライブラリの関数で制御
            //    LATGbits.LATG15 = 1;  //レジスタ直接制御
        }
        else
        {
            LED = false;             
            LED1_Clear();   //RG15: LED消灯 
            //    GPIO_PinClear(GPIO_PIN_RG15);
            //    LATGbits.LATG15 = 0;
        }
     
    //LED1_Toggle();    //RG15:LED 点灯/消灯
}

   
   
  ③ TMR1_PeriodSet()関数でPeriod Register(PR1)の値を設定します。 このレジスタで設定できる最大値は16ビット(65536)です。
レジスタに直接 PR1 = 39063; と書き込むこともできます。 
 タイマ1のクロックソースは、システムクロック200MHzの1/2で デフォルトのPBCLK3では100MHzです。(→URL)
 ソースクロックが100MHzだと プリスケーラを最大の256に分周してもインターバル時間は 10nsec x 65536 x 256 = 167,772,160nsec = 167.7msec が最大周期となります。 仕様の周期1secにはならないので 本プロジェクトでは initialization.c()でPBCLK3を10MHzに変更して 1secの周期をつくります。
  100 nsec x 39063 x 256 = 1000012.8μsec = 1000.0128msec
       
    TMR1_PeriodSet(39063);  //50 nsec x2  x 39063 x 256 = 1000012.8μsec = 1000.0128msec  
                            //クロック:100MHz → 10MHz at interrupts.c
//  //PR1 = 39063;    //レジスタ直接設定
 
 
   
  ④ Harmonyのライブラリ関数 TMR1_CallbackRegister()で タイマ1のコールバック関数を宣言します。 
  そしてTMR1_Start()関数でタイマ1をイネーブルにするとタイマ1が動作開始します。 
 
 
    TMR1_CallbackRegister(TMR1_Callback_Fn, NULL);  //コールバック関数設定 
                                                    //void TMR1_CallbackRegister(TMR_CALLBACK callback_fn, uintptr_t context);  
    
    TMR1_Start();   //タイマ1 スタート
    //T1CONbits.ON = 1;     //レジスタ直接制御
   
   
   
  以下、 main.c 全文
 
   
   
   



  ■ initialization.c に青字部追加
  ➀ SYS_Initialize()関数の中で、PBCLK3のクロック周波数を 100MHzから 10MHzに変更します。
  クロック周波数を変更する場合は、 アンロックシーケンス(unlock sequence) で クロックの状態をアンロックにして PBxDIVレジスタの値を変更する必要があります。 クロックを変更したあとは再びロック状態に戻します。
  Harmony V2では SYS_DEVCON_SystemUnlock() と SYS_DEVCON_SystemLock() と云う関数が用意されていましたが Harmony V3ではまだライブラリ関数は用意されていないようです。 したがって、ここではレジスタに直接書き込んでアンロックシーケンスを制御しています。
 
// PBCLK3ペリフェラルクロック変更  
     
    //アンロックシーケンス(unlock sequence)      //Unlock the device      
    SYSKEY = 0;             // Ensure OSCCON is locked
    SYSKEY = 0xAA996655;    // Write Key1 to SYSKEY
    SYSKEY = 0x556699AA;    // Write Key2 to SYSKEY

   PB3DIVbits.PBDIV = 0x13;  //19: PBCLK3(Timer,OC等ペリフェラルクロック):1/20(デフォルトの1/10)               --> 10MHz(= 200MHz/20) 
//    PB3DIVbits.PBDIV = 0x01;  //1(デフォルト): PBCLK3(Timer,OC等ペリフェラルクロック):1/2 (デフォルトの1/1)  --> 100MHz(= 200MHz/2) 
//    PB3DIVbits.PBDIV = 0x00;  //0: PBCLK3(Timer,OC等ペリフェラルクロック): 1/1(デフォルトの2倍)              --> 200MHz(=200MHz/1)
   
   //Lock the device
    SYSKEY = 0x33333333;

   
   
  以下、 initialization.c 全文