フォト
2018年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
無料ブログはココログ

« アナログ入力を使った16ボタン入力 | トップページ | 豊四季Tiny BASIC for micro:bit をV0.06に更新しました »

2018年1月25日 (木)

micro:bitをArduino環境で使う (6) PPIを使った単音出力

PPI(Programmable Peripheral Interconnect)を使って圧電スピーカーにて
単音出力を実装しました。

01

スケッチ

//
// micro:bit PPIを使ったTone by たま吉さん
//

#include "nrf.h"
#define TIMERFREQ 1000000L    // タイマー基本周期
#define TONE_TIMER NRF_TIMER0 // 利用タイマー資源

//
// 音の停止
// 引数
//
void dev_notone() {
    TONE_TIMER->TASKS_STOP = 1;  // タイマストップ
}

//
// 音出し
// 引数
//  pin     : PWM出力ピン 
//  freq    : 出力周波数 (Hz) 15~ 50000
//  duration: 出力時間(msec)
//
void dev_tone(uint8_t pin, uint16_t freq, uint16_t duration) {
  uint32_t ulPin;
  uint32_t f =TIMERFREQ/freq;
  
  // GPIOTEの設定:LEDピン・トグルタスクを定義する
  ulPin = g_ADigitalPinMap[pin];   // TonePinの実ピン番号の取得 
  NRF_GPIOTE->CONFIG[0] =          // チャネル0に機能設定
    (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |            // タスクモード
    (ulPin << GPIOTE_CONFIG_PSEL_Pos) |                              // ピン番号設定
    (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |  // 動作指定:トグル
    (GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos);        // ピン出力初期値
  NRF_GPIOTE->POWER = 1;                                             // GPIOTE有効
    
  //タイマ設定
  TONE_TIMER->TASKS_STOP = 1;                          // タイマストップ
  TONE_TIMER->TASKS_CLEAR = 1;                         // カウンタクリア
  TONE_TIMER->MODE = TIMER_MODE_MODE_Timer;            // モード設定:タイマモード
  TONE_TIMER->PRESCALER   = 4;                         // プリスケーラ設定:16分周(1MHz)
  TONE_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;   // カウンタ長設定:16ビット長指定
  TONE_TIMER->CC[0] = f/2;                             // コンパレータ0の設定(出力周波数設定)

  TONE_TIMER->SHORTS =                                 // ショートカット設定:クリアタスク指定
      (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);

  // PPIの設定(チャネル0を利用)
  //   TIMER0 コンパレータ0一致イベント と GPIOTE(ch0)LEDピン・トグルタスク を結び付ける
  NRF_PPI->CH[0].TEP  = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];       // PPI.ch0 にLEDピン・トグルタスク設定
  NRF_PPI->CH[0].EEP  = (uint32_t)&TONE_TIMER->EVENTS_COMPARE[0];  // PPI ch0 にコンパレータ0一致イベント設定  
  NRF_PPI->CHENSET   |= PPI_CHENSET_CH0_Enabled;                   // PPI ch0 有効

  TONE_TIMER->TASKS_START = 1;   // タイマスタート

  if (duration) {
    delay(duration);
    TONE_TIMER->TASKS_STOP = 1;  // タイマストップ
  }
}

void setup() {
  uint32_t ulPin;
  uint16_t freq = 440;  // 出力周波数 (Hz)

  uint32_t f =TIMERFREQ/freq;
  Serial.begin(115200); 
  Serial.println("microbit is ready!");

  dev_tone(12,523,1000); // ド
  dev_tone(12,587,1000); // レ
  dev_tone(12,659,1000); // ミ
  dev_tone(12,698,1000); // ファ   
  dev_tone(12,784,1000); // ソ  
  dev_tone(12,880,1000); // ラ  
  dev_tone(12,988,1000); // シ  
  dev_tone(12,1047,1000);// ド   
}

void loop(){
    __SEV();
    __WFE();
    __WFE();
}

dev_tone()関数にて単音出力が出来ます。
CPUを使わずにタイマー、GPIOE、PPIだけで音を出しています。

音階に対応する周波数は下記の通りです。

02

これも豊四季Tiny BASIC for micro:bitに組み込む予定です。

« アナログ入力を使った16ボタン入力 | トップページ | 豊四季Tiny BASIC for micro:bit をV0.06に更新しました »

arduino」カテゴリの記事

ARM」カテゴリの記事

micro:bit」カテゴリの記事

コメント

コメントを書く

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

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/571408/66319549

この記事へのトラックバック一覧です: micro:bitをArduino環境で使う (6) PPIを使った単音出力:

« アナログ入力を使った16ボタン入力 | トップページ | 豊四季Tiny BASIC for micro:bit をV0.06に更新しました »