液晶搭載マイコン・モジュール (8) 音量制御
(※これまでの関連記事はカテゴリーの「液晶搭載マイコンモジュール」をご覧ください。)
昨日圧電スピーカによるサウンド機能を追加しましたので、今回はさらに音量調整できるようにしてみました。
とりかかる前は、PWM回路があるから、単にパルスのデューティ比を変えればそのまま音量に反映するだろう、楽勝だ、と思っていました。
ところが、驚いたことに、ソフトを改修して昨日50%にしてあったデューティ比をいくら下げても音量が下がったように見えない(聞えない)ことがわかりました。
初めは当然何かソフトの改修が間違っているのだろうと思いました。しかし手持ちのポータブルオシロで波形を見たところ、信号は確かに設定したデューティ比で出力されているのが確認され、でも音は変わってない、しばし途方にくれてしまいました。。。
気を取り直してWEBで圧電スピーカの特性について調べたところ、基本的には一定音量で鳴るようになっていること、ただし、パルスをごく短くすれば、音量が一定音量に達する前に抑えることができそうなこと、が分かりました。
早速、T16.ch1のプリスケーラ設定を以下のように変更して、今より短い最小パルスを発生できるようにしてみました。また、オシロ確認でパルスが反転しているのが分かりましたので、一緒に直しました。(赤が変更箇所です。)
T16E_CLK1_T16EDF = 0x07; // CLK = PCLK/256 = about 31.250KHz
T16E_CTL1_INITOL = 0; // Initial level = LOW
T16E_CTL1_SELFM = 1; // fine mode select
T16E_CTL1_CBUFEN = 1; // Comparison enable
T16E_CTL1_INVOUT = 1; // Invert output
T16E_CTL1_CLKSEL = 0; // internal clock select
T16E_CTL1_OUTEN = 1; // Clock output enabled
T16E_CTL1_T16ERST = 1; // counter reset
T16E_CTL1_T16ERUN = 0; // Timer stop
これで、サウンド発生ルーチンを以下のように更新しました。
void setSound(int frequency,int volume) {
int work;
if ((frequency>0)&&(frequency<=8000)&&(volume >= 1)&&(volume <= 2)){
work = 31250/frequency;
T16E_CB1_T16ECB = work;
if (volume == 1) {
T16E_CA1_T16ECA = 1;
}else{
T16E_CA1_T16ECA = work/2;
}
T16E_CTL1_T16ERST = 1; // counter reset
T16E_CTL1_T16ERUN = 1; // Timer start
}
if (frequency == 0){
T16E_CTL1_T16ERST = 1; // counter reset
T16E_CTL1_T16ERUN = 0; // Timer stop
}
}
パラメータにvolumeを追加し、1=LOWのときはパルス幅を最小とし、2=Highのときはパルス幅を周期の50%としています。残念ながら方式的に2段階以上の細かい調整は難しいようです。
せっかくPWMがあるので無段階制御といきたいところだったのですが。。。まあ圧電スピーカでそんなに細かいことをやっても仕方ないかな、ということで今回は無理やり納得することにいたしました。(^^;
以上
にほんブログ村 ←記事が面白かったらクリックしてやってください。
コメント