フォト
2025年6月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
無料ブログはココログ

« 次はSTM32ボードを積極的に使ていきたい(5) - NTSCビデオ出力 | トップページ | 久しぶりのPICマイコン、ちょっとハマった »

2017年2月19日 (日)

次はSTM32ボードを積極的に使ていきたい(6) - Lチカ

Arduino STM32環境 Blue PillボードでのLチカの3連発

基本に戻って、Lチカ(1秒間隔でLEDをチカチカ)のメモです。
3つの方法についてのメモです。

Dscn6448

回路図
01

  流れる電流は4.0mAくらいにしています。
   I = (3.3v - 2.0 v) / 330Ω × 1000 = 3.94 mA  (順方向電圧降下を2.0vとする)

   ※LEDを駆動する端子は訳アリでPA8にしています。

(1)delay()を使った方法

#define LED_PIN  PA8  // TIMER1 1CH用出力ピン

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
 digitalWrite(LED_PIN, HIGH);
 delay(1000);
 digitalWrite(LED_PIN, LOW);
 delay(1000);
}

LED_PINの出力をHIGH、LOWと変化させてLEDを点滅させています。
loop()で無限ループさせているので、他に処理が出来ません。

そこで、次にタイマー割り込みを使ってみます。


(2)タイマー割り込みを使った方法

#define LED_PIN  PA8  // TIMER1 1CH用出力ピン

uint8_t sw = LOW;

void handle_timer() {
  if (sw == LOW) {
    sw = HIGH;
  } else {
    sw = LOW;    
  } 
  digitalWrite(LED_PIN, sw);
}

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Timer1.pause();                   // タイマー停止
  Timer1.setPrescaleFactor(7200);   // システムクロック 72MHzを10kHzに分周
  Timer1.setOverflow(10000);        // 最大値を1秒に設定
 
  Timer1.attachInterrupt(           // 割り込みハンドラの登録
      TIMER_UPDATE_INTERRUPT,       // 呼び出し条件は、カウンターオーバーフロー更新時
      handle_timer                  // 呼び出す関数
    );  

  Timer1.setCount(0);               // カウンタを0に設定
  Timer1.refresh();                 // タイマ更新
  Timer1.resume();                  // タイマースタート
}

void loop() {

}

Timer1はあらかじめ用意されているTimerオブジェクト変数です。
Arduino STM32では標準でタイマー割り込み機能(API)が提供されています。
Blue PillボードではTimer1、Timer2、Timer3、Timer4の4つが利用出来ます。

1秒間隔で割り込み関数を呼び出すための設定として、
   分周設定    :   7200分の1
   最大値設定 :  10,000カウント
を行っています。

システムクロック72MHzを7200分の1に分周した10kHzをタイマーのクロックとして
設定しています。
10kHzは0.0001秒に1回、カウンターの値をカウントアップします。
そのカウント値が10,000に達した時に、UPDATEイベントが発生するように指定します。
0.0001秒× 10,000 = 1.0秒 ですね。

Timer1.attachiInterupt()で割り込み処理を行う関数を設定しています。
引数のTIMER_UPDATE_INTERRUPT は、カウンター値を0に戻す更新時に
呼び出す指定で、2つ目の引数に指定した関数を呼び出します。

呼び出されるhanle_timer()でLEDの制御を行っています。
attachiInterupt()では、TIMER_UPDATE_INTERRUPT他に別途、4つの比較値(レジスタ)
に一致した条件での割り込み関数を呼び出すことも出来ます。
ですので、1つのタイマーで複数の異なるカウント値で割り込み処理が可能です。

(3)PWM出力を使った方法

#define LED_PIN  PA8  // TIMER1 1CH用出力ピン

void setup() {
  pinMode(LED_PIN, PWM);            // LED_PINをPWMに設定
  Timer1.pause();                   // タイマー停止
  Timer1.setPrescaleFactor(7200);   // システムクロック 72MHzを10kHzに分周
  Timer1.setOverflow(10000*2);      // 周期を2秒に設定
  pwmWrite(LED_PIN, 10000);         // PWMパルス幅を1秒に設定

  Timer1.setCount(0);               // カウンタを0に設定
  Timer1.refresh();                 // タイマ更新
  Timer1.resume();                  // タイマースタート
}

void loop() {

}

PWMを使っってLEDを点滅させています。
PWMもタイマー制御機能の一部です。

前述(1)、(2)はCPUがLEDの点灯・消灯制御を行っていましたが、
この方法ではタイマーが勝手にLEDの制御を行ってくれます。
CPUの負荷は0%ですね。

制約が少々あります。
任意のI/Oピンを制御することは出来ません。
TimerにはPWM出力を行うピンが割り当てられています。
LED_PINに指定したPA8はTimer1で利用出来るI/Oピンです。
(正確にはTimer1のCH1に割り当てれれているI/Oピン)

PWM出力の設定として、周期とパスル幅の設定が必要ですが、
周期は
  Timer1.setPrescaleFactor(7200);
  Timer1.setOverflow(10000*2);

で2秒周期の設定を行っています。

パルス幅は
  pwmWrirte(LED_PIN, 10000);
で周期の半分の幅1秒を設定しています。

この設定で、2秒周期のうち1秒間はHIGH,残り1秒間はLOWとなり
LEDを点滅させることが出来ます。

Timer1は同時に4つのPWM出力が可能です。
ただし、周期は同じでパスル幅のみ別々に設定が可能です。

タイマーは他にTimer2、Timer3、Timer4が独立して利用出来ます。
BluePillボードにて各タイマーが制御できるI/Oピンについては、
下記のサイトが参考になります。
・stm32duono Blue Pill
  http://wiki.stm32duino.com/index.php?title=Blue_Pill
  (特にpinoutの情報)

  pinoutのPDFをダウンロードしてパウチして利用すると便利です。

  Dscn6449


2018/12/14 追記
タイマーに関するドキュメントを下記のリンク先にまとめました。
タイマークラスライブラリ HardwareTimer
https://scrapbox.io/ArduinoSTM32/HardwareTimer

libmaple API タイマーのサポート
https://scrapbox.io/ArduinoSTM32/Timer_support(timer.h)


« 次はSTM32ボードを積極的に使ていきたい(5) - NTSCビデオ出力 | トップページ | 久しぶりのPICマイコン、ちょっとハマった »

arduino」カテゴリの記事

ARM」カテゴリの記事

STM32」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: 次はSTM32ボードを積極的に使ていきたい(6) - Lチカ:

« 次はSTM32ボードを積極的に使ていきたい(5) - NTSCビデオ出力 | トップページ | 久しぶりのPICマイコン、ちょっとハマった »