目次>8章.機能が豊富なPICを使う(PIC12F683)>(6)PWM機能を使ってスピーカを鳴らす(単音を出す)
PWM機能を使ってスピーカを鳴らす (PIC12F683)
(動作確認:単音を出してみる)
更新日2006.3.11
PIC12F683のPWM機能を使ってスピーカを鳴らします。
PIC16F84Aでスピーカを鳴らす実験を行いましたが、PIC16F84AにはPWM機能が無いため、プログラムでパルスを生成し、スピーカに出力しました。
PIC12F683には、CCP(Capture/Compare/PWM)モジュールというものが内蔵されていて、PWMモードに設定すると5番ピン(GP2/CCP1)からパルス(矩形波)を出力できます。
ここでは、CCPのPWMモードを使ってスピーカを鳴らす実験を行います。
実験回路
|
・ |
今回の実験で使用する回路です。
5番ピン(GP2/AN2/T0CKI/INT/COUT/CCP1)にスピーカを接続します。
2番ピン(GP5)のLEDは、今回は使用しませんので無くてもかまいません。
| ブレッドボードの右端にあるLEDと抵抗は、回路図にはありませんが電源ランプとして使っています。
|
|
CCPモジュールとPWMモード
|
|
PIC12F683にはCCPモジュールが内蔵されています。
- CCPモジュールは、レジスタの設定で以下の3種類の動作を選択できます。
キャプチャモード | CCP1ピンの変化によりTMR1(TMR1H:TMR1L)レジスタの内容をCCPR1(CCPR1H:CCPR1L)レジスタにコピーし、キャプチャ割込みを発生する
| コンペアモード | TMR1(TMR1H:TMR1L)レジスタとCCPR1(CCPR1H:CCPR1L)レジスタの値が一致した時、CCP1ピンを変化させたりCCP1割込みを発生させる
| PWMモード | PR2レジスタで指定する周期と、CCPR1Lレジスタで指定するデューティ(パルス幅)により、CCP1ピンからパルス(矩形波)を出力する
|
今回は、PWMモードを使用します。
下図ように、周期を変えずにパルスの幅を変える方式を、PWM(Pulse Width Modulation:パルス幅変調)と言います。
パルス幅(ONの割合)が大きいほど出力の総量が大きくなるので、モータのスピード制御やライト(LEDなど)の明るさ制御などに使用されます。
PIC12F683では、以下のようにPWMを実現しています。
PR2レジスタで周期を指定し、CCPR1Lレジスタでデューティを指定します。
それぞれのレジスタで指定する値は、TMR2のカウント数です。
従って、TMR2の周波数(または周期)を決定すると、周期とデューティを決められます。
TMR2のカウントアップは、1命令サイクル毎に+1されます。
- 具体例を以下に示します。
-
クロック | :4MHz
| PR2 | :239
| CCPR1L | :50
|
命令サイクル | :(1秒/4MHz)×4クロック=1uS(マイクロ秒)
| 周期 | :1uS(マイクロ秒)×239=239uS
| 周波数 | :1秒/239uS=4184Hz
| デューティ | :1uS(マイクロ秒)×50=50uS
|
下の補足は、良く解らなければ、TMR2に4倍/16倍のプリスケーラが使用できることだけを理解し、後の記事は無視しても使用できます。
- 補足1
-
TMR2は、プリスケーラを使用できます。
倍率は、4倍/16倍の2種類で、T2CONレジスタで指定します。
TMR2がデューティとして使用される場合は、プリスケーラ相当の2ビットが下位に付加され、10ビットで使用されます。
- 補足2
-
実際のデューティ指定は、CCPR1Lレジスタの8ビットにCCP1CONレジスタのビット5:4(DC1B1,DC1B0)の2ビットを付加した10ビットでの指定になります。
- 補足3
-
補足1と補足2から、デューティは10ビットの分解能があると言えます。
|
プログラムの仕様
|
|
今回作成するプログラムは、ドレミの「ド」の音をPWMを使用して出すというものです。
クロックは、内部クロックを使用し、4MHzとします。
- 「ド」の音は、261.5Hzとしました。TMR2は16倍のプリスケーラを付けて、動作させます。
-
《設定内容》
クロック | :4MHz
| PR2 | :239
| CCPR1L | :50
| TMR2プリスケーラ | :16倍
|
《結果》
命令サイクル | :(1秒/4MHz)×4クロック=1uS(マイクロ秒)
| 周期 | :1uS(マイクロ秒)×239×16=3.824mS
| 周波数 | :1秒/3.824mS=261.5Hz
| デューティ | :1uS(マイクロ秒)×50×16=0.8mS
|
|
プログラムの作成
|
|
今回のプログラムは単純で、各種レジスタを初期設定するだけです。
今回のプログラムで初期設定するレジスタと、その設定値について説明します。
ここでは、今回設定する値を中心に説明します。
レジスタのもう少し詳しい説明は、「PIC12F683のレジスタ(特殊レジスタ:SFR)」を参照して下さい。
- <GPIOレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | - | GP5 | GP4 | GP3 | GP2 | GP1 | GP0
| 設定値 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
|
ポート(GP0〜GP5)のON/OFFを制御するレジスタで、0をセットするとOFF(LEDは消灯),1をセットするとON(LEDは点灯)になります。
初期値としては、全て0にします。
尚、Bit3,6,7は設定が無視されますが、プログラムでは0をセットします。
- <TRISIOレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | - | TRISIO5 | TRISIO4 | TRISIO3 | TRISIO2 | TRISIO1 | TRISIO0
| 設定値 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
|
ポート(GP0〜GP5)を入力で使うか出力で使うかを指定します。
尚、Bit3,6,7は設定が無視されますが、プログラムでは0をセットします。
- <CMCON0レジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | COUT | - | CINV | CIS | CM2 | CM1 | CM0
| 設定値 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1
|
コンパレータの動作を設定するために使用しますが、今回はGP0〜2をデジタル入出力として使用しますので、CM0〜CM2には1を設定します。
- <OSCCONレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | IRCF2 | IRCF1 | IRCF0 | OSTS | HTS | LTS | SCS
| 設定値 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0
|
OSCCONレジスタでは、オシレータの動作モードを設定します。
今回は4MHzで動作させますので、IRCF2,IRCF1に1を設定します。
- <ANSELレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | ADCS2 | ADCS1 | ADCS0 | ANS3 | ANS2 | ANS1 | ANS0
| 設定値 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
|
ANSELレジスタでは、アナログ入力(A/D変換)の設定を行います。
今回は、AN0〜AN3(GP0,1,2,4)はデジタル入出力で使用しますので、全て0にします。
- <PR2レジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | PWM周期
| 設定値 | 239(十進数)
|
PR2レジスタでは、PWMの周期を指定します。
- <CCPR1Lレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | PWMデューティ
| 設定値 | 50(十進数)
|
CCPR1Lレジスタでは、PWMのデューティ(パルス幅)を指定します。
- <CCP1CONレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | - | DC1B1 | DC1B0 | CCP1M3 | CCP1M2 | CCP1M1 | CCP1M0
| 設定値 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0
|
CCP1CONレジスタでは、CCPモジュールの動作を指定します。
今回は、PWMモードで使用しますので、CCP1Mxに1100を設定します。
- <T2CONレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | TOUTPS3 | TOUTPS2 | TOUTPS1 | TOUTPS0 | TMR2ON | T2CKPS1 | T2CKPS0
| 設定値 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1
|
T2CONレジスタでは、TMR2のプリスケーラ(T2CKPSx)とTMR2動作開始(TMR2ON)を設定します。
コンフィグレーションビット(__CONFIG命令の設定)
|
__CONFIG命令では以下の記述をします。
__CONFIG _CP_OFF & _CPD_OFF & _WDT_OFF & _BOD_ON & _IESO_OFF& _PWRTE_ON & _INTOSCIO & _MCLRE_OFF
|
-
_CP_OFF | プログラムメモリコードプロテクトしない
| _CPD_OFF | EEPROMメモリコードプロテクトしない
| _WDT_OFF | ウォッチドックタイマ使用しない
| _BOD_ON | 電源電圧低下監視を有効にする
| _IESO_OFF | 内部・外部切り替えモード無効
| _PWRTE_ON | パワーアップタイマ有効
| _INTOSCIO | オシレータは内部クロック使用(2番ピン:GP5,3番ピン:GP4)
| _MCLRE_OFF | マスタクリア無効(4番ピンをGP3として使用)
|
|
プログラム全体
|
| 上記の処理を組み込んだプログラムはこちらです。
メモ帳などのテキストエディタに取り込んで、P683PWM.ASMという名で保存し、MPLABでアセンブル&PICライタでPICに書き込んで動かしてみて下さい。
今まで、PIC16F84Aを使用していた場合は、MPLABのプロジェクトウィザードで「PIC12F683」を選択して下さい。
また、PICライタでも同様に「PIC12F683」を選択して下さい。
|