研修の講師とかやっていたので、つい何でも演習課題にしてしまうクセがある。(笑
昨日の解答です。
はい、いじったのは配列の中身を倍の10個にして、回しました。
単純と言えば、単純ですけど。
cdeさん、合ってました?
他にも方法があるかと思います。
ただ、この方法はプログラムの構造をいじらずにリソースだけいじっているので
バグになりにくいと言うことです。
では、ついでにこの勢いでナイトライダーを作ってみましょう。
LEDを直線状に並べ替えて、点灯します。
単純に直線的に移動する(三角波?)8状態を並べてみたら、速すぎたので、
データを増やしました。
ただ増やすだけでは芸がないので、正弦波で移動するようにしてみました。
そしたら、変数領域が足りないと言うエラーが出ました。
RAMが41バイトしか無かったのね。orz
で、constを慌てて付けました。
ま、AVRじゃこう簡単にはいかないけど。
ソースコードです。
いかがでしょうか?
これも配列の中をいじっただけです。
繰り返し表示するだけだったら、この方法でプログラムの構造を変えずに
配列の中身だけいじって色々出来ます。
昨日の解答です。
/* * 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;
}
}
}
いかがでしょうか?
これも配列の中をいじっただけです。
繰り返し表示するだけだったら、この方法でプログラムの構造を変えずに
配列の中身だけいじって色々出来ます。
は置いといて、Prescalerもクロックも選択肢が無いなら仕方ないですねぇ。
GPIO = ~led_patt[pat_cnt>>1];
とかだと配列リソース(とキーストローク)も増えずに済むかな、なんちて。
パワフルでリソースも潤沢なマイコンなら何でも出来て当たり前。
だけど、工夫が無い。
ちっちゃいマイコンは、制約が多いからこそ、そこにアイデアが生まれる。