![]()
| 以前に作ったサンプルプログラム(初期タイプ)は流れそのままで、同じ繰り返しなど無駄な部分が多かったので、ようやく見直しをして改良しました。「関数を使用したタイプ」と「関数と配列を使用したタイプ」の2つです。 ライン数と使用メモリの節約ができました。省略できる箇所もまだありますが、あまり省略すると自分で作ったプログラムの中身がわからなくなるのでやめました。(しっかりしたコメントとフローチャートを作らないのが原因のようですが・・・) |
| サンプルプログラム比較表 | |||||
| 番号 | プログラム名 | タイプ | 使用ライン数[行] (コメント文を除く) |
使用メモリ [byte] |
使用メモリの比率 (初期型を100とした時) |
| 1 | bon_ir20 | 初期タイプ | 131 | 316 | 100 |
| 2 | bon_ss~3 | 関数使用タイプ | 85 | 221 | 70 |
| 3 | bon_ss~4 | 関数+配列使用タイプ | 60 | 180 | 57 |
*使用ライン数は表記の仕方で変わるのであまり当てになりませんが、使用メモリには、改良の成果が表れています。 |
| サンプルプログラム(関数使用タイプ) |
//******************************************************************************
//* bon_ss~3 スタートビット検出+リモコンデータ検出 *
//* SONYリモコンを押すと梵天丸移動 *
//******************************************************************************
#include <16f84a.h> // 使用デバイスの定義情報をインクルードする。
#fuses HS, NOWDT, NOPROTECT // コンフィグレーションの設定(HSモード,WDTなし,プロテクトなし)
#use delay (clock=8000000) // 梵天丸の発振子の周波数8MHz 時間待ち関数(delay)の設定
//-----------------------------------------------------------------------------
// I/Oポートの定義
//-----------------------------------------------------------------------------
#byte RA = 5 // ポートAのアドレス5番地をRA:文字変数に設定する。
#byte RB = 6 // ポートBのアドレス6番地をRB:文字変数に設定する。
#bit start_bit = RA.4 // 赤外線の入力ポートRA4をstart_bit:文字変数に設定する。
//-----------------------------------------------------------------------------
// サブルーチン関数
//-----------------------------------------------------------------------------
func(byte cnt)
{
byte i;
cnt = 0;
for (i=1;i<=10;i++) // 10回サンプリング
{
delay_us(110); // 110μs×10=1100μsのうちに
if (input(PIN_A4)==0) // RA4の"L"レベルの回数を検出
cnt = cnt + 1; // 検出の場合 cnt値+1
else
cnt = cnt + 0; // 未検出の場合 cnt値+0
}
return cnt;
}
//-----------------------------------------------------------------------------
// メイン関数
//-----------------------------------------------------------------------------
main(){
byte flag, cnt, i, j, k; // byte型変数(符号なし8ビット)
byte data1, data2, data3, data4, data5, data6, data7, data8, data9;
byte rcv, rcv1;
set_tris_a(0x10); // ポートAはRA4のみ入力に設定(1:Input)他は出力に設定(0:Output)
set_tris_b(0xff); // ポートBはすべて入力に設定(1:Input)
data1 = 0x01; // 前左 パターン 0000 0001 モータ動作データ
data2 = 0x03; // 前進 パターン 0000 0011 リモコンのボタンとdataの番号が対応
data3 = 0x02; // 前右 パターン 0000 0010 下位4ビットが
data4 = 0x09; // 左転 パターン 0000 1001 (MSB)左逆転
data5 = 0x00; // 停止 パターン 0000 0000 右逆転
data6 = 0x06; // 右転 パターン 0000 0110 左正転
data7 = 0x04; // 後左 パターン 0000 0100 (LSB)右正転
data8 = 0x0c; // 後進 パターン 0000 1100
data9 = 0x08; // 後右 パターン 0000 1000
RA = 0x00; // 電源オン時、モータを停止状態にしておく
while(1){
while(start_bit!=0) {} // スタートビットが入力されるまで待つ
flag = 0;
for (i=1;i<=5;i++) // スタートビット検出
{ // 500μs×5=2500μsのうちに
delay_us(500); // RA4の"L"レベルの回数を検出
if (input(PIN_A4)==0)
flag = flag + 1;
}
if (flag >=4) // 4回以上検出した場合は
{
delay_us(300);
rcv = 0;
for ( j = 1 ; j < 5; j++ ) // データを4ビット分、検出する
{
cnt = func(cnt);
if (cnt >=8) // cnt値が8以上の場合
{
delay_us(600); // 次のデータビットまで待機
for (k = 1, rcv1=1; k < j; k++ )// ループ回数のカウント
rcv1 = rcv1 * 2; // データ重み付け
rcv = rcv + rcv1; // リモコンデータ検出結果の加算
}
}
}
switch(rcv) // リモコンデータ検出結果
{
case 0 : RA = data1; // リモコンボタン"1" 押す 前左
break;
case 1 : RA = data2; // リモコンボタン"2"押す 前進
break;
case 2 : RA = data3; // リモコンボタン"3"押す 前右
break;
case 3 : RA = data4; // リモコンボタン"4"押す 前左
break;
case 4 : RA = data5; // リモコンボタン"5"押す 前左
break;
case 5 : RA = data6; // リモコンボタン"6"押す 前左
break;
case 6 : RA = data7; // リモコンボタン"7"押す 前左
break;
case 7 : RA = data8; // リモコンボタン"8"押す 前左
break;
case 8 : RA = data9; // リモコンボタン"9"押す 前左
break;
}
delay_ms(100); // 3連送データの2,3回目をキャンセルする
} // 無限ループで繰り返し
}
|
| サンプルプログラム(関数+配列使用タイプ) |
//******************************************************************************
//* bon_ss~4 スタートビット検出+リモコンデータ検出 *
//* SONYリモコンを押すと梵天丸移動 *
//******************************************************************************
#include <16f84a.h> // 使用デバイスの定義情報をインクルードする。
#fuses HS, NOWDT, NOPROTECT // コンフィグレーションの設定(HSモード,WDTなし,プロテクトなし)
#use delay (clock=8000000) // 梵天丸の発振子の周波数8MHz 時間待ち関数(delay)の設定
//-----------------------------------------------------------------------------
// I/Oポートの定義
//-----------------------------------------------------------------------------
#byte RA = 5 // ポートAのアドレス5番地をRA:文字変数に設定する。
#byte RB = 6 // ポートBのアドレス6番地をRB:文字変数に設定する。
#bit start_bit = RA.4 // 赤外線の入力ポートRA4をstart_bit:文字変数に設定する。
//-----------------------------------------------------------------------------
// サブルーチン(ビット判定関数)
//-----------------------------------------------------------------------------
func(byte cnt) // ビット判定
{
byte i;
cnt = 0;
for (i=1;i<=10;i++) // 10回サンプリング
{
delay_us(110); // 110μs×10=1100μsのうちに
if (input(PIN_A4)==0) // RA4の"L"レベルの回数を検出
cnt = cnt + 1; // 検出の場合 cnt値+1
else
cnt = cnt + 0; // 未検出の場合 cnt値+0
}
return cnt;
}
//-----------------------------------------------------------------------------
// メイン関数
//-----------------------------------------------------------------------------
main(){
byte data[9] = { // モータ動作データ
0x01, 0x03, 0x02 // 左、 前進、右
0x09, 0x00, 0x06 // 左回転、停止、右回転
0x04, 0x0c, 0x08 // 左後ろ、後進、右後ろ
};
byte flag, cnt, i, j, k; // byte型変数(符号なし8ビット)
byte rcv, rcv1;
set_tris_a(0x10); // ポートAはRA4のみ入力に設定(1:Input)他は出力に設定(0:Output)
set_tris_b(0xff); // ポートBはすべて入力に設定(1:Input)
RA = 0x00; // 電源オン時、モータを停止状態にしておく
while(1){
while(start_bit!=0) {} // スタートビットが入力されるまで待つ
flag = 0;
for (i=1;i<=5;i++) // スタートビット検出
{ // 500μs×5=2500μsのうちに
delay_us(500); // RA4の"L"レベルの回数を検出
if (input(PIN_A4)==0)
flag = flag + 1;
}
if (flag >=4) // 4回以上検出した場合
{
delay_us(300);
rcv = 0;
for ( j = 1 ; j < 5; j++ ) // データを4ビット分、検出する
{
cnt = func(cnt); // ビット判定サブルーチンへ
if (cnt >=8) // cnt値が8以上の場合
{
delay_us(600); // 次のデータビットまで待機
for (k = 1, rcv1=1; k < j; k++ )// ループ回数のカウント
rcv1 = rcv1 * 2; // データ重み付け
rcv = rcv + rcv1; // リモコンデータ検出結果の加算
}
}
}
RA = data[rcv]; // リモコンデータ検出結果をモータ動作としてへ出力
delay_ms(100); // 3連送データの2,3回目をキャンセルする
} // 無限ループで繰り返し
}
|
平成16年5月23日作成