閲覧総計:9017  (本日:1235;  昨日:2)

サーボモーターを動かす(16F1827 XC8)

タイマー割り込み機能の応用として、サーボモーターを動かしてみた。
↓使用したサーボモーター RB303
http://www.ministudio.co.jp/Cgi-bin/Order-JP/DetailJp.asp?GoodsNum=97
サーボモーターは1ms〜2msのパルス信号を、周期15ms〜20msで送信する事で制
御します。
http://homepage3.nifty.com/mitt/pic/pic5_23.html
【ポイント】
1.TMR0割り込みで15msの周期を作成
今回はTimer0割り込みで15.104msの周期を作成しサーボの制御信号としました。
2.グローバル変数angleにてパルス信号幅を制御
引数に変数設定できるarg_delay()遅延関数を作り、グローバル変数angleで
パルス信号幅を制御しました。0〜240, サーボ中位地は120  2014/1/5

TS3V0007.JPGサーボモーター制御信号のロジアナ画面.jpg16F1827ピン配置.JPG
/* サーボモーターの制御(タイマー割り込み)
 * PIC16F1827
 * XC8 v1.20
 * Servo:RA1
 * LED:RA2
 */
#include <xc.h>

#pragma config FOSC = INTOSC, WDTE = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#pragma config PLLEN = OFF, STVREN = OFF, LVP = OFF

//__delay_us(), __delay_ms()へのクロック情報の設定
#define _XTAL_FREQ 8000000 //PICのクロックをHzで設定(8MHz)

//関数のプロトタイプ宣言
extern void arg_delay(unsigned int x);

//グローバル変数の定義
unsigned char angle; //サーボの振れ角度

int main(void) {
    //PICの初期設定
    PORTA = 0b00000000; //PORTAの中身をきれいにする
    TRISA = 0b00000000; //PORTA全てを0:出力に設定
    OSCCON = 0b01110000; //PLL:OFF, 内部クロック8MHzで駆動
    ANSELA = 0b00000000; //AN0-AN4は全て0:デジタルI/Oとする

    //TMR0割り込みの初期設定
    //15.104ms=0.125us(8MHz)*4*プリスケーラー256*118カウント
    //ちなみに19.968ms=0.125us(8MHz)*4*プリスケーラー256*156カウント
    OPTION_REG = 0b0111; //プリスケーラ値設定0b0111(=256回)
    TMR0 = -118; //TMR0カウント値設定 118回(アップカウンタ)
    INTCONbits.TMR0IE =1; //タイマ割込み許可
    INTCONbits.GIE = 1; //全体割込み許可

    //メイン処理
    LATAbits.LATA2 = 1; //RA2:パワーオンを示すLED点灯
    angle = 120; //サーボの触れ角を0度に
    while(1) {
        //基準角度確認
        angle = 0; __delay_ms(2000);
        angle = 120; __delay_ms(2000);
        angle = 240; __delay_ms(2000);
        angle = 120; __delay_ms(2000);

        //左端から右端まで首を振る
        for(angle = 0; angle < 240; angle++)
            __delay_ms(50);
        for(angle = 240; angle > 0; angle--)
            __delay_ms(50);
    }
}

static void interrupt isr(void) { //割り込み関数
    if(INTCONbits.TMR0IF == 1) {  //割込み種がTimer0割込みの場合
        INTCONbits.TMR0IF = 0; //Timer0割り込みフラグクリアー
        TMR0 = -118; //TMR0カウント値設定 118回(アップカウンタ)

        LATAbits.LATA1 = 1; //パルスON
        arg_delay(100 + angle); //パルスON時間
        LATAbits.LATA1 = 0; //パルスOFF
    }
}

//待ち時間が変数設定できるarg_delay()関数を定義
//(_delay()は引数に変数設定が出来ない為)
void arg_delay(unsigned int x) {
     while(x) {
         _delay(1);
         x--;
     }
}

 
★この情報は役に立つか?

選択肢 投票
はい 42  
普通 38  
いいえ 36