Quantcast
Channel: JH7UBCブログ
Viewing all articles
Browse latest Browse all 440

PIC16F628A PWMテスト

$
0
0
 PIC16F628Aを使ってPWM(Pulse Width Modulation)のテストをやってみます。

 Arduinoでは、簡単にPWMが使えますので、PWMを使った経験があるのですが、PICでは初めてなので、WebサイトやPIC16F628Aの説明書を見て、その構造と方法がある程度できました。(完全に理解したわけではありません。Hi)

 まず、ハードウェアですが、PWMは、PIC内のCCPモジュールで行われます。説明書に簡略した図がありました。

イメージ 1 
 PWM信号を作る源発振は、クロックの4倍の周期の信号です。(4・Tosc)

 その信号によって、TMR2がカウントアップされます。

 PWM信号の周期を決定するのはPR2レジスタ(8bit)です。

 TMR2とPR2は常時比較され、一致したらRB3(CCP1)ピンにHighが出力され、TMR2はリセットされます。

 一方、デューティサイクルを決定するのは、CCPR1LレジスタにCCP1COレジスタの5bit目と4bit目の値を加えた10bitのデータです。

 このデータは、CCPR1Hレジスタ(10bit)に送られ、その上位8bitが常時TMR2と比較され、一致したらRB3(CCP1)ピンにLowが出力されます。

 この2つの動作が繰り返され、PWM信号を発生します。TNR2には、プリセレクタを設定することができ、その値を含めて、各レジスタとPWM周期、デューティサイクル、PR2の関係は下の図のようになります。

イメージ 6



 mainプログラムを次のようにして、1000Hz デューティ比50%の信号を発生させてみました。クロックは内部クロック4MHzです。CONFI等は前の記事と同じです。

void main() {
    CMCON = 0x07;       //comparator OFF
    TRISA = 0b00100000; //RA5 input 他はoutput
    TRISB = 0x00;       //全てoutput
    PORTA = 0x00;       //PORTA初期化
    PORTB = 0x00;       //PORTB初期化
   
    /* PWM設定 */
    CCP1CON = 0b00001100;//PWMモード,CCP1X=0,CCP1Y=0
    T2CON = 0b00000001; //プリスケーラ1:4
    /*
     * PWM 周期設定 1000Hzに設定
     * PR2=(クロック周波数/(PWM周波数*4*プリスケーラ値)-1
     *    =(4000000/(1000*4*4))-1
     *    = 249
     */
    PR2 = 249;
    /*カウンタ・レジスタ初期化 */
    CCPR1L = 0;
    CCPR1H = 0;
    TMR2 = 0;
    /* ディーティセット */
    CCPR1L = 199;//デューティ比50%にセット 249/2=124.5なので、124をCCPR1Lにセット
    /* PWM START(TMR2 START) */
    TMR2ON = 1;
    while(1){
       
    }
}

 実際のPWM信号です。

イメージ 2

 周期は、1msよりやや短いですが、ほぼ希望通りデューティ比50%の信号が出ています。

 周波数を測ると

イメージ 3

 1010Hz~1012Hzでした。約1%の誤差です。内部クロックの誤差と思われます。周波数の精度を求めなければ、これで問題ないようです。

 デューティ比を変えて、20%と80%の時の波形です。

イメージ 4

イメージ 5

 OKですね。

 次は、周波数の精度を少し上げて、ドレミファソラシドの音階を発生させてみたいと思います。

 今回は、以下のサイトが大変参考になりました。




Viewing all articles
Browse latest Browse all 440

Trending Articles