PIC32MX CoreTimer Delay 関数

2016年9月22日

以前よくわからないCoreTimerの使い方を書きましたが、今回はシンプルに。
参考にしたのはこちら。
Core timer handler stops updating ?

更にmCTが使えなくなっているので、16/08/27バージョン。100nはPICの速度によって使えなかったり。固まるのでわかるかと。割り込みには対応していないので、基本的にはmain関数内のみ。または同じ割り込みレベルのみ。

whileの上の行をwhileの下に書けば、ちゃんと動く気はしますが、割り込みが全部止まるので、使い物にはならないでしょう。最上位割り込みならおkかな。

#include <xc.h>
#define _SUPPRESS_PLIB_WARNING
#define _DISABLE_OPENADC10_CONFIGPORT_WARNING
#include <plib.h>
#include "lib.h"

#ifdef __PIC32
// ----------------------------------------------------------------------------
//
void delayCT100n(volatile unsigned long nsec)
{
    unsigned int status;
    unsigned long delay = (GetSystemClock() / (2 * 10000000ul)) * nsec;
    
    status = INTDisableInterrupts();
    OpenCoreTimer(delay);
    INTClearFlag(INT_CT);
    INTRestoreInterrupts(status);
    while( !INTGetFlag(INT_CT) );
}

// ----------------------------------------------------------------------------
//
void delayCT1u(volatile unsigned long usec)
{
    unsigned int status;
   
    status = INTDisableInterrupts();
    OpenCoreTimer((GetSystemClock() / (2 * 1000000ul)) * usec);
    INTClearFlag(INT_CT);
    INTRestoreInterrupts(status);
    while( !INTGetFlag(INT_CT) );
}

// ----------------------------------------------------------------------------
//
//
void delayCT1m(volatile unsigned long msec)
{
    unsigned int status;
    
    status = INTDisableInterrupts();
    OpenCoreTimer((GetSystemClock() / (2 * 1000ul)) * msec);
    INTClearFlag(INT_CT);
    INTRestoreInterrupts(status);
    while( !INTGetFlag(INT_CT) );
}

 

// ----------------------------------------------------------------------------
//
void delayCT1u(volatile unsigned long usec)
{
unsigned int status;

status = INTDisableInterrupts();
OpenCoreTimer((GetSystemClock() / (2 * 1000000UL)) * usec);
mCTClearIntFlag();
INTRestoreInterrupts(status);
while( !mCTGetIntFlag() );
}

// ----------------------------------------------------------------------------
//
//
void delayCT1m(volatile unsigned long msec)
{
unsigned int status;

status = INTDisableInterrupts();
OpenCoreTimer((GetSystemClock() / (2 * 1000UL)) * msec);
mCTClearIntFlag();
INTRestoreInterrupts(status);
while( !mCTGetIntFlag() );
}

 

1u delay ですが、割り込み禁止などの処理が入っているので、さらに1uほど遅れます。

delayCT1u(1);

とすれば、大体2uになります。
1msecの関数もありますが、単にusecだと桁が多すぎて間違えそうなので作っただけで、1usecの関数でもおkです。

これで、PICの動作周波数を変えても確実にdelayができます。Nop();の連打は変わりますので。

MIPS16にはCoreTimerが対応していないので、MIPS32でコンパイルする必要があります。

PIC32

Posted by saba