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

 ↓ラジコンブログのランキングサイトです。クリックしていただけると嬉しいです!
 にほんブログ村 その他趣味ブログ ラジコンへ
 ↓ブログの解析・ランキングサイトです。クリックしていただけると嬉しいです!
 blogram投票ボタン

ソースを公開します。


とりあえず自分の保存用にブログに載せておきます。もし使いたいと言う方はご自由にどうぞ。ただし、以下の注意点をご理解ください。

注意点
  • 動作確認はしていますが、たまたま動いているだけかもしれません。
  • まったくエレガントではないコードです。これは私の技術力不足が大きいのですが、「12F509をターゲットにしている」のと、Hi-Tech社の古いフリーのコンパイラ(PICC LITE V9.6)を利用している」のも原因の一部です。もし改造される場合には、スタックは2段、ユーザ作成関数をインライン化できないなどさまざまな制限がありますので、12F509のデータシートとコンパイラのマニュアルをチェックする事をおすすめします。
  • 動作確認を行いながらNOPの回数などを調整しましたので、様々な値は即値になっています。
  • MPLAB IDEでプロジェクトを作ってビルドしていますので、ソース中に対象PICを限定する定義(”defined(_12F509)”等)はありません。
  • 残光調整はあまり細かくしても人間の目にはわかりませんので適当です。


なお、ソースは残光2つと残光1つの2バージョンあります。また、全LEDのフラッシュ処理も3パターンに増やしてあります。動作は以下の動画で確認してみてください。


●残光2つのバージョン
/**************************************************************
for Hi-Tech PICC-Lite 9.60
12F509でナイトライダー(LED5つ)+α(定期的に全LEDフラッシュ)
全体のLEDが5つで残光が2つのバージョン
2009/11/07 ozpapa
**************************************************************/
#include <pic.h>

//INTRC GPIO ,WTIMER DIS,PWRUPTIMER DIS,MCLR INT,BOD DIS
//#define MCLRDIS        0xFEF    // master clear reset disable
//#define WDTDIS        0xFFB    // watchdog timer disable
//#define INTRC        0xFFE    // internal
__CONFIG( MCLRDIS & WDTDIS & INTRC);

// 0000 1000
#define LED_ALL_OFF 0x08
// 0011 1111
#define LED_ALL_ON 0x3F

#define FLASH_COUNT        5
#define TAIL_COUNT        3

// 以下のマクロを使う場合には呼び出し側でMyCnt(int)を定義しておく。
//#define WAIT_C( Cnt) for( MyCnt=Cnt*10; MyCnt--; MyCnt) asm( "nop");

// NOPによるウェイトルーチン
// wait_C,wait_C2,WAIT_Cは同じようにCnt*10ウェイトするが、関数コールかどうかや、ループの
// 段数により時間が微妙に変わるので、最適なものを利用すればよい。
void wait_C2(int Cnt)
{
    int MyCnt;
    for( MyCnt=Cnt*10; MyCnt--; MyCnt)
    {
        asm( "nop");
    }
}
void wait_C(int Cnt)
{
    int MyCnt;
    int MyCnt2;
    for( MyCnt2=10; MyCnt2--; MyCnt2)
    {
        for( MyCnt=Cnt; MyCnt--; MyCnt)
        {
            asm( "nop");
        }
    }
}
// KnightRider処理
// ビットパターンで指定された3つのLED(メインのLED、1つ前のLED、2つ前のLED)を点灯
// させる。デューティー比を変えて、メインのLEDは徐々に明るく、1つ前と2つ前のLEDは徐々に暗く
// する事で残光効果を作り出している。デューティー比は以下のように変えている(つもり)。
// メイン 1つ前 2つ前
// 50%  50%  30%
// 60%  40%  20%
// 70%  30%  10%
// 80%  20%   0%
// 90%  10%   0%
void kr_Do(char p1, char p2, char p3)
{
    int MyCnt;
    // 50 50 30
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1 ;
        wait_C( 50);
        GPIO = p2 | p3;
        wait_C( 30);
        GPIO = p2;
        wait_C( 20);
    }
    // 60 40 20
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1;
        wait_C( 60);
        GPIO = p2 | p3;
        wait_C( 20);

        GPIO = p2;
        wait_C( 20);
    }
    // 70 30 10
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1;
        wait_C( 70);
        GPIO = p2 | p3;
        wait_C( 10);

        GPIO = p2;
        wait_C( 20);
    }
    // 80 20 0
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1;
        wait_C( 80);
        GPIO = p2 | p3;
        wait_C( 0);

        GPIO = p2;
        wait_C( 20);
    }
    // 90 10 0
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1;
        wait_C( 90);
        GPIO = p2 | p3;
        wait_C( 0);

        GPIO = p2;
        wait_C( 10);
    }

    return;

}

void kr(void)
{
    kr_Do( 0b00000010, 0b00000001, 0b00000001);
    kr_Do( 0b00000100, 0b00000010, 0b00000001);
    kr_Do( 0b00010000, 0b00000100, 0b00000010);
    kr_Do( 0b00100000, 0b00010000, 0b00000100);
    kr_Do( 0b00010000, 0b00100000, 0b00100000);
    kr_Do( 0b00000100, 0b00010000, 0b00100000);
    kr_Do( 0b00000010, 0b00000100, 0b00010000);
    kr_Do( 0b00000001, 0b00000010, 0b00000100);

    return;
}

// 全LEDフラッシュ
void flash_all_led( void)
{
    int i;
    for(i=FLASH_COUNT; i--; i)
    {
        GPIO = LED_ALL_OFF;
        wait_C(500);
        GPIO = LED_ALL_ON;
        wait_C(2000);
    }
    GPIO = LED_ALL_OFF;
    return;
}

// 全LED高速フラッシュ
void flash_all_led2( void)
{
    int i;
    for(i=FLASH_COUNT; i--; i)
    {
        GPIO = LED_ALL_OFF;
        wait_C(200);
        GPIO = LED_ALL_ON;
        wait_C(600);
        GPIO = LED_ALL_OFF;
        wait_C(200);
        GPIO = LED_ALL_ON;
        wait_C(600);
        GPIO = LED_ALL_OFF;
        wait_C(200);
        GPIO = LED_ALL_ON;
        wait_C(600);
    }
    GPIO = LED_ALL_OFF;
    return;
}

// LEDが3つずつ交互フラッシュ
void flash_all_led3( void)
{
    int i;
    for(i=FLASH_COUNT; i--; i)
    {
        GPIO = LED_ALL_OFF;
        wait_C(150);
        GPIO = 0b00000111;
        wait_C(500);
        GPIO = LED_ALL_OFF;
        wait_C(150);
        GPIO = 0b00000111;
        wait_C(500);
        GPIO = LED_ALL_OFF;
        wait_C(150);
        GPIO = 0b001110000;
        wait_C(500);
        GPIO = LED_ALL_OFF;
        wait_C(150);
        GPIO = 0b001110000;
        wait_C(500);
    }
    GPIO = LED_ALL_OFF;
    return;
}

void main()
{

    // GP2は外部クロック用ポートと兼用なので外部クロック用に利用しない指定をする。
    // →本来なら特定ビット(T0CS)をOFFすれば良さそうだが、他のビットの意味がわから
    //   ないのでとりあえず全ビットクリア
    OPTION = 0;
    // 全ポートを出力に指定(GP3は入力専用だが、今回は使わないので気にせず0クリア)
    TRIS = 0;
    // 全LED消灯
    GPIO = LED_ALL_OFF;
    while (1)
    {
        // ナイトライダー動作(5回)
        kr();
        kr();
        kr();
        kr();
        kr();

        // 全LEDフラッシュ(1回)
        flash_all_led();

        // ナイトライダー動作(5回)
        kr();
        kr();
        kr();
        kr();
        kr();

        // 全LED高速フラッシュ(1回)
        flash_all_led2();

        // ナイトライダー動作(5回)
        kr();
        kr();
        kr();
        kr();
        kr();

        // LEDが3つずつ交互フラッシュ(1回)
        flash_all_led3();
    }
}



●残光1つのバージョン
/**************************************************************
for Hi-Tech PICC-Lite 9.60
12F509でナイトライダー(LED5つ)+α(定期的に全LEDフラッシュ)
全体のLEDが5つで残光が1つのバージョン
2009/11/07 ozpapa
**************************************************************/
#include <pic.h>

//INTRC GPIO ,WTIMER DIS,PWRUPTIMER DIS,MCLR INT,BOD DIS
//#define MCLRDIS        0xFEF    // master clear reset disable
//#define WDTDIS        0xFFB    // watchdog timer disable
//#define INTRC        0xFFE    // internal
__CONFIG( MCLRDIS & WDTDIS & INTRC);

// 0000 1000
#define LED_ALL_OFF 0x08
// 0011 1111
#define LED_ALL_ON 0x3F

#define FLASH_COUNT        5
#define TAIL_COUNT        3

// 以下のマクロを使う場合には呼び出し側でMyCnt(int)を定義しておく。
//#define WAIT_C( Cnt) for( MyCnt=Cnt*10; MyCnt--; MyCnt) asm( "nop");

// NOPによるウェイトルーチン
// wait_C,wait_C2,WAIT_Cは同じようにCnt*10ウェイトするが、関数コールかどうかや、ループの
// 段数により時間が微妙に変わるので、最適なものを利用すればよい。
void wait_C2(int Cnt)
{
    int MyCnt;
    for( MyCnt=Cnt*10; MyCnt--; MyCnt)
    {
        asm( "nop");
    }
}
void wait_C(int Cnt)
{
    int MyCnt;
    int MyCnt2;
    for( MyCnt2=10; MyCnt2--; MyCnt2)
    {
        for( MyCnt=Cnt; MyCnt--; MyCnt)
        {
            asm( "nop");
        }
    }
}
// KnightRider処理
// ビットパターンで指定された2つのLED(メインのLED、1つ前のLED)を点灯
// させる。デューティー比を変えて、メインのLEDは徐々に明るく、1つ前のLEDは徐々に暗く
// する事で残光効果を作り出している。デューティー比は以下のように変えている(つもり)。
// メイン 1つ前
// 60%  40%
// 70%  30%
// 80%  20%
// 90%  10%
// 100%  0%
void kr_Do(char p1, char p2)
{
    int MyCnt;
    // 60 40
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1 ;
        wait_C( 60);
        GPIO = p1 | p2;
        wait_C( 0);
        GPIO = p2;
        wait_C( 40);
    }
    // 70 30
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1;
        wait_C( 70);
        GPIO = p1 | p2;
        wait_C( 0);

        GPIO = p2;
        wait_C( 30);
    }
    // 80 20
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1;
        wait_C( 80);
        GPIO = p1 | p2;
        wait_C( 0);

        GPIO = p2;
        wait_C( 20);
    }
    // 90 10
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1;
        wait_C( 90);
        GPIO = p1 | p2;
        wait_C( 0);

        GPIO = p2;
        wait_C( 10);
    }
    // 100 0
    for( MyCnt=TAIL_COUNT; MyCnt--; MyCnt)
    {
        GPIO = p1;
        wait_C( 100);
        GPIO = p1 | p2;
        wait_C( 0);

        GPIO = p2;
        wait_C( 0);
    }

    return;

}

void kr(void)
{
    kr_Do( 0b00000010, 0b00000001);
    kr_Do( 0b00000100, 0b00000010);
    kr_Do( 0b00010000, 0b00000100);
    kr_Do( 0b00100000, 0b00010000);
    kr_Do( 0b00010000, 0b00100000);
    kr_Do( 0b00000100, 0b00010000);
    kr_Do( 0b00000010, 0b00000100);
    kr_Do( 0b00000001, 0b00000010);

    return;
}

// 全LEDフラッシュ
void flash_all_led( void)
{
    int i;
    for(i=FLASH_COUNT; i--; i)
    {
        GPIO = LED_ALL_OFF;
        wait_C(500);
        GPIO = LED_ALL_ON;
        wait_C(2000);
    }
    GPIO = LED_ALL_OFF;
    return;
}

// 全LED高速フラッシュ
void flash_all_led2( void)
{
    int i;
    for(i=FLASH_COUNT; i--; i)
    {
        GPIO = LED_ALL_OFF;
        wait_C(200);
        GPIO = LED_ALL_ON;
        wait_C(600);
        GPIO = LED_ALL_OFF;
        wait_C(200);
        GPIO = LED_ALL_ON;
        wait_C(600);
        GPIO = LED_ALL_OFF;
        wait_C(200);
        GPIO = LED_ALL_ON;
        wait_C(600);
    }
    GPIO = LED_ALL_OFF;
    return;
}

// LEDが3つずつ交互フラッシュ
void flash_all_led3( void)
{
    int i;
    for(i=FLASH_COUNT; i--; i)
    {
        GPIO = LED_ALL_OFF;
        wait_C(150);
        GPIO = 0b00000111;
        wait_C(500);
        GPIO = LED_ALL_OFF;
        wait_C(150);
        GPIO = 0b00000111;
        wait_C(500);
        GPIO = LED_ALL_OFF;
        wait_C(150);
        GPIO = 0b001110000;
        wait_C(500);
        GPIO = LED_ALL_OFF;
        wait_C(150);
        GPIO = 0b001110000;
        wait_C(500);
    }
    GPIO = LED_ALL_OFF;
    return;
}

void main()
{

    // GP2は外部クロック用ポートと兼用なので外部クロック用に利用しない指定をする。
    // →本来なら特定ビット(T0CS)をOFFすれば良さそうだが、他のビットの意味がわから
    //   ないのでとりあえず全ビットクリア
    OPTION = 0;
    // 全ポートを出力に指定(GP3は入力専用だが、今回は使わないので気にせず0クリア)
    TRIS = 0;
    // 全LED消灯
    GPIO = LED_ALL_OFF;
    while (1)
    {
        // ナイトライダー動作(5回)
        kr();
        kr();
        kr();
        kr();
        kr();

        // 全LEDフラッシュ(1回)
        flash_all_led();

        // ナイトライダー動作(5回)
        kr();
        kr();
        kr();
        kr();
        kr();

        // 全LED高速フラッシュ(1回)
        flash_all_led2();

        // ナイトライダー動作(5回)
        kr();
        kr();
        kr();
        kr();
        kr();

        // LEDが3つずつ交互フラッシュ(1回)
        flash_all_led3();
    }
}




さっ、明日の準備明日の準備!

以上
スポンサーサイト

 ↓ラジコンブログのランキングサイトです。クリックしていただけると嬉しいです!
 にほんブログ村 その他趣味ブログ ラジコンへ
 ↓ブログの解析・ランキングサイトです。クリックしていただけると嬉しいです!
 blogram投票ボタン

Comment

  1. ただいま「非公開コメント」も受付中です。
  2. 好みは

    2009/11/08(Sun) 01:44優駿ぱぱ [ URL|Mail ]

    ozpapaさんこんばんは。
    自分の好みは残光2の方ですね。
    なんとなくですけど(笑)

  3. Re: 好みは

    2009/11/08(Sun) 20:27ozpapa [ URL|Mail ]

    優駿ぱぱさん、こんばんは。いつもコメントありがとうございます!

    > 自分の好みは残光2の方ですね。
    > なんとなくですけど(笑)
    そうですね、残光2の方がよりナイトライダーぽくて良いなと私も思います。LEDを10個くらいに増やすと残光2(あるいはそれ以上)がもっといきてくると思います。今回使ったPIC12F509は出力ポートが5つなのでLEDを5つにしましたが、そのうちにもうちょっと出力ポートの多いPICでも作ってみたいなと思います。

    以上

Comment Form


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

プロフィール

ozpapa

Author:ozpapa
ようやく通える場所にできたサーキットが閉鎖。今は、息子とMさん親子の4人で、近所の広場でドリフト&Mシャーシです。

検索フォーム

アクセスカウンター(2010/03/08~)

ブロとも申請フォーム

QRコード

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