PIC16F628AのPWMを利用して、ドレミファソラシドの音階を発生させてみます。
周波数の精度を上げるために、クロックは、1MHzのクリスタルオシレータを使った外部発振としました。
発生させたPWMは、RB3ピンに圧電ブザー(圧電スピーカー)を直付けして聞いてみます。
回路図です。
ブレッドボードです。
プログラムです。
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 1000000
// CONFIG
#pragma config FOSC = ECIO //外部クロック
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = OFF
#pragma config BOREN = OFF
#pragma config CPD = OFF
#pragma config CP = OFF
#pragma config FOSC = ECIO //外部クロック
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = OFF
#pragma config BOREN = OFF
#pragma config CPD = OFF
#pragma config CP = OFF
unsigned long clock = 1000000;//クロック周波数1MHz
unsigned char ps_val = 4;//TMR2プリスケーラ値
unsigned int f[8] ={262,294,330,349,392,440,494,523};//ドレミファソラシドの周波数
void tone(unsigned int freq){
PR2 = clock / (freq * 4 * ps_val) - 1;//PR2の計算
CCPR1L = PR2 / 2;//デューティ比50%
}
PR2 = clock / (freq * 4 * ps_val) - 1;//PR2の計算
CCPR1L = PR2 / 2;//デューティ比50%
}
void main() {
CMCON = 0x07;//comparator OFF
TRISA = 0b00100000;
TRISB = 0x00;
PORTA = 0x00;
PORTB = 0x00;
/*PWM関係カウンタ・レジスタ初期化 */
CCPR1L = 0;
CCPR1H = 0;
TMR2 = 0;
/* PWM設定 */
CCP1CON = 0b00001100;//PWM mode
T2CON = 0b00000001;//prescaler 1:4
TMR2ON = 1;//TMR2 START
while(1){
for(unsigned char i = 0; i <= 7;i++){
tone(f[i]);
__delay_ms(1000);
}
}
CMCON = 0x07;//comparator OFF
TRISA = 0b00100000;
TRISB = 0x00;
PORTA = 0x00;
PORTB = 0x00;
/*PWM関係カウンタ・レジスタ初期化 */
CCPR1L = 0;
CCPR1H = 0;
TMR2 = 0;
/* PWM設定 */
CCP1CON = 0b00001100;//PWM mode
T2CON = 0b00000001;//prescaler 1:4
TMR2ON = 1;//TMR2 START
while(1){
for(unsigned char i = 0; i <= 7;i++){
tone(f[i]);
__delay_ms(1000);
}
}
}
耳で聞いた感じでは、違和感なくドレミファソラシドが聞こえます。
周波数カウンタで、各周波数を実測してみました。(Hz)
音階(周波数) 実測値
ド262 262
レ294 294
ミ330 330
ファ349 348
ソ392 393
ラ440 440
シ494 496
ド523 525
けっこう良い精度で、音階を発生させることができました。
レ294 294
ミ330 330
ファ349 348
ソ392 393
ラ440 440
シ494 496
ド523 525
けっこう良い精度で、音階を発生させることができました。
#define _C 262 //ド
#define _D 294 //レ
#define _E 330 //ミ
#define _F 349 //ファ
#define _G 392 //ソ
#define _A 440 //ラ
#define _B 494 //シ
#define __C 523 //_ド
#define _D 294 //レ
#define _E 330 //ミ
#define _F 349 //ファ
#define _G 392 //ソ
#define _A 440 //ラ
#define _B 494 //シ
#define __C 523 //_ド
と音階を定義しておけば、記号でメロディーがかけそうです。