« R8C/TinyマイコンでLED2個の調光ができた | トップページ | 玄人志向のCF-IDE変換基板 »

2007/05/03

R8C/TinyマイコンでRCサーボモータが動いた

MB-R8CQマイコン基板の続きです。

タイマーCの出力でRCのサーボモータを動作させようと思ったのですが,オシロスコープで観察すると,出力の許可,禁止を切り替えるときにスパイクノイズが発生することが判明しました。それで,いろいろプログラムをいじってみたのですが,取り除くことができませんでした。

そこで,ハードウェアによる出力は諦め,TM0とTM1で割り込みを発生させ,割り込みプログラムの中でポート出力をソフト的に書き換えることにしました。

tcoutの行は不要なので削除しました。A/D変換を2ms間隔で10回行いその平均値を使用しています。設定値は時間(μs)の2.5倍ですので10/4ということで総和を4で割っています。

#define NEUTRAL 3750
int count_ch = 0;
int data[2][10] = {{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0}};
void set_TimerCOutCmp(void)
{
pd1_0 = 1;    // P1_0 for Output
p1_0  = 0;    // P1_0 Output L
pd1_1 = 1;    // P1_1 for Output
p1_1  = 0;    // P1_1 Output L
tcc0  = TC_SOURCE_F8; // Counter C Clock 20MHz/8 = 2.5MHz
tcc1  = TC_CMP1_H | TC_CMP0_L | TC_MODE_OUTC | TC_RELD_CMP1;
tm0 = NEUTRAL;   // default pulse width 1.5ms
tm1 = 5000;    // Interval 2ms
}
void set_CMP0IC(void)
{
ilvl0_cmp0ic = 1;  // Level 7
ilvl1_cmp0ic = 1;
ilvl2_cmp0ic = 1;
ir_cmp0ic = 1;   // Enable Interrupt
}
void set_CMP1IC(void)
{
ilvl0_cmp1ic = 1;  // Level 7
ilvl1_cmp1ic = 1;
ilvl2_cmp1ic = 1;
ir_cmp1ic = 1;   // Enable Interrupt
}
// コンペア0割り込み
#pragma interrupt timerC0_int (vect=28) void timerC0_int(void)
{
    int ad_data;
    int i;     switch (count_ch) {
    case 0:
        p1_0  = 0;   // P1_0 Output L
        count_ch = 1;
        ad_data = 0;
        for (i = 0; i < MAX_CH; i++) {
            ad_data += data[1][i];
        }
        ad_data = NEUTRAL + ad_data / 4;
        break;
    case 1:
        p1_1  = 0;   // P1_1 Output L
        count_ch = 2;
        ad_data = NEUTRAL;
        break;
    case 9:
        count_ch = 0;
        ad_data = 0;
        for (i = 0; i < MAX_CH; i++) {
            ad_data += data[0][i];
        }
        ad_data = NEUTRAL + ad_data / 4;
        break;
    default:
        count_ch++;
        ad_data = NEUTRAL;
        break;
    }
    tm0 = (ad_data <= 4900) ? ad_data : 4900;
} // コンペア1割り込み
#pragma interrupt timerC1_int (vect=16) void timerC1_int(void)
{
    int ad_data;     switch (count_ch) {
    case 0:
        p1_0  = 1;   // P1_0 Output H
        break;
    case 1:
        p1_1  = 1;   // P1_1 Output H
        break;
    default:
        break;
    }
    data[0][count_ch] = get_ADch(AD_AN10) - 512;
    data[1][count_ch] = get_ADch(AD_AN11) - 512;
}

この方法なら,ポートはタイマーCと関係ないので,元のピンアサインでも問題なかったです。作った後でR8C/Tinyをキーワードにして検索していたら,R8C/Tinyを使用した10軸ラジコンサーボコントローラーというページを見つけました。シリアルポートを利用してコマンドを送り,RCサーボをドライブしているようです。10個というのはすごいですね。私のはA/D変換器が4chしかありませんので,1対1であれば上限は4個という事になります。

ボリュームの代わりにRC送信機で使用しているジョイスティックを使用すると,角度が±30°程度ですから,300°の1/5ということで,電圧が2.5V±0.5Vしか変化しません。これをFS5Vの10ビットでA/D変換すると分解能が約200。分解能をあげるためにOPアンプで増幅しようかと思いましたが,10回の平均値を使用しているので,まずは,それで分解能が足りるかどうか試してみることにしました。

|

« R8C/TinyマイコンでLED2個の調光ができた | トップページ | 玄人志向のCF-IDE変換基板 »

プログラミング」カテゴリの記事

電子工作」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: R8C/TinyマイコンでRCサーボモータが動いた:

« R8C/TinyマイコンでLED2個の調光ができた | トップページ | 玄人志向のCF-IDE変換基板 »