高精度タイマーを使う
投稿:2012-03-06
接続したLCDは、I2Cでコマンドを送信してから26.7μsのウエイトが必要なのです。
FreeRTOSのDelayは1ms単位(TickTime)ですしタイマーも同様です。
ですので、μs単位のDelay関数を用意してありますが、1ms未満のDelayも1msだけ待っています。
より短時間(高精度)のタイマーを使いたい時は、マイコンの仕掛けを直接使って実現することになります。
LPCXpresso(1768)の場合、マイコンの中にタイマー/カウンター兼用の装置が4組入っています。そのうちの1つを使って1μs単位のDelay機能を用意しました。
タイマーへ供給するクロックはCPUのクロック100MHzのまま使って、プリスケーラで100分の1に落とすと、ちょうど1MHzになってクロック間隔が1μsになるという具合。
さて、今回の鉄ゲタコーナーは…ありません(ほっ)。
まあ、どうせ話が通じないと思うので、あとはソース見てください(^^;
yrntrlmnmnt20120214.zip
static xQueueHandle pQueueTimer = NULL;
static uint32_t uTimer = 0;
//タイマー割り込み
void TIMER0_IRQHandler(void)
{
unsigned long ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
//タイマー値が残っていればカウントダウン
if (0 < uTimer)
{
uTimer--;
//0で呼び出し元へダミーのデータを送信する
if (!uTimer)
{
portBASE_TYPE HigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(pQueueTimer, "t", &HigherPriorityTaskWoken);
if (HigherPriorityTaskWoken)
{
//中身はvPortYieldFromISR
taskYIELD();
}
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(ulDummy);
}
void timer_delay_us(uint32_t uMicroS)
{
//入れた途端にカウントダウンする場合があるので、+1
uTimer = uMicroS + 1;
uint8_t ucDummy;
if (pQueueTimer)
{
//カウント0でキューにダミーデータが入るのを待つ
xQueueReceive(pQueueTimer, &ucDummy, portMAX_DELAY);
}
}
今ソース見て気づいたけど、タイマーに時間を指定すると、時間が来た時に割り込みルーチンに制御が来るので、
わざわざプログラムでカウントダウンしなくてもいいんだ。
ここは次の機会に改善しておこう。さて、今回の鉄ゲタコーナーは…ありません(ほっ)。
まあ、どうせ話が通じないと思うので、あとはソース見てください(^^;
yrntrlmnmnt20120214.zip
