FC2カウンター

現在の訪問者数

現在の閲覧者数:

カレンダー

07 | 2017/08 | 09
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -

プロフィール

剣菱P

Author:剣菱P
剣菱Pと申します。
性別:男
年齢:27
二兎を追って一兎も得られないタイプ

マイコンやプログラミング、ニコニコ動画、雑記等
方向性は見えずとも、ちょっとずつ更新していく予定です!

リンクフリーです。
こんなブログでよかったらよろしくお願いしま~す。

公開メール kenbishiP@gmail.com

検索フォーム

最新記事

最新コメント

カテゴリ

メールフォーム

名前:
メール:
件名:
本文:

月別アーカイブ

最新トラックバック

リンク

ブロとも一覧

ブロとも申請フォーム

ランキング

ランキング参加中です。気が向いたらクリックしてあげてください。


にほんブログ村 その他趣味ブログへ
にほんブログ村 その他趣味ブログ 趣味の工作へ

スポンサーサイト


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

VC++/CLI  シリアル通信 12F683でサーボ»

コメント

コメントの投稿













管理者にだけ表示を許可する

12F683でサーボ 解決編


12F683を使ってサーボを動かすということになったが、
前回あげたようなちょっとした問題が僕を悩ませた

結果たどり着いたのが、タイマー1とCCPのコンペアマッチモード

まずタイマー1

こいつは16bitのカウンターと3bitのプリスケーラを備えた頼もしいやつ

つまりタイマー1は66536カウント可能。
タイマー0の256カウントなんて目じゃないぜ

基本的にはタイマー0と同様の カウントアップカウンタでオーバーフロー時に割り込み発生

次にCCPのコンペアマッチモード
PWMモードはタイマー2と同期していましたが
コンペアマッチモードはタイマー1と同期してます。

タイマー1のカウント値が指定した数値と一致すると特定の動作を実行させることが出来ます。

この二つの機能を合わせて

タイマー1カウント開始 同時に5V出力
CCP1と一致 CCP1割り込み発生 0V出力
カウントは続く
オーバーフロー カウントリセット
タイマー1割り込み発生 5V出力

以下無限ループ

これで求める仕様が実現できます。

まず
4MHzを使った場合から考えて見ます
クロックの4分の1で動くので実質1MHz
このクロックの周期は1μs
1μs × 65536 ≒ 66ms

これは周期20msの約三倍 使えないことはないけど分解能を考えると
クロックを20MHzにしてもいいかも
20MHzなら 実質クロックは5MHz
周期は 0.2μs

0.2μs × 65536 ≒ 13ms
今度は20に届かない けどプリスケーラが3bitついてるので
そこから2倍を選択すれば
13×2 = 26ms 長さ的にはいい感じじゃなかろうか

6msだけ必要な長さより長いのでこれを削ります。
タイマー1は指定した数から数え始めて65536に到達したらオーバーフローを起こすので
20msカウントさせたければ
20ms ÷ (0.2μs × 2) = 50000   (×2はプリスケーラ)

つまり50000カウントすれば20ms経過する

65536 - 50000 = 15536

16進数にすると 0x3CB0
ここから数えれば良いわけです。 このポイントを実質的に0とします。

さて、サーボに必要なのは1~2msのパルス
中心部分は1.5msなので
1.5msの時間を計るには
1.5ms ÷ (0.2μs × 2) = 3750 カウント

タイマー1をカウントし始めてから 3750カウント分の間だけピンから5Vを出力
つまりタイマー1 オーバーフローのタイミングで 5Vを出力し
カウンターの値が

15536 + 3750

と同じになった時にCCPのコンペアマッチ割り込みをかけて 出力を0Vにする命令を実行

その後はタイマー1がカウントを続けてオーバーフローを起こしたらまた再び5Vを出力

プログラムは


#include <12f683.h>
#fuses HS,NOWDT,NOPROTECT,NOMCLR,BROWNOUT
#use delay(clock = 20000000)
#use rs232(BAUD =9600, XMIT = PIN_A1, RCV = PIN_A3)
#define zero_p 15536                    //20msカウントするための始点

#int_timer1                        //タイマー1オーバーフローで
void intval(){                        //出力を5V Highにする
    set_timer1(0x3cb0);
    output_high(PIN_A0);
}

#int_ccp1                            //コンペアマッチ割り込みで
void ccp1_isr(){                        //出力を0V Lowにする
    output_low(PIN_A0);
}   
main()
{
   
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);        //内部クロック使用 プリスケーラ2倍
    setup_ccp1(CCP_COMPARE_INT);        //CCP1コンペアマッチした時の動作
                            //今回はタイマー1リセット以外なら動作します
    CCP_1 = zero_p + 3750;                //サーボに必要な1.5msのパルス幅
    enable_interrupts(INT_TIMER1);            //タイマー1割り込み許可
    enable_interrupts(INT_CCP1);                //CCP割り込み許可
    enable_interrupts(GLOBAL);                //全体割り込み許可
    set_timer1(0x3cb0);                    //20ms計るためのタイマー値
    set_tris_a(0x08);                    //入出力設定
    output_a(0x00);
   
    while(1){
        if(input(PIN_A3)==0){
            CCP_1 = zero_p + 5000;
        }
        else{
            CCP_1 = zero_p + 3750;
        }
    }
}



なんか崩れちゃってますが気にしない方向でw

スイッチを一つ設けて、サーボを動かしています。押してる時2ms 放せば1.5msのパルスを作ります。


クリックしてくれるとうれしいです。
スポンサーサイト

VC++/CLI  シリアル通信 12F683でサーボ»

コメント

コメントの投稿













管理者にだけ表示を許可する


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。