「回路系技術資料/STM32TIMER」の編集履歴(バックアップ)一覧はこちら
回路系技術資料/STM32TIMER - (2011/12/10 (土) 15:39:53) の1つ前との変更点
追加された行は緑色になります。
削除された行は赤色になります。
*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ビットで値を返します。
ライブラリの使い方
宣言の仕方
EncoderModeTimer EncoderTimer(タイマーの番号);
タイマーをエンコーダモードで初期化します。
対応するタイマーは1,2,3,4です。
値の読み出し
getCount関数
エンコーダの値の読み出します。
#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の機能として実装されおらず、扱うのはかなり面倒なのでライブラリ化してみました。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ビットで値を返します。
**ライブラリの使い方
-EncoderModeTimer EncoderTimer(タイマーの番号);
タイマーをエンコーダモードで初期化します。
対応するタイマーは1,2,3,4です。
値の読み出し
-getCount関数
エンコーダの値の読み出します。
#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);
}