PSoC/AN2247
概要
実験環境
開発環境
パッケージ内容
- CY8C27443-24PI用
- COMポート通信 ボーレート 115200
- SysClock 24MHz
- VC1 SysClock/2 = 12MHz
- VC2 VC1/6 = 12MHz/6 = 2MHz
- VC3 SysClock/26 = 923.0769kHz
UARTクロック用。115200bps×8bit = 921.6kHz
接続
Pin | Port | 概要 |
2 | P0[5] | アナログ出力->Pin26(P0[4])に接続 |
3 | P0[3] | アナロググランドDCレベル出力(2.5V付近) |
4 | P0[1] | アナログ入力(DTMF信号入力)1Vp-p以上 |
10 | P1[7] | UART出力 |
14 | VSS | GND |
28 | VDD | +5V入力 |
AN2247のFigure7.DTMF Schematic 回路図には、UARTの接続例が書かれているが、おかしい。PCからのシリアル出力がPSoCに入力されているが、PSoCの出力をPCに入力するのが妥当だろう。なぜPCからの出力をPSoCが受信しなければならないのか分からない。それに、PSoC内部では、UART受信モジュールが導入されていない。検出結果を出力するモジュールとして、Transmitterが導入されている。したがって、この回路図はおかしい。
トラブル
boot.tblをアップデートしてしまうと動作しなくなる。
調べたところ、割り込みがきていない事が分かった。boot.tblをアップデートしない状態であれば動作していた。
割り込みが発生していない。
dtmf_low_cpu.lst を確認したところ、割り込み関数として登録されていない様だ。
(0136) org 24h ;PSoC Block DBB01 Interrupt Vector
0024: 7D 05 85 LJMP 0x0585 (0137) ljmp _LP_Timer_ISR
0027: 7E RETI (0138) reti
_LP_Timer_ISRの割り込みベクターテーブルだ。0x0585にジャンプせよ!と書かれている。0x0585を調べたところ、何も定義されていないダミー関数にとび、retiで戻っている。どうも、関数名がよくないようだ。そこで以下のように変更したところ、うまく行った。
- 変更内容 lp_timer_isr.c (タイマー割り込み関数の定義変更)
変更前
1
2
3
|
| #pragma interrupt_handler lp_timer_isr
#pragma interrupt_handler hp_timer_isr
#pragma interrupt_handler timer_isr
|
変更後
1
2
3
|
| #pragma interrupt_handler LP_Timer_ISR
#pragma interrupt_handler HP_Timer_ISR
#pragma interrupt_handler Timer_ISR
|
- 変更内容 lp_timer_isr.c (タイマー割り込み関数名を変更)
- lp_timer_isr関数名
変更前
変更後
- hp_timer_isr関数名
変更前
変更後
- timer_isr関数名
変更前
変更後
}}
DeviceEditorでBuildを行うとワーニングが表示される。
Level 5 Warning - Configuration dtmf_low_cpu,
User Module HP_BPF_CLK: InterruptType value has not been initialized.
Level 5 Warning - Configuration dtmf_low_cpu,
User Module LP_BPF_CLK: InterruptType value has not been initialized.
Level 5 Warning - Configuration dtmf_low_cpu,
User Module Transmitter: TX Interrupt Mode value has not been initialized.
Level 5 Warning - Configuration dtmf_low_cpu,
User Module Transmitter: Data Clock Out value has not been initialized.
これは、初期値が定義されていないから出る模様。結果的にはほっといても動作する。
data_const.h
1
2
|
| #define FQ_697_MAX 44500
#define FQ_697_MIN 41200
|
- 数値の決め方
define数値=(1/f[Hz]*15[周期]×カウンタのサンプリング周波数)
define数値=(1/697Hz*15[周期]×2MHz)=43041.606... となる。
- 697Hzに対してこのように設定されている。
2MHzクロックカウンタでカウントアップし、1ショットパルス幅で算出していることから
697Hzの1周期T=1434.72us
15周期15T=21.52ms
2MHzでカウントアップすると、21.52ms×2MHz = 43041.606... となる。
- 5%の誤差を許容する場合には、
define数値=(1/697Hz*1.05*15[周期]×2MHz)=45193.68 となる。
- 4%の誤差を許容する場合には、
define数値=(1/697Hz*1.04*15[周期]×2MHz)=44763.27 となる。
- 3%の誤差を許容する場合には、
define数値=(1/697Hz*1.03*15[周期]×2MHz)=44332.85 となる。
誤差
- CY8C29466 内部クロック誤差 24MHz±2.5% => 23.4MHz~24.6MHz
CY8C29466用にCloneをつくってみた。
CY8C27443の時には、結構いいかんじでDTMF解析が出来ていたが、CY8C29466にしたら検出精度が落ちた。検出できないことも多くなった。なにが原因??
各モジュールの動き
デジタルブロックは以下の通り。
- DBB00, DBB01 (LP_Timer) 16-bit timer
二つのSinカーブの周期を算出するためのもの。低周波数用。
- DBB10, DBB11 (HP_Timer) 16-bit timer
二つのSinカーブの周期を算出するためのもの。高周波数用。
- DBB02 (LP_BPF_CLK) and DBB12 (HP_BPF_CLK)
バンドパスフィルタ用のクロック生成用。
- DCB03 (Timer)
DTMF信号時間とPause時間測定用
- DCB13 (Transmitter)
検出したDTMFシンボルをPCに返す
アナログブロックは以下の通り。
- ACB00 (LP_IN_AMP) and ACB02 (HP_IN_AMP)
BPF入力アンプとroute入力
- ASC10, ASD11 (LPB_1)
1stバンドパスフィルタ(低周波数用)
- ASD11, ASC21 (LPB_2)
2ndバンドパスフィルタ(低周波数用)
- ASC12, ASD22 (HPB_1)
1stバンドパスフィルタ(高周波数用)
- ASD13, ASC23 (HPB_2)
2ndバンドパスフィルタ(高周波数用)
- ACB01 (LP_SCH_TRIG), ACB03 (HP_SCH_TRIG)
Sin波を矩形波に変換するシュミットトリガー。キャプチャーパルス生成としても利用。
- LP_SCH_TRIG の出力は、ComparatorBus1 を経由して、DBB00, DBB01 (LP_Timer)のキャプチャ入力として使用される。
- HP_SCH_TRIG の出力は、ComparatorBus3 を経由して、DBB10, DBB11 (HP_Timer)のキャプチャ入力として使用される。
- Cool Edit Pro 2.0を使って波形生成を行ったらしい。初めて聞いたソフトウェア。お!マルチトラックの編集も出来そうだなぁ。これいいなぁ
- DTMF信号が入ってきたときのみ割り込みが発生する。
ソフトの動き
- timer_isr()
- Clockは32kHzで動作。
- キャプチャバッファは使用せず。(常にActive)
- Period=64
- ComparateValue=0
64周期で割り込みが発生する感じかな。割り込み周期=1/32kHz×64=2ms
Timer_Stop_M
- hp_timer_isr()
- lp_timer_isr()
どぞー♪