ikkei blog

電子工作やパズルのブログです。主にLEDを使った電子工作をやっています。

「PIC12F509でLEDを回転点滅させてみた」のソースコード その2

2013年05月24日 23時53分09秒 | PIC
研修の講師とかやっていたので、つい何でも演習課題にしてしまうクセがある。(笑
昨日の解答です。


/*
 * 5 LED rotation
 *
 *  Created: 2013/05/19
 *  Author: ikkei
 *  modified: 500ms

 sink output
    GP0--LED1
    GP1--LED2
    GP2--LED3
    GP4--LED4
    GP5--LED5

 */

//#include "pic.h" //MPLAB V8
#include <xc.h>

//__CONFIG(UNPROTECT & MCLRDIS & WDTDIS & INTRC); //MPLAB V8
#pragma config OSC = IntRC  // internal RC oscillator
#pragma config WDT = OFF    // WDT disabled
#pragma config CP = OFF     // Code protection off
#pragma config MCLRE = OFF  // GP3/MCLR pin function is digital input


unsigned char led_patt[] = { 0x01, 0x01, 0x02, 0x02, 0x04, 
                             0x04, 0x10, 0x10, 0x20, 0x20};
unsigned char pat_cnt;

#define STEP 195  // 256us * 195 = 50ms
#define T_STEP 256 - STEP

int main(void) {
    TRIS = 0x00;
    // wake up disable, pull-up enable, clock source internal, prescaler 1/256
    // internal 4MHz -> 1/4 -> 1/256 -> TM0     256us clock
    OPTION = 0x87; 
    TMR0 = T_STEP;
    pat_cnt = 0;
    while(1){
        if (TMR0 == 0){
            TMR0 = T_STEP;
            GPIO = ~led_patt[pat_cnt];
            pat_cnt++;
            pat_cnt %= 10;
        }
    }
}




はい、いじったのは配列の中身を倍の10個にして、回しました。
単純と言えば、単純ですけど。
cdeさん、合ってました?

他にも方法があるかと思います。

ただ、この方法はプログラムの構造をいじらずにリソースだけいじっているので
バグになりにくいと言うことです。



では、ついでにこの勢いでナイトライダーを作ってみましょう。
LEDを直線状に並べ替えて、点灯します。


単純に直線的に移動する(三角波?)8状態を並べてみたら、速すぎたので、
データを増やしました。
ただ増やすだけでは芸がないので、正弦波で移動するようにしてみました。

そしたら、変数領域が足りないと言うエラーが出ました。
RAMが41バイトしか無かったのね。orz
で、constを慌てて付けました。
ま、AVRじゃこう簡単にはいかないけど。

ソースコードです。



/*
* 5 LED rotation
*
* Created: 2013/05/19
* Author: ikkei
* Knight rider

sink output
GP0--LED1
GP1--LED2
GP2--LED3
GP4--LED4
GP5--LED5

*/

//#include "pic.h" //MPLAB V8
#include <xc.h>

//__CONFIG(UNPROTECT & MCLRDIS & WDTDIS & INTRC); //MPLAB V8
#pragma config OSC = IntRC // internal RC oscillator
#pragma config WDT = OFF // WDT disabled
#pragma config CP = OFF // Code protection off
#pragma config MCLRE = OFF // GP3/MCLR pin function is digital input


const unsigned char led_patt[] = { 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x02, 0x04, 0x10, 0x10,
0x20, 0x20, 0x20, 0x20, 0x20,
0x10, 0x10, 0x04, 0x02, 0x02};
unsigned char pat_cnt;

#define STEP 195 // 256us * 195 = 50ms
#define T_STEP 256 - STEP

int main(void) {
TRIS = 0x00;
// wake up disable, pull-up enable, clock source internal, prescaler 1/256
// internal 4MHz -> 1/4 -> 1/256 -> TM0 256us clock
OPTION = 0x87;
TMR0 = T_STEP;
pat_cnt = 0;
while(1){
if (TMR0 == 0){
TMR0 = T_STEP;
GPIO = ~led_patt[pat_cnt];
pat_cnt++;
pat_cnt %= 20;
}
}
}





いかがでしょうか?
これも配列の中をいじっただけです。

繰り返し表示するだけだったら、この方法でプログラムの構造を変えずに
配列の中身だけいじって色々出来ます。




最新の画像もっと見る

2 コメント

コメント日が  古い順  |   新しい順
流石PIC (cde)
2013-05-25 10:02:21
何もできんw

は置いといて、Prescalerもクロックも選択肢が無いなら仕方ないですねぇ。

GPIO = ~led_patt[pat_cnt>>1];
とかだと配列リソース(とキーストローク)も増えずに済むかな、なんちて。
返信する
なるほど (ikkei)
2013-05-25 12:12:29
そう言う手も有りましたね。

パワフルでリソースも潤沢なマイコンなら何でも出来て当たり前。
だけど、工夫が無い。
ちっちゃいマイコンは、制約が多いからこそ、そこにアイデアが生まれる。
返信する

コメントを投稿