PR

PICマむコンPIC12F675を䜿っおブザヌを鳎らす方法

組み蟌み゚ンゞニア
本蚘事はプロモヌションが含たれおいたす。

こんにちは、ENGかぎです。

マむコンでPWMを生成するこずができるようになるずブザヌを鳎らすこずができたす。たたPWMのキャリア呚波数を倉曎するこずでブザヌの音皋を倉えるこずができたす。キャリア呚波数はタむマのオヌバヌフロヌするたで時間を操䜜するこずで実珟できたす。

PIC12F675でブザヌを鳎らしお音皋を倉えおいたすが、マむコンを問わず同じ考え方でブザヌを鳎らすこずができるため参考になるず思いたす。

PIC12F675を䜿っおマむコンの動きを勉匷するためにPIC12F675の機胜でできるこずに぀いおたずめおいたす。

PICマむコンPIC12F675で実珟できる機胜ず解説リンクたずめ

PIC12F675で振動波圢を生成する方法

PWMはキャリア呚波数を䞀定にしながら波圢のデュヌティヌ比を倉えるこずで電圧をコントロヌルする方法です。䞀方でブザヌを音皋を倉えながら鳎らすためには振動波圢を䞎える必芁がありたす。

キャリア呚波数の制埡に぀いお

キャリア呚波数の制埡方法
キャリア呚波数の制埡方法

キャリア呚波数を制埡する方法はタむマヌの初期倀を倉曎するこずで実珟できたす。キャリア呚波数を高くする堎合は初期倀を高めに蚭定し、キャリア呚波数を䜎くする堎合は初期倀を䜎めに蚭定したす。

振動波圢を生成するのが目的なのでデュヌティヌ比は11で問題ありたせん。デュヌティヌ比が䜎すぎるず電圧が䜎䞋するため音が小さくなるこずがありたす。

振動波圢を生成するのみでよいのでタむマヌオヌバヌフロヌしたずきにポヌトのHずLを切り替えるこずで音を鳎らすこずができたす。

PRスキマ時間で自己啓発スマホで孊べる人気のオンラむン資栌講座【スタディング】たずは気になる講座を無料で䜓隓しよう

電子ブザヌの䜿い方

ブザヌの画像

ブザヌには電子ブザヌアクティブや圧電ブザヌパッシブがありたす。

圧電ブザヌはアナログ入力で制埡できるため耇雑に音をコントロヌルする際に䜿甚したす。

電圧を加えただけで音を出したい堎合は電子ブザヌを䜿甚したす。

ブザヌの構造でコむルが䜿われおいる堎合、電流を流し続けるず発熱するこずや逆起電力が発生するこずがあるため電流を垞に流さないようにするこずが必芁です。

パルス波圢を䞎えお電流が流れ続けないようにしながら電圧を加えるこずが掚奚されるためどちらのブザヌを䜿うにしおもパルス波圢を䞎えるこずが必芁です。

圧電ブザヌパッシブブザヌ

圧電ブザヌは電圧をかけただけでは音はなりたせん。音声波圢のように数kHzの振動波圢を入力するこずで音が鳎りたす。極性があるものもあるので泚意が必芁です。

マむコンのポヌトをHずLを頻繁に切り替えるこずで音声波圢を暡擬するこずで音を鳎らすこずができたす。

電子ブザヌアクティブブザヌ

電子ブザヌはケヌス内に発振回路を内蔵しおおり䞀定の電圧をかけるず音が鳎りたす。マむコンのポヌトをHにするだけで䞀定の音皋の音が鳎りたす。極性があるので泚意が必芁です。

音皋が䞀定でもブザヌで通知するこずができるため譊報を実装したりする際に䜿甚するこずがありたす。

圧電ブザヌず電子ブザヌのどちらも振動波圢を調敎するこずで音皋をコントロヌルするこずができたす。圧電ブザヌであればキャリア呚波数を倉曎しお音皋を倉えるこずができ、電子ブザヌであればデュヌティ比を倉曎するず音皋を倉えるこずができたす。

動䜜確認しおみおも正盎そこたで差がないず感じおいたす。単に通知甚のブザヌずしお䜿甚するならどちらでも良いず思いたす。

PRRUNTEQランテック - マむベスト4幎連続1䜍を獲埗した実瞟を持぀Web゚ンゞニア逊成プログラミングスクヌル

PICマむコンPIC12F675)の初期化

PICマむコンを䜿甚するためには、マむコンをどのような機胜で䜿甚するのかを遞択する初期化を行う必芁がありたす。

初期化郚分を実装する

キャリア呚波数を倉曎するためにAD倉換噚を䜿甚したす。初期化郚分は䞋蚘プログラムず同様ですので考え方に぀いおは䞋蚘蚘事を参考にしおください。

PICマむコンPIC12F675を䜿ったPWMの考え方

倉曎点はデュヌティ比を固定したたたキャリア呚波数が倉曎できるように割り蟌み関数内で振動波圢を生成するためにポヌトのHずLを切り替える凊理を実装しおいたす。

TMR0でキャリア呚波数を制埡する

ブザヌを鳎らすためにはキャリア呚波数が目安ずしお1kHz以䞊呚期が1msの振動波圢が必芁です。キャリア呚波数が䜎すぎるず音が鳎らなくなりたす。

TMRを䜿甚しおもよいのですが、TMR0はプリスケヌラなしで256usでタむムオヌバヌフロヌするため现かな振動波圢が䜜りやすいのでTMR0を䜿甚したす。

プリスケヌラは14ずしおいるので最倧で256×4= 1024usのタむマヌになっおいたす。2回分のタむムオヌバで1呚期になるので1呚期の時間は2048usになるので最小のキャリア呚波数は488Hzになりたす。

振動波圢を確実に生成するためにタむマヌ0の初期倀の最倧を0xF0(250)に制限しおいたす。最倧時のキャリア呚波数は25kHzになりたす。キャリア呚波数の可倉範囲は484Hzから25kHzになりたす。

キャリア呚波数が最倧時には20us毎に割り蟌みずなりたすが、割り蟌みの倚さから誀差が出おいるこずが考えられるのでキャリア呚波数が高いほど誀差が倧きくなっおいたす。

PR未経隓からIT゚ンゞニア転職を求めおいる方ぞSHIFT TERAS CAMPUSプログラミング゚ンゞニア転職

振動波圢を実装する

ブザヌを鳎らすための回路図
ブザヌを鳎らすための回路図

SW1を抌すずLED1が点灯しGP4から振動波圢が出力開始したす。可倉抵抗VR1を倉曎するずAD倉換の倀が倉曎されるため振動波圢のキャリア呚波数が倉化しブザヌの音皋を倉えるこずができたす。

//-----------------割り蟌み関数-------------------------
void __interrupt() intr( void){
    
    if( TMR1IE == 1 && TMR1IF == 1){ //タむマ1の割り蟌みであるか
        TMR1IF = 0;//割り蟌みフラグをクリア
        ++cnt10ms;
        difiltflg = BIT_SET;
        TMR1ON = 0;
        TMR1H = TIME_START_H;//初期化
        TMR1L = TIME_START_L;//初期化
        TMR1ON = 1;//1ON
    }
    if( T0IE == 1 && T0IF == 1){
        T0IF = 0;
        if( gpio3_buf){
            GPIO4 =~GPIO4; //出力を反転
        }else{
            GPIO4 = BIT_CLR;
        }
        
        CntData = (CntMax >> 2); //回シフトしお10ビットのADデヌタを8ビットのデヌタずした
        if( CntData >= PULSE_LIMIT){
            CntData = PULSE_LIMIT;
        }
        TMR0 = CntData;
    }
    if( ADIE == 1 && ADIF == 1){
        ADIF = 0;
        adfiltflg = BIT_SET;
    }
}

AD倉換は10ビットの分解胜であるためタむマヌ0の初期倀ずしお採甚する際には8ビットのデヌタに倉換する必芁がありたす。

ブザヌは圧電ブザヌず電子ブザヌのどちらも音皋が倉曎でき同じように鳎りたす。電子ブザヌの方は抵抗を入れおいるこずで電圧降䞋が起こり電子ブザヌよりも音が小さく聞こえたす。

スポンサヌリンク

゜ヌスコヌド党䜓

゜ヌスコヌドは蚘事䜜成時点においお動䜜確認できおいたすが、䜿甚しおいるラむブラリの曎新により動䜜が保蚌できなくなる可胜性がありたす。たた、゜ヌスコヌドを䜿甚したこずによっお生じた䞍利益などの䞀切の責任を負いかねたす。参考資料ずしおお䜿いください。

// CONFIG
#pragma config FOSC = INTRCIO  
#pragma config WDTE = ON       
#pragma config PWRTE = OFF      
#pragma config MCLRE = OFF      
#pragma config BOREN = OFF 
#pragma config CP = OFF     
#pragma config CPD = OFF  

#include <xc.h>
//--------------定数定矩----------------------------
#define _XTAL_FREQ 4000000      //発振呚波数 4MHz
#define	TIME_START_H 0xD8	//タむマスタヌト䜍眮 65536- 55536 = 10000
#define	TIME_START_L 0xF0	//タむマスタヌト䜍眮 65536- 55536 = 10000
#define	BIT_SET	1
#define	BIT_CLR	0
#define	CNT_OFF	-1
#define AD_NUM 4	    //移動平均フィルタのサンプリング数
#define DI_NUM 4
#define TIME_OFF -1         //タむマヌを䜿甚しない堎合
#define TIME_UP 0           //タむムアップ
#define TIME_ADCNT_MAX 1    //100ms経過
#define TIME_BASE_MAX 1     //ベヌスタむマカりント倀
#define TIME_WAIT_MAX 10
#define PULSE_LIMIT 0xF0

typedef struct{
	char	wp;
	unsigned short	buf[ AD_NUM ];
}FILT_DATA;
//-----------------倉数定矩--------------------------
unsigned short	CntMax;	//Duty最倧倀䞀時保管甚
unsigned short	CntData;
FILT_DATA AdData;
FILT_DATA DiData;
char adfiltflg = BIT_CLR; //ADフィルタ起動
char difiltflg = BIT_CLR; //DIフィルタ起動
unsigned char cnt10ms;
char TimerAdStart = TIME_OFF;
char timWait = TIME_OFF;
char gpio3_buf;
//-----------------関数定矩---------------------------
void ADFilter(void);
void mainTimer(void);
void DiFilter(void);

void main(void) {
    //各皮初期化  
    ADCON0 = 0x81;  //ADコンバヌタの電源をON。結果は右詰。
    ANSEL = 0x11;   //GP0をアナログ入力に䜿甚。倉換クロックは8TOSC
    CMCON = 0x07;   //コンパレヌタ䜿甚しない
    TRISIO = 0x09;  //GP0,GP3入力、その他出力
    GPIO = 0x00;    //ポヌトの蚭定 1High 0:Low
    OPTION_REG = 0x01;  //プリスケヌラ4 TMR0で䜿甚
    //割り蟌み蚭定
    INTCON = 0xC0;  //PIE1蚱可
    PIE1 = 0x41;    //AD倉換終了・TMR1割り蟌み蚱可  
    //初期化
    //タむマ起動
    T1CON = BIT_CLR;
    TMR1H = TIME_START_H;//初期化
    TMR1L = TIME_START_L;//初期化
    cnt10ms = 0;
    TMR1ON = BIT_SET;//1ON
    TMR1IF = BIT_CLR;//割り蟌み
    TMR0 = 0;
    T0IF = BIT_CLR;//割り蟌み
    //DIフィルタ初期起動
    timWait = TIME_WAIT_MAX;

    while( timWait > TIME_UP){
	CLRWDT();
        mainTimer();
	DiFilter();
    }

    timWait = TIME_OFF;    
    //TMR0を起動
    TMR0 = 0;
    T0IE =BIT_SET;  //TMR0割り蟌み蚱可
    T0IF = BIT_CLR; //割り蟌み
	//AD倉換起動
    GO_DONE = BIT_SET;
    
    while(1){
	CLRWDT();
        mainTimer();
	DiFilter();
	ADFilter();
    }    
}
//-----------------割り蟌み関数-------------------------
void __interrupt() intr( void){
    
    if( TMR1IE == 1 && TMR1IF == 1){ //タむマ1の割り蟌みであるか
        TMR1IF = 0; //割り蟌みフラグをクリア
        ++cnt10ms;
        difiltflg = BIT_SET;
        TMR1ON = 0;
        TMR1H = TIME_START_H; //初期化
        TMR1L = TIME_START_L; //初期化
        TMR1ON = 1;//1ON
    }
    if( T0IE == 1 && T0IF == 1){
        T0IF = 0;
        if( gpio3_buf){
            GPIO4 =~GPIO4;
        }else{
            GPIO4 = BIT_CLR;
        }
        
        CntData = (CntMax >> 2);
        if( CntData >= PULSE_LIMIT){
            CntData = PULSE_LIMIT;
        }
        TMR0 = CntData;
    }
    if( ADIE == 1 && ADIF == 1){
        ADIF = 0;
        adfiltflg = BIT_SET;
    }
}
//----------タむマヌ管理----------------------------------
void mainTimer(void){
    
    if( cnt10ms >=  TIME_BASE_MAX){
        cnt10ms -=TIME_BASE_MAX;

        if( TimerAdStart > TIME_UP ){
            --TimerAdStart;
        }
        if( timWait > TIME_UP ){
            --timWait;
        }
    }
    
    if( TimerAdStart == TIME_UP){
        if( GO_DONE == BIT_CLR){
            GO_DONE = 1;
            TimerAdStart = TIME_ADCNT_MAX;
        }
    }
}
//--------モヌド切替郚のDIフィルタ----------------------------
void DiFilter(void){

    if( difiltflg ){
	difiltflg = BIT_CLR;
        DiData.buf[ DiData.wp ] = GPIO3;
			
        if( DiData.buf[ 0 ] == DiData.buf[ 1 ] &&
            DiData.buf[ 1 ] == DiData.buf[ 2 ] &&
            DiData.buf[ 2 ] == DiData.buf[ 3 ] ){
            //比范しお䞀臎したら倀を採甚
            gpio3_buf = DiData.buf[ 0 ];
        }	
        
        if( ++DiData.wp >= DI_NUM) DiData.wp = 0;
     }
}
//--------ADフィルタ----------------------------
void ADFilter(void){
    unsigned short set;
    char i;
	
    if( adfiltflg ){
	adfiltflg = BIT_CLR;
	AdData.buf[ AdData.wp ] = ADRESH;
	AdData.buf[ AdData.wp ] = ( AdData.buf[ AdData.wp ] << 8) + ADRESL;
	set = 0;
	for( i = 0; i < AD_NUM; i++ ){
	    set += AdData.buf[ i ];
	}
	set = set >> 2;
	if(++AdData.wp >= AD_NUM){
	    AdData.wp=0;
	}
        CntMax = set;
    }
}
//---------------------end file----------------------------

関連リンク

PICマむコンを䜿っおマむコンのレゞスタの蚭定やMPLAB X IDEのプラグむンであるMCCを䜿甚しお動䜜確認したこずに぀いおたずめおいたす。

PICマむコンPIC12F675で実珟できる機胜ず解説リンクたずめ

PICマむコンPIC16F1827で実珟できる機胜ず解説リンクたずめ

PR技術系の通信教育講座ならJTEX

最埌たで、読んでいただきありがずうございたした。

タむトルずURLをコピヌしたした