電電高専生日記

8ピンPICで順番記憶ゲーム

2015/07/16 23:27

概要

8ピンPIC(12F683)を用いて、順番記憶ゲームを作りました。
のLEDとスイッチが3つずつあり、LEDがランダムに1つずつN回点滅します。その順番を覚えて、対応した色のスイッチを順番通りに押す、というゲームです。正しく入力出来たら次はN+1回に挑戦。間違えたら終了。

回路

特別複雑な作りにはしてないので回路図は省略。GP0,1,2を出力端子、GP3,4,5を入力端子として設定してます。
入力は、スイッチが押されている時のみ接地されてLレベル、離されている時はHレベルとなるようにしてます。入力を解放しておくと不安定になるからです。あと電源スイッチぽいもの付けました。

プログラム

全部main関数に突っ込んでやった。
そして正直プログラム考えるの苦心しました。特に、rand関数でLED点滅の順番をランダムにしようとしても、電源を切ってまた付けると、同じ順番となってしまうのには悩みました。これは、入力待ちのwhileループ中でrand()を繰り返すことで解決しました。しかしこれだと1回目の出力が毎回同じになってしまいますが、それは諦めました。

#include <htc.h>
__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON 
& BOREN_ON & MCLRE_OFF & CP_OFF & IESO_OFF & FCMEN_OFF);
#define _XTAL_FREQ 1000000
#define MAX_ORDER 10  //最大の点滅数

void main()
{
	OSCCON = 0x40;
	ANSEL = 0;
	CMCON0 = 0x07;
	TRISIO = 0x38;	//GP0,1,2を出力 GP3,4,5を入力
	
	short count=3;	//点滅する数N 初期値は3
	short i,outGP,flag,GAME=1;
	short order[MAX_ORDER];

	while (1){
		GP0=GP1=GP2=0;
		__delay_ms(2000);
		//表示出力
		for (i=0; i<count; i++){
			outGP=rand()%3;
			order[i]=outGP;
			if (outGP==0)	GP0=1;
			if (outGP==1)	GP1=1;
			if (outGP==2)	GP2=1;
			__delay_ms(600);
			GP0=GP1=GP2=0;
			__delay_ms(150);
		}
		//入力
		for (i=0; i<count; i++){
			while (1){
				rand();
				if (order[i]==0 && GP3==0 && GP4==1 && GP5==1){	//3番押して正解
					GP0=1;
					__delay_ms(200);	//チャタリング防止
					GP0=0;
					flag=1;
					break;
				}
				if (order[i]==1 && GP3==1 && GP4==0 && GP5==1){ //4番押して正解
					GP1=1;
					__delay_ms(200);	//チャタリング防止
					GP1=0;
					flag=1;
					break;
				}
				if (order[i]==2 && GP3==1 && GP4==1 && GP5==0){ //5番押して正解
					GP2=1;
					__delay_ms(200);	//チャタリング防止
					GP2=0;
					flag=1;
					break;
				}
				if (order[i]!=0 && GP3==0 && GP4==1 && GP5==1){ //3番押して不正解
					flag=0;
					break;
				}
				if (order[i]!=1 && GP3==1 && GP4==0 && GP5==1){ //4番押して不正解
					flag=0;
					break;
				}
				if (order[i]!=2 && GP3==1 && GP4==1 && GP5==0){ //5番押して不正解
					flag=0;
					break;
				}
			}
			if (flag==0){
				for (i=0; i<5; i++){
					GP0=GP1=GP2=1;
					__delay_ms(250);
					GP0=GP1=GP2=0;
					__delay_ms(100);
				}
				GAME=0;
				break;	
			}
		}
		if (GAME==1){	//正解した場合
			if (count==MAX_ORDER){	//ゲームクリア
				while(1){
					GP0=0;
					GP1=0;
					GP2=1;
					__delay_ms(150);
					GP0=0;
					GP1=1;
					GP2=0;
					__delay_ms(150);
					GP0=1;
					GP1=0;
					GP2=0;
					__delay_ms(150);
				}
			}
			count++;
		} else {		//間違えた場合
			break;
		}
	}
	while(1);
}

結果・感想

進路も決まってヒマなので、半田付けまでしたものの、メチャ疲れました。
回路はちゃんと動作しました。しかし意外と順番を覚えるのって難しい。10回でもクリアできない。

追記 GP端子の入力/出力の振り分け

GP端子の入力/出力を振り分ける方法。毎回忘れて調べ直しになるので、調べた結果をまとめておきます。

8ビットの2進数を考え、0桁目をGP0の振り分け、1桁目をGP1の振り分け、…、5桁目をGP5の情報とする。入力端子としたいのなら1、出力端子としたいのなら0とする。6、7桁目は0としておく。最後に、この8ビットの2進数を16進数としてTRISIOに代入する。

今回の場合、GP3,4,5のみを入力としたいので、8ビットの2進数は00111000であり、16進数にすると38です。したがってTRISIO=0x38とすればOK。

参考にさせていただいたサイト

  • このエントリーをはてなブックマークに追加

最新記事

コメント(0)





プロフィール

名前:elkosendiary

性別:男

生年:1995年


2011年4月 高専入学
2016年3月 高専卒業
2016年4月 大学編入学
2018年3月 大学卒業予定

にほんブログ村 大学生日記ブログ 理系大学生へ
にほんブログ村

カテゴリ
Adsense
月別アーカイブ
ブログ内検索

おすすめ記事

「高専大学編入ログ」を作成しました

自作ゲーム「Defend PortMoresby!」バージョン3

【改良版】 RaspberryPiで作ったカメラ付き戦車ラジコン