目次
前
次
音出し(割込み活用)
音を出すには音源を複数用意して、切り替える方法もあります。
ブロック図でみると、以下。
複数の音源を用意して、アナログマルチプレクサで切り替えれば
チャイムや警報音を出力できます。
この方式で回路を考えました。
PICからアナログマルチプレクサに2ビットのパターンを与えると
対応した周波数の音がスピーカから出力される方式。
音を出すためにPICが担当する役割は、以下の2点。
周波数選択
出力時間決定
出力時間は、タイマー割込みで2msを刻んで
システムタイマーを作り、関数で時間幅を調整
すればよいでしょう。
割込みによるシステムタイマーの定義は、以下。
typedef unsigned long ULONG ;
ULONG xcnt ;
void interrupt(void)
{
/* generate 2ms */
if ( INTCON.TMR0IF == ON ) {
/* clear flag */
INTCON.TMR0IF = OFF ;
/* 256 - 250 = 6 */
TMR0 = 6 ;
/* increment */
xcnt++ ;
}
}
1msの割込みで、システムタイマーカウンタxcntをインクリメント
しておき、時間幅はdelay_ms、delayで生成します。
typedef unsigned char UBYTE ;
typedef unsigned int UWORD ;
void delay_ms(UWORD x)
{
ULONG last ;
/* calculate target */
last = xcnt + (x >> 1);
/* wait */
while ( xcnt < last ) ;
}
void delay(UBYTE x)
{
UWORD i ;
UBYTE last ;
/* last count */
last = x ;
/* wait */
for ( i = 0 ; i < last ; i++ ) {
delay_ms(1000);
}
}
最下位でハードウエアを動かす関数を定義します。
周波数と時間幅をパラメータにして関数snd_outを定義。
#define SND_A 0
#define SND_B 1
#define SND_C 2
#define SND_D 3
#define SND_NONE 7
void snd_out(UBYTE which,UWORD tx)
{
/* judge sound number */
if ( which > SND_NONE ) return ;
/* send sound number */
PORTA = which & 7 ;
/* delay (1 second x N) */
delay( tx );
}
チャイムを鳴らすような場合、プッシュボタンを利用して
トリガーを与えます。
トリガーが来たかを判断するのは、入力ピンの論理値が
0から1、1から0の変化をとらえます。
PIC16F627では、ポートBの0ビット目が外部割込みの入力
ピンになっているので、ここにプッシュボタンを接続して
トリガーを扱えるようにします。
外部割込みを使うと、割込みハンドラに対応するコードを追加。
void interrupt(void)
{
/* generate 1ms */
if ( INTCON.TMR0IF == ON ) {
/* clear flag */
INTCON.TMR0IF = OFF ;
/* 256 - 250 = 6 */
TMR0 = 6 ;
/* increment */
xcnt++ ;
}
/* external interrupt */
if ( INTCON.INTF == ON ) {
/* clear flag */
INTCON.INTF = OFF ;
/* set event flag */
EFLAG = ON ;
}
}
割込み関連レジスタの該当フラグを見て、セットされていた
ならば、クリア後、イベント通知フラグをセット。
イベント通知フラグをとらえて、チャイムを鳴らすシーケンスを
起動してみればよいでしょう。
if ( EFLAG == ON ) {
/* clear flag */
EFLAG = OFF ;
/* start */
snd_out(SND_A,1);
snd_out(SND_B,3);
snd_out(SND_C,2);
snd_out(SND_D,5);
snd_out(SND_C,3);
snd_out(SND_B,2);
snd_out(SND_A,3);
}
2つの割込みを使えるように、初期化処理を定義。
/* initialize timer 0 */
{
/*
4MHz/4 = 1MHz (Fosc)
Fosc/4 = 250kHz
250kHz/2 = 125kHz prescaler = 1:2
*/
OPTION_REG = 0x00 ;
/* 256 - 250 = 6 */
TMR0 = 6 ;
/* enable timer0 overflow interrupt */
INTCON.TMR0IE = ON ;
}
/* external interrupt */
{
/* select edge manner */
OPTION_REG.INTEDG = ON ;
/* enable */
INTCON.INTE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
ソースコードをまとめると、以下。
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
typedef unsigned int UWORD ;
typedef unsigned long ULONG ;
#define SND_A 0
#define SND_B 1
#define SND_C 2
#define SND_D 3
#define SND_NONE 7
volatile UBYTE EFLAG ;
volatile ULONG xcnt ;
/* prototype */
void usr_init(void);
void snd_out(UBYTE which,UWORD tx);
void delay_ms(UWORD x);
void delay(UBYTE x);
void main(void)
{
/* initialize */
usr_init();
/* endless loop */
while (ON) {
if ( EFLAG == ON ) {
/* clear flag */
EFLAG = OFF ;
/* start */
snd_out(SND_A,1);
snd_out(SND_B,3);
snd_out(SND_C,2);
snd_out(SND_D,5);
snd_out(SND_C,3);
snd_out(SND_B,2);
snd_out(SND_A,3);
}
}
}
void usr_init(void)
{
/* initialize PORT values */
PORTA = 0x00 ;
PORTB = 0x00 ;
/* set directions */
TRISA = 0x00 ;
TRISB = 0xfe ;
/* initialize timer 0 */
{
/*
4MHz/4 = 1MHz (Fosc)
Fosc/4 = 250kHz
250kHz/2 = 125kHz prescaler = 1:2
*/
OPTION_REG = 0x00 ;
/* 256 - 250 = 6 */
TMR0 = 6 ;
/* enable timer0 overflow interrupt */
INTCON.TMR0IE = ON ;
}
/* external interrupt */
{
/* select edge manner */
OPTION_REG.INTEDG = ON ;
/* enable */
INTCON.INTE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
/* others */
EFLAG = OFF ;
xcnt = 0 ;
snd_out(SND_NONE,0);
}
void snd_out(UBYTE which,UWORD tx)
{
/* judge sound number */
if ( which > SND_NONE ) return ;
/* send sound number */
PORTA = which & 7 ;
/* delay (1 second x N) */
delay( tx );
}
void delay_ms(UWORD x)
{
ULONG last ;
/* calculate target */
last = xcnt + (x >> 1);
/* wait */
while ( xcnt < last ) ;
}
void delay(UBYTE x)
{
UWORD i ;
UBYTE last ;
/* last count */
last = x ;
/* wait */
for ( i = 0 ; i < last ; i++ ) {
delay_ms(1000);
}
}
PIC16F627は、切替え器を構成していると言えます。
すべての機能をマイコンに持たせないで、固定した専用回路で
実現できることは任せた方が、わかりやすいこともあります。
目次
前
次