ちょっと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);//再度の周期割り込み設定 } } } |
(おしまい)