GR-SAKURA
GR-KURUMI
GR-COTTON
GR-CITRUS
GR-PEACH
GR-KAEDE
GR-ADZUKI
GR-LYCHEE
GR-ROSE
GR-MANGO(*)
SNShield
Web Compiler
IDE for GR
TOPPERS関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
秋月で買えるデジタルシリコンマイクロホン SPM0405HD4H( http://akizukidenshi.com/catalog/g/gM-05577/ , 1MHzクロック駆動を想定)ですが、外部クロックでカウントできるタイマーを使う必要がある思ってます。
これに使えるタイマー(16bit)の空きは、ありますでしょうか?
スケッチリファレンスには載ってないみたいですが outputClock() が使えるのでは
定義は、どのヘッダファイルにありますでしょうか?
gr_common/include/RLduino78.h には関数プロトタイプがあるだけなので見ても分からんと思います。
情報有難うございます。でも、クロック信号の生成が欲しいのでなく、外部クロック信号入力で内部タイマーをカウントさせたいので、この関数そのものは使えない感じですが、タイマアレイの使い方の参考になりそうです。外部クロックを有効にする必要がありそうです。なんか、だいぶんめんどくさいかも。
RL78/G13 ユーザーズマニュアル ハードウェア編のページ325の「(3)外部イベント・カウンタ」の設定を調べて、TI01とTO01とか共用になってるD3端子を使うのが良いかな。
横からすみません。データシートちら見しましたが、PWMじゃなくてPDMなので、カウンタを回す構成は不要なのでは、と思いました。
SPI等を使って8bit単位でカウントするような方法もあるようです(detail.chiebukuro.yahoo.co.jp/.../q13136651523)
ご存知かもですが、PDMの図解(kanaimaru.com/.../d170.htm)
間違ってたらスミマセン。安いし買ってみようかなこのマイク。
他の処理もさせたいので、タイマーでカウントさせて、もっと遅い周期で値を取りたいというわけです。SPIを使うという案は、別のサイトのコミュニティでも出てました。
この人の記事あたり https://plus.google.com/107853337949809503038/posts/eg8dERQJqww
自己レスです。
_startTimerChannel関数の引数u16TimerModeでタイマ・モード・レジスタの値を渡すようになってるようです。
static void _startTimerChannel(uint8_t u8TimerChannel, uint16_t u16TimerMode, uint16_t u16Interval, bool bPWM, bool bInterrupt);
タイマーユニット0のチャネル1をイベント・カウンタ・モードで使う場合は、下記かな。
u8TimerChannel = 1; タイマーユニット0のチャネル1を指定。
u16Interval = 0xfffe; TDR01へセットする値は最大値にしとくので良いかな?
bPWM = false;
bInterrupt = false;
u16TimerMode = 0x1106; TMR01へセットする値。
タイマーユニット0のチャネル1を対象にすると、TMR01の値は、2進数で「00 01 0 001 00 00 011 0」(0x1106)こうかな? 内訳は下記。
CKS011-CKS010 = 0 0 Don't Care? 外部端子からのクロック供給なので
CCS01 = 1 TI01端子からの入力信号の有効エッジ
SPLIT01 = 0 16bitカウンタ
STS011-STS011 = 0 0 1 TImn端子入力の有効エッジを,スタート・トリガ,キャプチャ・トリガの両方に使用
CIS011-CIS010 = 0 0 立下りエッジ(今回、どっちでも良い)
bit5-bit4 = 0 0 常時00
MD013-MD011 = 0 1 1 イベント・カウンタ・モード
MD010 = 0 割込なし
あと、「_pinMode(u8Pin, INPUT);」に修正しておけば、OKかな? あと、追加設定が必要かどうか、再度、「RL78/G13ユーザーズマニュアル ハードウェア編」を見てみるか。
TCR01を読み出した後、当該カウンタだけ、値をゼロに戻したい場合、どうするんだろうか? 「タイマ・チャネル開始レジスタm(TSm)」のTS0に、0x02を書き込めば良いのだろうか?
まずは、outputClockをパクッてこんな感じかしら?
void inputClock(bool start ) // Timer 0 Channel 1; を前提 注)これから動作検証です// ライブラリ側の_startTAU0とstartTimerChannelのstatic前言を外さないとコンパイルできないか、、、 { FUNC_MUTEX_LOCK; pinMode( 3, INPUT ); if (start) { // タイマーアレイユニットの開始 _startTAU0(TIMER_CLOCK); // タイマーの開始 _startTimerChannel( 1, 0x1106, 0xfffe, false, false); } else { // タイマーの停止 _stopTimerChannel( 1 ); // タイマーアレイユニットの停止 _stopTAU0(); } FUNC_MUTEX_UNLOCK; }unsigned short readTimer() // シリコンマイクのクロックが、GR-KURUMIとずれると、零レベルの調整どうするか悩ましい。// シリコンマイクのクロックもカウントしないとうまくないか。手抜きたい。平均値を計算で出しといて、差っ引くかな。// ちゃんとやるには、タイマーが2つ必要か// レベルメータだったら、楽できるか。継続的に最大値と最小値を求めて、その範囲で考えれば良いのか。{ // TCR01から値を読み取る unsigned short ret = TCR01.tcr01; // TS0に、0x0002を書き込 ←これで良いのかどうか? TS0.ts0 = 0x0002; return ret;}
なんとなく、シリコンマイク用のライブラリ要望って感じもしてきました(;^ω^)
GR-KURUMI で各タイマはこんな感じで割り当ててるので、暗黙的に使われてる 05 と 00 以外はその用途に使わなければ自由に使えそうな感じですね。
チャネル3で、シリコンマイクへ供給するクロックを出力して、チャネル1で、シリコンマイクからのデータをカウントするような感じが、良いですかね。
RL78/G13 の タイマ・アレイ・ユニットの「入力信号のハイ/ロウ・レベル幅測定」機能を使用するとして、タイマ入力端子(TImn) のピンが GR-KURUMI の外部に出てるのが
だけのようなので、これを使用するとするとカウントはチャネル 03 か 01 ということになりますね。
情報有難うございます。
シリコンマイクのクロックは、三端子水晶発振器DLO555MB(1MHz)を使って、さっそく、先に掲載したプログラム(D3でデータ受信)を試してみました。結果、ちゃんと動くようです。1msecごとに、カウンタ値を読み出して、1秒間で、その値の最大値と最小値を求めて、その差を、シリアルで取って表示させています。「あーーー」というと、まあ、値が増えて反応してます。
結論としては、
Q「デジタルシリコンマイクロホンSPM0405HD4Hをデジタルで使えるか否か?」
A「デジタル接続で使える」
ということで、このトピは終わります。有難うございました。
ご参考
追伸、ライブラリに修正が必要なので、シリコンマイク用のライブラリ要望です。ご検討、お願い致します。それしても、マニュアルを読むのが、老眼進んできつい、また、眼精疲労が、、、、
3端子水晶発振器の代わりに、D10から、outputClockで、1MHz出力させて、シリコンマイクに供給して、同じように動作することも、確認しています。
カウンタとして、D4のカウンタを使うと、マイクロ秒のタイマ関数が、正常に動かなくなるのかな?
あと、GR-KURUMIでは、PIORレジスタには、どんな値がセットされてるんでしょう。D3とD4以外も、使える?
今、D5のチャネル2でも動作することを確認しました。
あと、理解が足りてないのか、TCR01レジスタの値は、減算値になるのでしょうか?
_startTimerChannel( 1, 0x1106, 0xfffe, false, false);で渡している0xfffeから、TCR01の値を引くと、それらしい値が求まるので、何の値が取れてるのか、少々、混乱してます。
自己レスですが、RL78/G13ユーザーズマニュアル ハードウェア編のページ335の表6-3に「イベント・カウンタ・モード、ダウン・カウント」と書いてありました。
参考に、時点のサンプルプログラムのソースコードを、以下に置いときます。マイクのデータ線は、D3で、マイクのクロック線は、D10にしています。また、D9にLEDを繋ぐと、音検知で、LEDが光るようになります。なお、下記で使う関数のstatic 宣言を外すように、gr_common/RLduino78/cores/RLduino78_basic.cppの修正が必要です。
誰か、さらに進めて、サンプリング周波数はもう少し上げて、PWMへ変換するとかしませんか?
/*GR-KURUMI Sketch Template Version: V1.12*/ #include <Arduino.h> #include <stdlib.h> #include "RLduino78_mcu_depend.h" #include "RLduino78_timer.h" #include "pintable.h" #include "fastio.h" #ifdef USE_RTOS #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #endif #ifdef USE_RTOS #define FUNC_MUTEX_LOCK xSemaphoreTake(xFuncMutex, portMAX_DELAY) //!< 関数用MUTEX LOCKマクロ #define FUNC_MUTEX_UNLOCK xSemaphoreGive(xFuncMutex) //!< 関数用MUTEX UNLOCKマクロ #else #define FUNC_MUTEX_LOCK //!< 関数用MUTEX LOCKマクロ #define FUNC_MUTEX_UNLOCK //!< 関数用MUTEX UNLOCKマクロ #endif // ライブラリ側で公開するように修正が必要 void _startTAU0(uint16_t u16TimerClock); void _stopTAU0(); void _startTimerChannel(uint8_t u8TimerChannel, uint16_t u16TimerMode, uint16_t u16Interval, bool bPWM, bool bInterrupt); void _stopTimerChannel(uint8_t u8TimerChannel); void outputClock( uint8_t, uint32_t ); // Pin 22,23,24 are assigned to RGB LEDs. int led_red = 22; // LOW active int led_green = 23; // LOW active int led_blue = 24; // LOW active void inputClock(bool start); unsigned short readTimer(); unsigned short min = 0xffff; unsigned short max = 0x0000; #define TIMER_INITIAL_VALUE (0xfffe) void inputClock(bool start ) // Timer 0 Channel 1; を前提 { FUNC_MUTEX_LOCK; min = 0xffff; max = 0x0000; pinMode( 3, INPUT ); // Channel 1 // pinMode( 5, INPUT ); // Channel 2 if (start) { // タイマーアレイユニットの開始 _startTAU0(TIMER_CLOCK); // タイマーの開始 _startTimerChannel( 1, 0x1106, TIMER_INITIAL_VALUE, false, false); // Channel 1 // _startTimerChannel( 2, 0x1106, 0xfffe, false, false); // Channel 2 } else { // タイマーの停止 _stopTimerChannel( 1 ); // Channel 1 // _stopTimerChannel( 2 ); // Channel 2 // タイマーアレイユニットの停止 _stopTAU0(); } FUNC_MUTEX_UNLOCK; } unsigned short readTimer() { // TCR01から値を読み取る unsigned short ret = TIMER_INITIAL_VALUE - TCR01.tcr01; // Channel 1 // unsigned short ret = TIMER_INITIAL_VALUE - TCR02.tcr02; // Channel 2 if (ret > max) max = ret; if (ret < min) min = ret; // rest the timer TS0.ts0 = 0x0002; // Channel 1 // TS0.ts0 = 0x0004; // Channel 2 return ret; } void MyCycle(unsigned long ms) { unsigned short val = readTimer(); } // the setup routine runs once when you press reset: void setup() { // initialize the digital pin as an output. Serial.begin(115200); Serial.println("Hello"); pinMode(led_red, OUTPUT); pinMode(led_green, OUTPUT); pinMode(led_blue, OUTPUT); pinMode( 9, OUTPUT); // turn the LEDs on, glow white. digitalWrite(led_red, LOW); digitalWrite(led_green, LOW); digitalWrite(led_blue, LOW); digitalWrite( 9, HIGH ); outputClock( 10, 1000000 ); // 1MHz clock for the mic attachIntervalTimerHandler( MyCycle ); inputClock( true ); // Timer 0 Channel 1; を前提 } int cnt = 0; // the loop routine runs over and over again forever: void loop() { unsigned short diff = max - min; if (diff > 10) digitalWrite( 9, LOW ); else digitalWrite( 9, HIGH ); if (((cnt++) % 1000 ) == 0) { Serial.println( diff ); min = 0xffff; max = 0x0000; } }
以上
ソースコードですが、修正済みのライブラリと込みで、guthubにアップしました。
github.com/.../MEMS-MIC4GR-KURUMI