「回路系技術資料/STM32TIMER」の編集履歴(バックアップ)一覧はこちら

回路系技術資料/STM32TIMER - (2011/12/10 (土) 15:34:26) の最新版との変更点

追加された行は緑色になります。

削除された行は赤色になります。

*STM32-TIMER **一定時間ごとの割込み タイマーを使って5秒毎にLEDを点滅させるスケッチです。 タイマーをスタートした瞬間に割り込みを入れたい場合 timer1.setCompare(TIMER_CH1, 1); タイマーをスタートして1回分の周期後に割り込みを入れたい場合 timer1.setCompare(TIMER_CH1, timer1.getOverflow()); タイマーをスタートして1回分の周期の半分後に割り込みを入れたい場合 timer1.setCompare(TIMER_CH1, timer1.getOverflow() * 0.5); 動作を変更させたい場合は上記の部分をコメントアウトして利用してください。 #define LED_RATE 5000000//5秒間隔 HardwareTimer timer1(1); void setup() { pinMode(BOARD_LED_PIN, OUTPUT);//青LEDのつながっているピンを出力モードに timer1.pause();//タイマーを停止 timer1.setPeriod(LED_RATE);//周期を5秒に設定 //タイマー1のチャンネル1をコンパレータモードに設定 timer1.setChannel1Mode(TIMER_OUTPUT_COMPARE); //タイマーをresumeした瞬間に1回目の割り込みが入る。 timer1.setCompare(TIMER_CH1, 1); //タイマーをresumeして5秒に1回目の割り込みが入る。 //timer1.setCompare(TIMER_CH1, timer1.getOverflow()); //タイマーをresumeして2.5秒に1回目の割り込みが入る。 //timer1.setCompare(TIMER_CH1, timer1.getOverflow() * 0.5); timer1.attachCompare1Interrupt(handler_led); timer1.refresh();//タイマーをクリア timer1.resume();//タイマーをスタート } void loop() { } void handler_led(void) {// toggleLED();//基板上の青LEDを点滅 } **エンコーダのカウント STM32のタイマーにはエンコーダをカウントするモードが存在します。 この機能を使わずに、割込み処理で行うことも可能ですが、こちらのほうが処理の負荷を少なくすることが可能です。mapleIDEの機能として実装されおらず、扱うのはかなり面倒なのでライブラリ化してみました。librariesに解凍したデータを入れておくと下記のスケッチで動作します。 例えばタイマー1を使う場合: EncoderModeTimer EncoderTimer1(1); ※ただし、タイマー1を使うプログラムは動作しなくなります。 例えばタイマー1と関連があるPWM出力など。http://www37.atwiki.jp/kisarazu_maicon/pages/116.html タイマーとエンコーダの入力ピンの関係 |TIMER1|PA(8),PA(9)|5Vトレラント| |TIMER2|PA(0),PA(1)|MAX4.0V| |TIMER3|PA(6),PA(7)|MAX4.0V| |TIMER4|PB(6),PB(7)|5Vトレラント| 5Vトレラントでないピンに5Vレベルのエンコーダをつなぐ時は抵抗やショットキーダイオードなどを使って、端子を保護する必要があるので注意してください。オープンドレイン出力のものや、プルアップ仕様のエンコーダであればそのまま使える場合もあります。なお、内蔵のダイオードに5mA以上の電流が流れると壊れます。 #ref(EncoderModeTimerVer0.01.rar) タイマーから値をそのまま読み出すバージョンです。 16ビット(0-65535)を超えるとオーバーフローします。 #ref(EncoderModeTimerVer0.02.rar) タイマーのオーバーフロー対策をしたバージョンです。 getCount関数をオーバーフローする周期より短い周期でアクセスすると オーバーフローしても整合がとれるように処理します。 符号付32ビットで値を返します。 #include "EncoderModeTimer.h" EncoderModeTimer EncoderTimer1(1);//タイマー1:エンコーダモード //EncoderModeTimer EncoderTimer2(2);//タイマー2:エンコーダモード //EncoderModeTimer EncoderTimer3(3);//タイマー3:エンコーダモード //EncoderModeTimer EncoderTimer4(4);//タイマー4:エンコーダモード void setup() { pinMode(PA(8), INPUT);//TIM1 CH1 pinMode(PA(9), INPUT);//TIM1 CH2 //pinMode(PA(0), INPUT);//TIM2 CH1 //pinMode(PA(1), INPUT);//TIM2 CH2 //pinMode(PA(6), INPUT);//TIM3 CH1 //pinMode(PA(7), INPUT);//TIM3 CH2 //pinMode(PB(6), INPUT);//TIM4 CH1 //pinMode(PB(7), INPUT);//TIM4 CH2 Serial3.begin(9600); } void loop() { Serial3.print("encoderPosition1="); Serial3.println(EncoderTimer1.getCount()); //Serial3.print("encoderPosition2="); //Serial3.println(EncoderTimer2.getCount()); //Serial3.print("encoderPosition3="); //Serial3.println(EncoderTimer3.getCount()); //Serial3.print("encoderPosition4="); //Serial3.println(EncoderTimer4.getCount()); delay(1000); } こちらはライブラリを使わない場合のサンプル。STM32VLD以外で試す場合はこちらをお勧めします。 #include <timer.h> #include <string.h> HardwareTimer timer1(1); void setup() { pinMode(PA(8), INPUT);//TIM1 CH1 pinMode(PA(9), INPUT);//TIM1 CH2 Serial3.begin(9600); delay(1000); *bb_perip(&((TIMER1->regs).gen->CR1), TIMER_CR1_CEN_BIT) = 0; memset( (TIMER1->regs).gen, 0, sizeof(timer_adv_reg_map) ); uint32 tmp; (TIMER1->regs).gen->ARR = 0xFFFF; tmp = (TIMER1->regs).gen->CCMR1; tmp &= ~TIMER_CCMR1_CC1S; tmp |= TIMER_CCMR1_CC1S_INPUT_TI1; tmp &= ~TIMER_CCMR1_CC2S; tmp |= TIMER_CCMR1_CC2S_INPUT_TI1; (TIMER1->regs).gen->CCMR1 = tmp; tmp = (TIMER1->regs).gen->SMCR; tmp &= ~TIMER_SMCR_SMS; tmp |= TIMER_SMCR_SMS_ENCODER3; (TIMER1->regs).gen->SMCR = tmp; *bb_perip(&((TIMER1->regs).gen->CCER), TIMER_CCER_CC1P_BIT) = 0; *bb_perip(&((TIMER1->regs).gen->CCER), TIMER_CCER_CC2P_BIT) = 0; *bb_perip(&((TIMER1->regs).gen->CR1), TIMER_CR1_CEN_BIT) = 1; } void loop() { Serial3.print("encoderPosition="); Serial3.println(timer1.getCount()); delay(1000); }
*STM32-TIMER **一定時間ごとの割込み タイマーを使って5秒毎にLEDを点滅させるスケッチです。 タイマーをスタートした瞬間に割り込みを入れたい場合 timer1.setCompare(TIMER_CH1, 1); タイマーをスタートして1回分の周期後に割り込みを入れたい場合 timer1.setCompare(TIMER_CH1, timer1.getOverflow()); タイマーをスタートして1回分の周期の半分後に割り込みを入れたい場合 timer1.setCompare(TIMER_CH1, timer1.getOverflow() * 0.5); 動作を変更させたい場合は上記の部分をコメントアウトして利用してください。 #define LED_RATE 5000000//5秒間隔 HardwareTimer timer1(1); void setup() { pinMode(BOARD_LED_PIN, OUTPUT);//青LEDのつながっているピンを出力モードに timer1.pause();//タイマーを停止 timer1.setPeriod(LED_RATE);//周期を5秒に設定 //タイマー1のチャンネル1をコンパレータモードに設定 timer1.setChannel1Mode(TIMER_OUTPUT_COMPARE); //タイマーをresumeした瞬間に1回目の割り込みが入る。 timer1.setCompare(TIMER_CH1, 1); //タイマーをresumeして5秒に1回目の割り込みが入る。 //timer1.setCompare(TIMER_CH1, timer1.getOverflow()); //タイマーをresumeして2.5秒に1回目の割り込みが入る。 //timer1.setCompare(TIMER_CH1, timer1.getOverflow() * 0.5); timer1.attachCompare1Interrupt(handler_led); timer1.refresh();//タイマーをクリア timer1.resume();//タイマーをスタート } void loop() { } void handler_led(void) {// toggleLED();//基板上の青LEDを点滅 } **エンコーダのカウント STM32のタイマーにはエンコーダをカウントするモードが存在します。 この機能を使わずに、割込み処理で行うことも可能ですが、こちらのほうが処理の負荷を少なくすることが可能です。mapleIDEの機能として実装されおらず、扱うのはかなり面倒なのでライブラリ化してみました。mapleIDEのlibrariesに解凍したデータをインストールすると利用できます。 #ref(EncoderModeTimerVer0.01.rar) タイマーから値をそのまま読み出すバージョンです。 16ビット(0-65535)を超えるとオーバーフローします。 #ref(EncoderModeTimerVer0.02.rar) タイマーのオーバーフロー対策をしたバージョンです。 getCount関数をオーバーフローする周期より短い周期でアクセスすると オーバーフローしても整合がとれるように処理します。 符号付32ビットで値を返します。 #ref(EncoderModeTimerVer0.03.rar) プリスケーラの設定に対応したバージョンです。 setPrescaleFactor関数とgetPrescaleFactor関数を追加しています。 **ライブラリの使い方 まず、対応するタイマーのピンとエンコーダを接続しておきます。 タイマーとエンコーダの入力ピンの関係 |TIMER1|PA(8),PA(9)|5Vトレラント| |TIMER2|PA(0),PA(1)|MAX4.0V| |TIMER3|PA(6),PA(7)|MAX4.0V| |TIMER4|PB(6),PB(7)|5Vトレラント| ※5Vトレラントでないピンに5Vレベルのエンコーダをつなぐ時は抵抗やショットキーダイオードなどを使って、端子を保護する必要があるので注意してください。オープンドレイン出力のものや、プルアップ仕様のエンコーダであればそのまま使える場合もあります。なお、内蔵のダイオードに5mA以上の電流が流れると壊れます。 **ライブラリの関数 -EncoderModeTimer EncoderTimer(タイマーの番号); タイマーをエンコーダモードで初期化します。 値の読み出し -int32 getCount関数 エンコーダの値の読み出します。Ver0.02以降は符号付きint32の範囲で、Ver0.01は符号なしint16の範囲で値が返ります。 ※ただし、タイマーを使うプログラムは動作しなくなります。 例えばタイマーと関連があるPWM出力など。http://www37.atwiki.jp/kisarazu_maicon/pages/116.html -void setPrescaleFactor(uint32 factor)関数 プリスケーラの値(1~65536)を設定します。 getCount関数で読み出される値は、このプリスケーラ値で割った値になります。 高速なエンコーダを使う場合や、キリの良い数にしたい場合に使うと良いと思います。 なお、標準では1がセット(プリスケーラ無効)されています。 -uint32 getPrescaleFactor()関数 プリスケーラに設定されている値を読み出します。 *サンプルプログラム #include "EncoderModeTimer.h" EncoderModeTimer EncoderTimer1(1);//タイマー1:エンコーダモード //EncoderModeTimer EncoderTimer2(2);//タイマー2:エンコーダモード //EncoderModeTimer EncoderTimer3(3);//タイマー3:エンコーダモード //EncoderModeTimer EncoderTimer4(4);//タイマー4:エンコーダモード void setup() { pinMode(PA(8), INPUT);//TIM1 CH1 pinMode(PA(9), INPUT);//TIM1 CH2 //pinMode(PA(0), INPUT);//TIM2 CH1 //pinMode(PA(1), INPUT);//TIM2 CH2 //pinMode(PA(6), INPUT);//TIM3 CH1 //pinMode(PA(7), INPUT);//TIM3 CH2 //pinMode(PB(6), INPUT);//TIM4 CH1 //pinMode(PB(7), INPUT);//TIM4 CH2 Serial3.begin(9600); } void loop() { Serial3.print("encoderPosition1="); Serial3.println(EncoderTimer1.getCount()); //Serial3.print("encoderPosition2="); //Serial3.println(EncoderTimer2.getCount()); //Serial3.print("encoderPosition3="); //Serial3.println(EncoderTimer3.getCount()); //Serial3.print("encoderPosition4="); //Serial3.println(EncoderTimer4.getCount()); delay(1000); } こちらはライブラリを使わない場合のサンプルです。STM32VLD以外で試す場合はこちらをお勧めします。 #include <timer.h> #include <string.h> HardwareTimer timer1(1); void setup() { pinMode(PA(8), INPUT);//TIM1 CH1 pinMode(PA(9), INPUT);//TIM1 CH2 Serial3.begin(9600); delay(1000); *bb_perip(&((TIMER1->regs).gen->CR1), TIMER_CR1_CEN_BIT) = 0; memset( (TIMER1->regs).gen, 0, sizeof(timer_adv_reg_map) ); uint32 tmp; (TIMER1->regs).gen->ARR = 0xFFFF; tmp = (TIMER1->regs).gen->CCMR1; tmp &= ~TIMER_CCMR1_CC1S; tmp |= TIMER_CCMR1_CC1S_INPUT_TI1; tmp &= ~TIMER_CCMR1_CC2S; tmp |= TIMER_CCMR1_CC2S_INPUT_TI1; (TIMER1->regs).gen->CCMR1 = tmp; tmp = (TIMER1->regs).gen->SMCR; tmp &= ~TIMER_SMCR_SMS; tmp |= TIMER_SMCR_SMS_ENCODER3; (TIMER1->regs).gen->SMCR = tmp; *bb_perip(&((TIMER1->regs).gen->CCER), TIMER_CCER_CC1P_BIT) = 0; *bb_perip(&((TIMER1->regs).gen->CCER), TIMER_CCER_CC2P_BIT) = 0; *bb_perip(&((TIMER1->regs).gen->CR1), TIMER_CR1_CEN_BIT) = 1; } void loop() { Serial3.print("encoderPosition="); Serial3.println(timer1.getCount()); delay(1000); }

表示オプション

横に並べて表示:
変化行の前後のみ表示: