閲覧総計:11792  (本日:1  昨日:0)


自作my_PWM()関数の紹介

左右2輪駆動の自動車を前後左右に自在にPWM制御しようとする際、PWM出力
が4つ必要となる。PIC16F628Aはハード組み込みのPWM出力を1つしか持っておらず
このニーズを満足しない。

その為、モータをソフトウエアPWM制御する関数を自作し利用している。 06/11/12

モータ駆動の為の自作PWM関数
void my_PWM_RB2(unsigned short int duty);
void my_PWM_RB3(unsigned short int duty);
void my_PWM_RB4(unsigned short int duty);
void my_PWM_RB5(unsigned short int duty);

P1010201.JPGP1010203.JPG
/**
* my_PWM関数
* 自動車を前後・左右に自在に制御する
*
* PIC 16F628A
* 発信器 4MHz
* 言語 MikroC v2.1
* Device Flags: _BODEN_OFF _BOREN_OFF _CP_OFF _PWRTE_ON
*     _WDT_OFF _LVP_OFF _MCLRE_OFF _INTRC_OSC_NOCLKOUT
*
* モータ 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 2,3:モータ右
* PortB 5,4:モータ左
* 電源:PIC:電池4本 モータ:電池3本
*/

//関数プロトタイプ宣言
void my_PWM_RB2(unsigned short int duty);
void my_PWM_RB3(unsigned short int duty);
void my_PWM_RB4(unsigned short int duty);
void my_PWM_RB5(unsigned short int duty);

void main(){
    unsigned int i;
    unsigned int pause = 1000; //待機時間1秒

    //ポートの初期化
    PORTB = 0b00000000;
    //入出力の設定 1:input  0:output
    TRISB = 0b00000000; //PORTB 8ヶ全て出力に設定

    //LED点灯
    PORTB = 0b11111111;
    Delay_ms(1000);
    PORTB = 0b00000000;

    do {
        for(i = 0; i < 500; i++) { //5秒継続
            my_PWM_RB2(99); //99%右前進
            my_PWM_RB5(97); //97%左前進
        }

        for(i = 0; i < 500; i++) { //5秒継続
            my_PWM_RB3(99); //99%右後進
            my_PWM_RB4(97); //97%左後進
        }

        for(i = 0; i < 500; i++) { //5秒継続
            my_PWM_RB2(99); //99%右前進
            my_PWM_RB5(60); //60%左前進
        }

        for(i = 0; i < 500; i++) { //5秒継続
            my_PWM_RB3(70); //70%右後進
            my_PWM_RB4(90); //90%左後進・
        }

        PORTB = 0b00000000; //停止
        Vdelay_ms(pause); //待機
    } while(1);
}


/**
* my_PWM_RB2()  機能:RB2の出力を0%-100%で制御する
*
* duty:範囲 0-100
* 100ループで約1秒 @4MHz
*/
void my_PWM_RB2(unsigned short int duty) {
    unsigned short int period = 100; //PWM分解能
    unsigned short int t_count;

    PORTB.F2 = 1; //ON
    for(t_count = 0; t_count < period; t_count++){
        if(t_count > duty - 1){
            PORTB.F2 = 0; //OFF
        }
        delay_us(10);
    }
}

void my_PWM_RB3(unsigned short int duty) {
    unsigned short int period = 100; //PWM分解能
    unsigned short int t_count;

    PORTB.F3 = 1; //ON
    for(t_count = 0; t_count < period; t_count++){
        if(t_count > duty - 1){
            PORTB.F3 = 0; //OFF
        }
        delay_us(10);
    }
}

void my_PWM_RB4(unsigned short int duty) {
    unsigned short int period = 100; //PWM分解能
    unsigned short int t_count;

    PORTB.F4 = 1; //ON
    for(t_count = 0; t_count < period; t_count++){
        if(t_count > duty - 1){
            PORTB.F4 = 0; //OFF
        }
        delay_us(10);
    }
}

void my_PWM_RB5(unsigned short int duty) {
    unsigned short int period = 100; //PWM分解能
    unsigned short int t_count;

    PORTB.F5 = 1; //ON
    for(t_count = 0; t_count < period; t_count++){
        if(t_count > duty - 1){
            PORTB.F5 = 0; //OFF
        }
        delay_us(10);
    }
}

★この情報は役に立ちましたか?

選択肢 投票
はい 7  
いいえ 25  
  • この自作my_PWM()関数に不備があるとのご意見を、07/1/24 09:41:35に後関先生管理の
    「PIC初心者掲示板」に頂きました。
    http://www.picfun.com/freecgi/TreeBBS/index.cgi?bid=1&tnum=266&page=2
    このプログラムでは「同時出力でなく交互出力でduty:100未満は実際半分のdutyになって
    しまうになってしまうみたいですが、一工夫すれば同時出力になるでしょう。」
    とのアドバイスです。
    この事が07/02/02現在「この情報は役に立たない2票」の投票結果となっているのではと考えます。
    お恥ずかしい話、私には上記アドバイスの内容が理解できず、解決の方法も分かりません。
    本件お分かりになられる方がおられましたら更なるアドバイスを頂けると助かります。
    よろしくお願い申し上げます。 -- PICとMikroC 2007-02-02 (金) 05:53:14



  • PWM_RB2_RB3_RB4_RB5(90,0,0,50); みたいに同時出力関数を作れば解決 -- PWM? 2007-02-07 (水) 12:34:52