PICのPWMの使い方を教えてください
PIC12F1822のPWMのテストをしていますが、正しい設定方法が判らず、以下の現象が出ています。
プログラム全体と、MPLIB のシミュレータによるLogic Analyzerの画像を添付しましたので、PICにお詳しい方のアドバイスをよろしくお願いいたします。
◆ テスト内容: 周波数一定でデューティー比を変化させていく
今回の設定は、PR2=127 なので、パルス幅を0 ~ 最大パルス幅の 511 ((PR2+1)*4)で変化させる
●問題点1: デューティー比100%近く(508/512)でPWM出力が突然 50%に変わる。
●問題点2: デューティー比100%以上(512/512以上)を設定するとPWMは100%('H'のまま)となる。
その後デューティ比を下げてもPWMの出力は'H'のままで、PWMの出力が出ない。
● 問題点3: パルス幅の設定で、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる(出力が'H'のまま) ・・・ これはシミュレータのバグでしょうか?
プログラム全体は、一番下にありますが、メインロジックは以下のように簡単なものです。
while (1) {
for (i = 500; i <= 512; i = i + 1) {
pulse_width = i ;
CCPR1L = pulse_width >> 2; // パルス幅上位8bit
CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; // パルス幅下位2bit
// ここで、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる
__delay_ms(1);
}
}
どうぞよろしくお願いいたします。
K.A.
---------------------------------------------
/*
* File: 周波数一定、ディューティー比連続変化
* Author: K.A.
*
* Created on 2014/07/20
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=ON, BOREN=ON, MCLRE=OFF
#define _XTAL_FREQ 8000000 // クロック8MHz
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
int main(int argc, char** argv) {
OSCCON = 0b01110010; // 内部クロックは8MHz
ANSELA = 0b00000000; // すべてをデジタルI/Oに割当
TRISA = 0b00001000; // すべてのピンは出力に割当てる(RA3は入力専用)
PORTA = 0b00000000; // 出力ピンの初期化(全て'0'にする)
RA5 = 0; // 動作確認用LED
/* PWM */
TRISA2 = 1; // RA2 出力をサスペンド
TMR2IF = 0; // TMR2 フラグをクリア
CCP1SEL = 0b0; // CCP1/P1Aの機能をRA2に割り当てる
CCP1CON = 0x0C; // PWM モード
// Period を 設定する xx ms=((PR2)+1)*4*125ns(8MHz)* PreScaler(x1-x64)
PR2 = 127; // 0.064ms (プリスケーラが x1 の場合)
T2CKPS0 = 0b0; // プリスケーラ 00:x1, 01:x4, 10:x16, 11:x64
T2CKPS1 = 0b0; //
CCPR1L = 0; // パルス幅上位8bit
CCP1CON = ((0 & 0x0003) << 4) | 0x0C; // パルス幅下位2bit
TMR2ON = 1; // TMR2 カウント開始
while (TMR2IF == 0) { /** / do nothing /**/ }
TRISA2 = 0; // RA2に出力を接続
unsigned int pulse_width;
int i;
while (1) {
// パターン1 : デューティー比を変化させていく
// 今回の設定は、PR2=127 なので、最大パルス幅は 511 ((PR2+1)*4)
// 問題点1: デューティー比100%近く(508/512)でPWM出力が突然 50%に変わる。
// 問題点2: デューティー比100%以上(512/512以上)を設定するとPWMは100%('H'のまま)となる。
// その後デューティ比を下げてもPWMの出力は'H'のままで、PWMの出力が出ない。
// 問題点3: パルス幅の設定で、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる(出力が'H'のまま)
for (i = 500; i <= 512; i = i + 1) {
pulse_width = i ;
// Pulse width を 設定する PW=(CCPR1L:CCP1CON<5:4>)*125ns(8MHz)*PreScaler(x1-x64)
CCPR1L = pulse_width >> 2;
CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C;
// CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる
// printf("PR2= %d, PW= %d, CCPR1L= %x, DCIB= %x \n", PR2, pulse_width, CCPR1L, temp2) ;
__delay_ms(1);
if (RA5==1) RA5=0; else RA5=1 ;
}
}
return (EXIT_SUCCESS);
}
----------------------------------------
補足
さっそく返信ありがとうございます。 参照するところはわかるんですが、処理AとBを同時に走らせるには、プログラム的にはどう書いたら良いのでしょうか? 割り込み処理ですと、割り込み処理Aでパルス幅を測定している間は、メイン処理は止まってしまわないのでしょうか?常に同時にってことはできるのでしょうか? よろしくお願いします。