« 2014年4月 | トップページ | 2015年4月 »

2014年10月

2014年10月 5日 (日)

PICのお勉強(35) C言語編 PWMでサーボモータを動かす

Pic16f88 16F88のPWM機能を使ってサーボモーターを動かしてみました。
まだ分からないことがたくさんあるのですが、なんとか動いてるようなのでソースを公開します→ lesson35.c
 モーターは秋月で買ったコレですが、まあ何でも大丈夫でしょう。電流をたくさん喰うので、マイコン用とは別に5V電源を用意します。

 サーボモータを動かすためにPWM周期を20ms程度に設定します。(このサイトで勉強しました)
内蔵クロックを1MHz,PR2 を 255,TMR2 プリスケーラ を16 とすると、


命令サイクル:(1s/1MHz)×4クロック = 4μs
PWM周期:4μs×(255+1)×16 = 16,384μs (= 16.384ms)
PWM周期16.4msだとちょっと短いかなあと思いましたが、これで大丈夫みたい。

あとはパルス幅を決めるCCPR1Lの値を指定してやればいいんだけど、これは試行錯誤で10,25,40という値にたどり着きました。これでサーボはだいたい-90度、0度、+90度になりました。
パルス幅を計算してみると、
CCPR1L=10 のとき、4×16×10 = 640μs (=0.64ms)
CCPR1L=25 のとき、4×16×25 = 1,600μs (=1.60ms)
CCPR1L=40のとき、 4×16×40 = 2,560μs (=2.56ms)
となるんだけど、これで計算は合ってるのかなあ。
PICの解説本やWebサイトを見てみると「パルス幅を1.0ms、1.5ms、2.0msにする」なんて書いてあるんだけどね。

/**************************************
16F88 HI-TECH C v.9.83
PWM でサーボモータを動かす
**************************************/

#define _LEGACY_HEADERS
#include

__CONFIG(CCPRB3 & DEBUGDIS & LVPDIS & BOREN & MCLRDIS & PWRTEN & WDTDIS & INTIO);

#define _XTAL_FREQ 1000000 // PICのクロックを1MHz

void main(void)
{
OSCCON = 1000000; // 内蔵OSC 1MHz
ANSEL = 0b00000000; // デジタル
TRISA = 0b11111111; // すべて入力
TRISB = 0b11110111; // BR3は出力
PORTA = 0b00000000;
PORTB = 0b00000000;

CCP1CON = 0b00001100; // PWMモードにする
T2CON = 0b00000111; // プリスケール16
PR2 = 255; // PWM周期
CCPR1L=25; // 中央

while (1)
{
CCPR1L=10;
__delay_ms(1000);
CCPR1L=25;
__delay_ms(1000);
CCPR1L=40;
__delay_ms(1000);
CCPR1L=25;
__delay_ms(1000);
}
}


| | コメント (0) | トラックバック (0)

« 2014年4月 | トップページ | 2015年4月 »