ちょっとTea Time!? PICO repeating_timerの憂鬱【備忘録】 2025.1.12

PICOで周期割り込み(タイマー割り込み)を実施する場合の
基本的な記述は下記の通り。

bool timer_callback(repeating_timer_t *rt)
{
 //ここに割り込みの処理を記入
 return(true);  // falseを返すと、割り込みが停止する。
}

void main()
{
 static repeating_timer_t timer;

 stdio_init_all();

// タイマー割り込み開始
 add_repeating_timer_us(-1000,&timer_callback,NULL,&timer);


//タイマー割り込み停止
 cancel_repeating_timer(&timer);
}

割り込み開始の記述は2通りで、時間単位がusとms。
下記の例だと1000us(1ms)毎あるいは1000ms(1秒)毎に割り込みがかかります。
 add_repeating_timer_us(-1000,&timer_callback,NULL,&timer);
 add_repeating_timer_ms(-1000,&timer_callback,NULL,&timer);

ここで注意点が判明
 数値が負の場合は割り込み周期は(負を除いた)数値のまま
 数値が正の場合は設定数値+割り込み処理時間

たとえば、下記の設定で割り込み処理時間が500usかかる場合は、
割り込み周期は約1500usになります。
 add_repeating_timer_us(1000,&timer_callback,NULL,&timer);

ここで備忘録:
1.割り込み周期の最低値は20usを目途に設定のこと。
  15usでは動作しません(ハングアップ?)する。
  なおadd_repeating_timer関数を実行してから、割り込み開始まで20us以上のタイムラグがあります。

2.割り込み処理時間は割り込み周期を越えないこと

 例えば2において、割り込み周期20usに設定して割り込み処理時間を50usにすると
 動作できない(ハングアップ?)するようです。したがって、割り込み処理の中で
 赤外線受光のサブルーチンを入れる場合は要注意です。

 割り込み処理の時間が、場合によっては、割り込み周期より長くなる場合があるときは次のように、
 適当な広域変数を定義しておいて、メインルーチンで割り込みを再度かけるようにしておくのも一つの手です。

repeating_timer_t timer;
static int timer_irq_flag = 0; // これが0でなければ、メインループで割り込みを設定する。

bool timer_callback(repeating_timer_t *rt)
{
 // 割り込み処理
 timer_irq_flag = 1; // メインループで割り込みを要求する。
 return(false);  // falseを返して割り込みを停止させる。
}

void main()
{
 stdio_init_all();

 add_repeating_timer_us(-250,&timer_callback,NULL,&timer);//最初の周期割り込み設定

 while(1){
  // メインループ
  if(timer_irq_flag){
   timer_irq_flag = 0;
   add_repeating_timer_us(-250,&timer_callback,NULL,&timer);//再度の周期割り込み設定
  }
 }
}



(おしまい)