ここでは、小型のDCモータの回転制御を行います。小型DCモータは玩具にもよ良く利用されています。ここで利用するモータは適正電圧1.5V〜3V、電流数百mA程度です。
DCモータは負荷がない場合(回転軸に何も接続されていない場合)、電流は少ないですが非常に高回転になり、軸やブラシを傷めます。また、負荷が重すぎる場合回転数が落ち、高い電流が流れます。電流が適正値を越えると、発熱して故障の原因になります。
モータの回転力は通常トルク(g/cm)であらわします。標準の回転数のときのトルクを適正負荷といいます。数では、標準回転数は約2000(rpm)、トルクは120g程度です。回転数の単位rpmは分あたりの回転数です。モータの回転数は高いので、通常、ギヤ(歯車)で回転数を落として使用します。回転数を 1/100 にすると、トルクは100倍になります。回転数*トルク が仕事量になります。ギヤなどの損失を無視すれば、モータに流し込む電流がモータの仕事量になります。仕事量が同じであれば、回転数が半分になればトルクは倍になります。

(図は http://www.picfun.com/motorframe.html より)
モータに流れる電流は電圧が一定であれば、回転数で定まり外部から制御することは困難です。電圧をかえると、直線的にトルクが増し、回転数も増加しますが、流れる電流が多い場合電圧の制御は簡単ではありません。
そこで、PWM: Pulse Width Modulation 制御がよく利用されます。
この方法は、一定区間の中で通電する割合(時間幅)を変更して平均的な電力を調整する方法です。下図は、25%、50%、75% の電力制御の説明図です。横方向が時間で、立ち上がっている間スイッチをオンにして通電します。

通電幅を0にすればオフ、繰り返し期間と通電期間を同じにすれば、完全オン状態になります。PWM制御は少々荒っぽい手法なので、制御可能な対象は限定されますが モータの電力制御にはよく利用されます。
PIC873にはPWM信号を生成する機能が2回路あります。ただし、全体の周期は2回路とも同じです。まず、setup_ccp1(CCP_PWM);
で、ccp1 機能を PWM に設定します。2回路のPWMが必要なら setup_ccp2 も設定します。
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
次に、タイマー2の周期を設定します。タイマー2はPWMの全体の周期を設定します。 タイマー2の元になるクロックは、PIC 本体のクロックの 1/4
の周波数です(周期は周波数の逆数です)。これを、さらに、1/prd にしてPWMの周期とします。これは、ccp1とccp2に共通です。prdは
255 以下とする必要があります
setup_timer_2(T2_DIV_BY_4,prd,1);
周期の中のパルスの幅(これを duty といいます)を定まるには、set_pwm1_duty(pwt) を利用します。pwt が1周期内部のパルス幅を定めます。これは、周期より小さな値に設定する必要があります。このパルス幅は、ccw1とccw2で異なる値にすることができます。
set_pwm1_duty(pwt1);
set_pwm2_duty(pwt2);
ccw1のpwm信号は、c2/ccp1 端子(13ピン)から、ccw2のpwm信号は、c1/ccp2 端子(12ピン)から取り出すことができます。
//DC Motor 制御
//PWM 制御
#include <16F873A.h>
#fuses HS,NOWDT,NOLVP,NOPROTECT
#use delay(clock = 20000000)
#use RS232(BAUD=9600,xmit=PIN_C6,rcv=PIN_C7)
int i;
int prd;
int div;
void main(){
//ポートA入力
set_tris_a(0xFF);
//ポートB4bit出力
set_tris_b(0xF0);
//RB3にPWM信号生成
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
//タイマー2の周期を約0.1mSに設定
prd=40;
setup_timer_2(T2_DIV_BY_4,prd,1);
prd -= 2;
while(1){
//パルス幅でモータをPWM制御する
div=0;
for(i=0;i<4;i++){
set_pwm1_duty(prd-div);
set_pwm2_duty(prd-div);
output_b(~i);
div += 2;
//1000m秒周期
delay_ms(3000);
}
}
}


