【入門】PIC12F683でPWM制御をしてみよう
PWM制御とは
PWM制御は、下記の記事にも取り上げた内容です。詳しくはそちらを参考にしてください。今回の制御では、12F683の機能を利用してPWM制御をしてみたいと思います。データシートにも詳しく記載してあるので、そちらも紹介しながら説明します。
データシートはこちらから→ここをクリック
プログラムで使用するレジスタの説明
PWMを利用するには、4つのレジスタ設定をする必要があります。データシートと合わせて説明します。使用するポートは、下図の赤枠囲んだ「GP2」になります。回路設計する際には、このピンしか使用できないので注意してください。
PR2レジスタ
PR2レジスタは、PWMを設定するレジスタではなく、タイマー2の周期設定するレジスタになります。PWM波形を生成しているのがタイマー2を使用しているため、PWM周期を決定する重要な設定になります。周期の計算は、データシート79ページに記載されています。PR2は、8ビットのため0から255までの整数を入力します。
<計算例>
PWM={101+1}×4×{1/8000000}×16
=0.000816
周波数は{1/PWM}になるので、1225.4902Hzになります。下図のデータシートに記載されている周波数と同じになりますね。
Tosc:マイコンの周期 ※PICマイコンは、4サイクルで1命令のため、下記の式で4倍にしています。
PR2:0から255で設定 ※データシートでは、16進数で記載されているので注意
T2CONレジスタ
T2CONレジスタの説明です。
TOUTPS<3:0>は、Timer2のポストスケールの設定です
TMR2ONは、使用する:1 使用しない:0
T2CKPS<1:0>は、Timer2のプリスケールの設定です
CCPR1Lレジスタ
CCPR1Lレジスタは、PWMのパルス幅(デューティ比)を決定するものです。必要な画像は、データシート80ページから切り抜きで集めました。CCPR1L:CCP1CON<5:4>というのは「CCP1CONの5ビット目、4ビット目とCCRPR1Lを順に並べた値」という意味です。ビットのイメージを表にしました。デューティを10ビットを表します。(実際の記載方法はプログラムを参照してください)
<計算例>
PulseWidth=(10ビットの整数)×(マイコンのクロック)×(TM2のプリスケール)
CCP1CONレジスタ
PWMの設定をしているレジスタになります。
DC1B<1:0>は、2ビット(4ビット目と5ビット目)がPWM動作時にデューティ比を決定する時に利用します。
CCP1M<3:0>は、モードの設定です。下記は、データシートの説明をそのまま掲載しています。「110x」の「x」は、1or 0 いずれかの数値を入力すれば問題ありません。
例 110x = PWM mode active-high
111x = PWM mode active-low
プログラム
サンプルプログラムは、動作説明しやすいような設定とプログラムになっています。特に、マイコンのクロックを4MHzに設定していると周期が1MHzになるため、
<PWM周期:5KHz>
設定値:PR2:199 マイコンのクロック:4MHz
PWM =(PR2+1)×4×Tosc×TMR2プリスケール
=(199+1)×4×(1/4MHz)×1
=200μS
デューティ比
10%: 200μS × 0.1 =20μS
50%: 200μS × 0.5 =100μS
90%: 200μS × 0.9 =180μS
(例えば、10%の設定値を計算)
Wide = 求めるもの × 4 ×(1/4MHz)×1
20 = 求めるもの × μS
※データシート上と計算式が異なります。おそらく「×4」が抜けているのではないでしょか?データ結果からみても計算が間違っていると思えませんし。。。
動作結果
Pickit2には、簡単なロジックツールがアプリに付属しています。私は、Pickit2こそが最強な書き込みだと思いますが、すでに生産中止&サポート中止です。まあ、クローンを作成できるのでよしとします。
下図は、50%でPWM動作をしているときの波形になります。しっかりと200μS周期に対して、100μSずつONとOFFが繰り返されているのがわかります。
下図は、10パーセントの時の波形になります。きれいに出力されています。
動作(動画)
後日公開
プログラム例
#include <xc.h>
// CONFIG
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-
#define _XTAL_FREQ 4000000
void main(void) {
/*手順1:内部クロックの設定:4MHz*/
/*データシート:P19,P20*/
OSCCON = 0b01101000;
/*ポートプルアップを使いたい場合は、このオプションレジスタを0で有効にしておく*/
/*プリスケーラ:256 */
OPTION_REG = 0b00000111;
/*手順2:ポートデジタルに設定*/
/*P33(P35)*/
/*設定全てデジタル & Fosc/64*/
ANSEL = 0b01100000;
/*手順2:ポートの入出力の設定 1;入力 0:出力*/
/*今回の設定:GP3は入力のみなので1を立てておく。*/
/*データシート:P36*/
TRISIO = 0b00001000;
/*ポートのデータは何が入っているかわからないので、消灯できるように0をポートに入れておく*/
GPIO = 0b00000000;
/*pwmの設定*/
CCP1CON = 0b00001100; //アクティブHigh
T2CON = 0b00000100; //TMR2有効、プリスケーラ1
PR2 = 199;//周期を200μSにするため
while(1){
//10%の設定
CCPR1L = 20;
//CCP1CON = 0b00001100;//←9ビットと10ビットはここへ
__delay_ms(2000);
//50%の設定
CCPR1L = 100;
//CCP1CON = 0b00001100;//←9ビットと10ビットはここへ
__delay_ms(2000);
//90%の設定
CCPR1L =180;
// CCP1CON = 0b00101100;//←9ビットと10ビットはここへ
__delay_ms(2000);
}
return;
}
まとめ
設定から使用するまでの内容を記事にしました。PWMで重要なのは、デューティ比と周波数の設定です。しっかりと設定方法を覚えて状況に合わせて作成できるように頑張ってください。