デジタルフィルタなんてMatlabでもやったことがないし(あ?やったかな?覚えてない(^q^;)手探り状態ですが、PSoCのFilterコンポーネントはz変換とか行列すらも出てこないので見た目通りに試してみた。
前回やったExampleでは外部入力された波形をFilterで加工しているが、リズムマシンはCPUで波形を作っているのでCPUからFilterを通さないといけいない。
サンプリング間隔ごとに逐次波形を計算しているのでDMAは不要だ。(←とおもう)
PSoC Creatorのプロジェクト
https://github.com/ryood/PSoC_5LP_DigitalFilter_Test
TopDesign
CPUで波形を生成して、「Filter」コンポーネントを通して「VDAC8_1」と「Opamp_1」のボルテージフォロワを通して出力する。
「VDAC8_2」と「Opamp_2」はフィルターを通す前の波形の出力用。
「Timer」はサンプリング周波数で割り込みをかけるものだ。
「Pin_Timer_TC」はタイマーがオーバーフローした時(サンプリング間隔で)にパルスを発生、「Pin_ISR_Check」は割り込みルーチン内のタイミング計測用だ。
FilterのConfigureダイアログ
前回やったExampleからFilter TypeをHigh Passに、Cutoffを8kHzに変更した。
ソースコード
#include <device.h>
#include <VDAC8.h>
#include <stdlib.h>
volatile uint8 cnt = 0;
CY_ISR(Timer_interrupt_handler)
{
uint16 v, fv;
/* Read Status register in order to clear the sticky Terminal Count (TC) bit
* in the status register. Note that the function is not called, but rather
* the status is read directly.
*/
Timer_STATUS;
cnt++;
v = rand() % UINT16_MAX;
// Filterをかける前の波形を出力
VDAC8_2_SetValue(v >> 8);
Pin_ISR_Check_Write(1u);
Filter_Write16(Filter_CHANNEL_A, v);
/* Poll waiting for the holding register to have data to read */
while (Filter_IsInterruptChannelA() == 0) ;
fv = Filter_Read16(Filter_CHANNEL_A);
Pin_ISR_Check_Write(0u);
VDAC8_1_SetValue(fv >> 8);
}
int main()
{
/* Start all components used on schematic */
VDAC8_1_Start();
VDAC8_2_Start();
Opamp_1_Start();
Opamp_2_Start();
Filter_Start();
Timer_Start();
ISR_Timer_StartEx(Timer_interrupt_handler);
/* Enable the interrupt register bit to poll
Value 1 for Channel A, Value 2 for Channel B */
Filter_INT_CTRL_REG |= (1 << Filter_CHANNEL_A);
CyGlobalIntEnable;
for(;;)
{
//CyDelay(10);
}
} /* End of main */
FilterをCPUから直接アクセスするにはFilter_Write**()とFilter_Read**()というAPIを使えば済むようだ。 ※**は引数のデータ型
rand()関数でWhite Noiseを作ってHPFを通してみた。
出力波形
PCのWavegeneでFFTしてみた。Filterに入れる前
Filterを通した後
実行時間
Filterの演算が終わるまでCPUがWaitしているのでどれぐらい時間がかかっているか見てみた。
ch1:Pin_ISR_Check ch2:Pin_Timer_TC
Master_Clockを74.7MHzに設定。サンプリング周波数48kHz。
PWはデューティーの+側の時間で2.800us。周波数にすると357kHzぐらいだ。
メモ:
- Filterの設定の「Filter gain:」を「1」にするとほとんどFilterが効かなくなる模様
- PSoC 5LP Prototyping Kitで使われているCY8C5888LTI-LP097は最大クロックが80MHzだが内蔵クロックを使うとうまく設定できない。(クロックの誤差で80MHzを超えるため)
- PSoC 5LPはPSoC4にくらべるとかなり強力。Cortex M0とCortexM3の差+UDBいっぱい+DFB+メモリもいっぱい(^q^/
0 件のコメント:
コメントを投稿