正弦波発生器の作成 - KKI WWW Page

第9回 信号処理演習
正弦波発生器の作成
教官:小澤 助教授
渡邉(非常勤講師)
2006/12/21
本日の予定
CCS のトラブルシューティング
正弦波発生器の作成
sin 関数による正弦波の生成
IIR フィルタによる正弦波の生成
CCS による正弦波のグラフ表示とプロファイリング
(パフォーマンスの測定)
2
CCS のトラブルシューティング
正しく動作していたプログラムが動かなくなったとき
以下のようなエラーが表示されたとき
3
CCS のトラブルシューティング
1)
CCS を終了させる
2)
リセットボタンを押す
→ LED が瞬けば OK
3)
瞬かない場合は Reset C6x11 DSK
を実行してみる
4)
それでもダメな場合はボードの電源
を入れ直してみる
リセットボタン
4
正弦波発生器の作成
もっとも基本的な波である正弦波を生成してみる
周波数 440Hz (ハ長調のラ)
サンプリング周波数 8000Hz
生成方法
C 言語標準ライブラリの sin 関数による正弦波の生成
IIR フィルタによる正弦波の生成
5
プロジェクト sin_c
C 言語標準ライブラリの sin 関数を使って正弦波を生成
Cソースファイル
sin_c.c (今から作成)
C6711 用ライブラリファイル
C:¥ti¥c6000¥cgtools¥lib¥rts6200.lib
リンカコマンドファイル
link.cmd (先週のファイルをコピーすればよい)
6
C ソースファイル sin_c.c
#include <math.h>
#define BUFF_SIZE
#define PI
96
3.141592653
float sinbuff[BUFF_SIZE];
void main(void)
{
int i;
float radius = 0.0;
for (i=0; i < BUFF_SIZE; i++) {
sinbuff[i] = sinf(radius);
radius += 2 * PI * 440 / 8000.0;
}
}
7
動作確認
プロジェクトを保存する
コンパイル&ロード&実行する
動作確認には以下の機能を利用:
Watch ウィンドウ
メモリイメージのグラフィック表示
Single Time (時間領域)
FFT Magnitude (周波数領域)
8
Watch ウィンドウ
プログラムの実行後,変数名を選択して右クリック
値の確認後は Watch Window を閉じること(右クリックして Close)
変数の値をリアルタイムで表示するため,CCS の動作が非常に遅くなる
9
メモリイメージのグラフィック表示
時間領域
[View]→[Graph]→[Time/Frequency]
440Hz の波形である
ことを確認せよ!
10
メモリイメージのグラフィック表示
周波数領域
グラフを右クリック→[Properties]
440Hz 付近にピークが
あることを確認せよ!
11
プロジェクト sin_iir
サンプリング周波数 8000Hz
入力信号を 1/8000 秒の間に加工して出力
高速な処理が要求される
IIR フィルタにより sin 波を生成する
Cソースファイル
sin_iir.c (今から作成)
C6711 用ライブラリファイル
C:¥ti¥c6000¥cgtools¥lib¥rts6200.lib
リンカコマンドファイル
link.cmd (先週のファイルをコピーすればよい)
12
正弦波発生用 IIR フィルタの導出
(教科書コラム8.A, p.149)
IIR フィルタ(無限インパルス応答フィルタ)
⎧1 n = 0
x[n] = δ [n] = ⎨
⎩0 n ≠ 0
y[n] = 2 cos(2πfT ) y[n − 1] − y[n − 2] + sin( 2πfT ) x[n − 1]
a1
単位インパルス
b
a2
x[n]
Z-1
遅延回路
乗算器
加算器
a1
b
y[n]
正弦波
Z-1
a2
13
正弦波発生用 IIR フィルタの導出
(教科書コラム8.A, p.149)
y[0] = 2 cos(2πfT ) y[−1] − y[−2] + sin(2πfT ) x[−1]
=0
y[1] = 2 cos(2πfT ) y[0] − y[−1] + sin( 2πfT ) x[0]
= sin( 2πfT )
y[2] = 2 cos(2πfT ) y[1] − y[0] + sin(2πfT ) x[1]
= 2 cos(2πfT ) sin(2πfT )
= sin( 2πf ⋅ 2T )
y[3] = 2 cos(2πfT ) y[2] − y[1] + sin( 2πfT ) x[2]
= 2 cos(2πfT ) sin(2πf ⋅ 2T ) − sin(2πfT )
= sin( 2πf ⋅ 3T )
M
周期Tで離散化
y[n] = sin( 2πf ⋅ nT )
した正弦波
14
正弦波発生用 IIR フィルタの導出
(教科書コラム8.A, p.149)
IIR フィルタ(無限インパルス応答フィルタ)
⎧1 n = 0
δ [n] = x[n] = ⎨
⎩0 n ≠ 0
y[n] = 2 cos(2πfT ) y[n − 1] − y[n − 2] + sin( 2πfT ) x[n − 1]
a1
a2
b
a1 = 2 cos ω0T = 2 cos(2π * 440 / 8000) = 1.8817615
a 2 = −1
b = sin ω0T = sin( 2π * 440 / 8000) = 0.33873792
y[0] = 0
y[1] = b = 0.33873792
y[2] = a1* y[1] + a 2 * y[0]
←sin_iir() 内で計算するので,初期値は 0 でよい15
C ソースファイル sin_iir.c
#include <math.h>
#define BUFF_SIZE
float
float
float
float
96
sinbuff[BUFF_SIZE];
y[3] = {0.0, 0.33873792, 0.0};
a1
= 1.8817615;
a2
= -1.0;
float sin_iir(void)
{
y[0] = a1 * y[1] + a2 * y[2];
y[2] = y[1];
y[1] = y[0];
return y[0];
}
// Get y(n)
// delay
// delay
void main(void)
{
int i;
for (i=0; i < BUFF_SIZE; i++)
sinbuff[i] = sin_iir();
}
16
動作確認
プロジェクトを保存する
コンパイル&ロード&実行する
生成した波の振幅スペクトルを表示し,
440Hz の波であることを確認せよ
17
演習課題1
IIR フィルタにより,
グループ番号*50Hz の正弦波を生成せよ
生成した波の振幅スペクトルを表示し,
グループ番号*50Hz の波であることを確認せよ
注意:係数を求めるとき,sin, cosの計算ではradianを使用する
18
実行時間の計測
C 言語標準ライブラリの sin 関数と
IIR フィルタ版の sin 関数の実行時間を比較
CCS のプロファイル機能を利用して
プログラムのパフォーマンスを測定可能
19
実行時間の計測手順
(1)
(2)
(3)
簡単のためにバッファサイズを 1 に変更
コンパイル&ロード
[Profiler] → [Start New Session…]
セッション名は MySession で OK
(4)
(5)
(6)
(7)
標準ライブラリ版(IIR フィルタ版)の sin 関数を右クリックして [Profile
Function] → [in MySession Session]
プロファイルウィンドウの [Functions] タブをクリック
プログラムを実行
プロファイルウィンドウ内の Incl. Average が関数を実行するのに必要な
CPU Cycle 数を表す
20
演習課題2
標準ライブラリ版の sin 関数と IIR フィルタ版
の sin 関数の実行時間を比較せよ
21
レポート課題:
プログラムができるまで
ソースファイル
foo.c
bar.c
boo.c
foo.o
bar.o
boo.o
コンパイラ
オブジェクトファイル
リンカ
実行形式
a.out
近年はコンパイラが
リンカの機能を含む
22
レポート課題
オブジェクトファイルとは何か?
リンカとは何か?
23