プロメモグラム

誰が見てもわかるような文章を目指す

PIC18F25K22でサーボモータを動かす

標準のPWMだとできない?

PIC18F25K22というか、PICにはCCPというモジュールが搭載されていて、PWMが標準で使える。 しかしながらこのモジュールはあまり長い周期の設定ができない(高周波数だとより厳しい)。 →だいたいのサーボモータ20msの周期中のパルス幅で角度を指定しているから使えない? このように判断した。

だからTMR0で0.1msごとに割り込みを入れて、0.1msの精度でパルスをON、OFFするようにプログラムを書いたらできた。 PICの事良く知らないけど、こんなに割り込んじゃって他のコードに影響出ないか不安。 このコードでつかうサーボは周期が20.0ms。真ん中が1.5ms、1.0~2.0msで角度を決められる。

時間出来たらもう少し詳しく書こう。

ソースコード

/*

 * PWMが低周波数で実現できなそうなのでタイマー0でやる

 */

#include<xc.h>


//コンフィギュレーションビット(内部オシレータを使用)
#pragma config IESO = OFF, FOSC = INTIO67, FCMEN = OFF


//クロック周波数の指定(8MHz)
#define _XTAL_FREQ 8000000

//大域変数
int count = 0;
int countvar; //0.1ms単位で立ち上がるタイミング指定

int main()
{
    int i;
    
    //内部クロックに設定(8MHz)
    OSCCON = 0b01100010;

    //全ポートデジタル入出力
    ANSELA = 0;
    ANSELB = 0;
    ANSELC = 0;

    //全ポート出力
    TRISA = 0;
    TRISB = 0;
    TRISC = 0;

    //全ポートOFF
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0xFF;

    //タイマ設定
    T0CON = 0b01001001;

    //割り込み設定
    TMR0L = 0x37;
    TMR0IF = 0;
    TMR0IE = 1;
    PEIE = 1;
    GIE = 1;

    //TIMER0 Start
    T0CONbits.TMR0ON = 1;



    while(1)
    {
        for(i=10 ; i<=20 ; i+=5)
        {
            countvar = i;
            __delay_ms(90);
            __delay_ms(90);
        }
    }

    return 0;
}

void interrupt isr(void)
{
    TMR0L = 0x37;
    TMR0IF = 0;
    count ++;
    if(count == countvar)
    {
        PORTA = 0;
    }
    else if(count == 200)
    {
        PORTA = 0xFF;
        count = 0;
    }
}