- 9977. 16F84AでモータPWM制御方法 [kazu2] 2006/03/21 12:40
- 16F84Aで2個のモータを独立にPWM制御する方法を考えてます。
しかし、duty99%(2.39V)とduty98%(1.89V)の間に大きな実効
電圧ステップが発生してしまいます。実効電圧2.3V、2.2V、2.0Vあ
たりの制御を実現したいのですが、解決方法をアドバイス頂けると
助かります。
duty V(実効電圧)
100 2.34
99 2.39
98 1.89
97 1.84
90 1.68
80 1.56
70 1.46
60 1.36
/**
* PWMテスト
*
* PIC 16F84A
* 発信器 10MHz
* 言語 MikroC v2.1
* Device Flags: _CP_OFF _PWRTE_ON _WDT_OFF _HS_OSC
*
* モータ mabuchi FA-130RA(1.5V-3.0V)
* モータドライバIC 東芝TA7291P
* http://www.semicon.toshiba.co.jp/td/ja/Linear_ICs/Motor_Driver_ICs/20060307_TA7291SG_datasheet.pdf
* PortB 0,1:モータ右
* PortB 6,7:モータ左
* 電源:電池4本(実測5.4V)
*/
/**
* my_PWM_RB0() 機能:RB0の出力を0%-100%で制御する
*
* duty:範囲 0-100
* 500ループで約1秒
*/
void my_PWM_RB0(unsigned short int duty) {
unsigned short int period = 100; //PWM分解能
unsigned short int t_count;
PORTB.F0 = 1; //ON
for(t_count = 0; t_count < period; t_count++){
if(t_count > duty) {
PORTB.F0 = 0; //OFF
}
delay_us(10);
}
}
void my_PWM_RB6(unsigned short int duty) {
unsigned short int period = 100; //PWM分解能
unsigned short int t_count;
PORTB.F6 = 1; //ON
for(t_count = 0; t_count < period; t_count++){
if(t_count > duty) {
PORTB.F6 = 0; //OFF
}
delay_us(10);
}
}
void main() {
unsigned int i;
unsigned int pause = 1000; //待機時間1秒
//ポートの初期化
PORTB = 0b00000000;
//入出力の設定 1:input 0:output
TRISB = 0b00000000; //PORTB 8ヶ全て出力に設定
do {
for(i = 0; i < 1000; i++) { //約2秒継続
my_PWM_RB0(90); //90%右前進
my_PWM_RB6(90); //90%左前進
}
PORTB = 0b00000000; //停止
Vdelay_ms(pause); //待機
} while(1);
}
- 9978. Re: 16F84AでモータPWM制御方法 [松本] 2006/03/21 13:27
- duty=99の時PORTBがoffにならないからでないかい?
- 10043. Re: 16F84AでモータPWM制御方法 [kazu2] 2006/03/29 00:37
-
> duty=99の時PORTBがoffにならないからでないかい?
アドバイスありがとうございます。
アドバイスを元に色々検討してみました。しかし、目的の2.0V近辺の
細かい制御を実現する事が出来ませんでした。
if(t_count > duty) { → if(t_count > duty -1) {
に変更する事で、duty=99とduty=98の間に大きな電圧差はなくなり
ました。
しかし、大きな電圧さはduty=100とduty=99の間に移動しただけで
2.0V近辺の細かい制御を実現する事が出来ませんでした。
PORTBをoffにしている時間10μ秒が長過ぎるのが影響しているのでは
と考え、off時間を1μ秒にして見ましたが問題は解決しませんでした。
duty V(実効電圧)
100 2.29
99 1.73
98 1.70
97 1.68
90 1.58
次に delay_us(10); の行を削除してみましたが、これも目的を実現
する結果とはなりませんでした。
PORTB.F0 = 1; //ON
for(t_count = 0; t_count < period; t_count++){
if(t_count > duty - 1) {
PORTB.F0 = 0; //OFF
}
}
duty V(実効電圧)
100 2.12
99 1.63
98 1.60
97 1.52
90 1.39
実効電圧2.3V、2.2V、2.0Vあたりの制御を実現する方法をアドバイス
頂けると助かります。よろしくお願いします。
- 10044. Re: 16F84AでモータPWM制御方法 [記事一覧でツリーを上に上げない] 2006/03/29 01:22
- >実効電圧2.3V、2.2V、2.0Vあたりの制御を実現する方法をアドバイス
>頂けると助かります。よろしくお願いします。
PICで直接PWMをする以上、2.0=0%, 2.3V=100%のような範囲分けは無理でしょう。
PICの外部に回路を置けば、方法はいくらでもありそう。
- 10045. Re: 16F84AでモータPWM制御方法 [kazu2] 2006/03/29 01:46
-
> > 実効電圧2.3V、2.2V、2.0Vあたりの制御を実現する方法をアドバイス
> > 頂けると助かります。よろしくお願いします。
> PICで直接PWMをする以上、2.0=0%, 2.3V=100%のような範囲分けは無理でしょう。
> PICの外部に回路を置けば、方法はいくらでもありそう。
早急なお返事ありがとうございます。
0.0V=0%, 2.3V=100%, 2.2V=95%, 2.1V=90%の制御を希望してますが、
これなら可能な方法がありますでしょうか?
- 10046. Re: 16F84AでモータPWM制御方法 [R] 2006/03/29 02:03
- 質問の回答とは違いますが・・・
2つのモータをmy_PWM_RB0/my_PWM_RB6と別々に制御しているので90%とかにはなりませんよ。
90%と指定したら約半分の45%となります。
0〜100%の制御をしたければ2つのPWMを同時に処理してください。
- 10047. 投稿者削除 [ ] 2006/03/29 09:19
-
- 10048. Re: 16F84AでモータPWM制御方法 [松本] 2006/03/29 09:30
- 既にかかれてますが、片方ずつ制御しているので、一方を制御している時他方はOFFになるので、PWMとしては0〜50%にしかなってません。
なので、両方同時に制御したほうが良いです。
たとえば以下のようにしてみたらどうです?
void my_PWM(u8 right_duty, u8 left_duty) {
u8 period = 100; //PWM分解能
u8 t_count;
PORTB.F0 = 1; // right ON
PORTB.F6 = 1; // left_on
for(t_count = 0; t_count < period; t_count++){
if(t_count == right_duty) PORTB.F0 = 0; // right off
if(t_count == left_duty ) PORTB.F6 = 0; // left off
delay_us(10);
}
}