JasmineL 发表于 2013-4-24 19:18:13

复古像素游戏《雷电》前传(红外遥控&16*16 LED点阵)

我看论坛上基本没有教16*16LED点阵模块的....

这是之前为我们课程的作业写的,现在贴出来与大家分享~

因为这学期才开始接触Arduino和汇编语言,编的不能保证简练..
而且有不完善的地方,但我们作业的时间有限,实现功能就行了~
现在还在苦逼苦逼的做最终的大作业.....

有兴趣的童鞋可以下下来自己玩一玩~~
红外遥控器4,6控制飞机左右,2发射炮弹,0是reset
哭泣的表情需要摁reset来继续

视频地址:
http://v.youku.com/v_show/id_XNTM1NzcxNTgw.html
http://player.youku.com/player.php/sid/XNTM1NzcxNTgw/v.swf

#include <IRremote.h>// 使用IRRemote函数库

#define RowA 3 //行信号,驱动138
#define RowB 4
#define RowC 5
#define RowD 6
int hc138en=7; //138 使能
//使用了硬件SPI,以下脚不能更改
#define R1 11 //数据出 MOSI
#define CLK 13 //时钟 SCK
#define STB 10 //刷新显示 SS
#define DATAIN 12 //数据入,读FLASH时有用 MISO

byte dots[] ={//子弹
0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,
0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,
0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x10,
0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01
};
byte plane2[] ={//飞机
0xE0,0x00,0x40,0x00,
0x70,0x00,0x20,0x00,
0x38,0x00,0x10,0x00,
0x1C,0x00,0x08,0x00,
0x0E,0x00,0x04,0x00,
0x07,0x00,0x02,0x00,
0x03,0x80,0x01,0x00,
0x01,0xC0,0x00,0x80,
0x00,0xE0,0x00,0x40,
0x00,0x70,0x00,0x20,
0x00,0x38,0x00,0x10,
0x00,0x1C,0x00,0x08,
0x00,0x0E,0x00,0x04,
0x00,0x07,0x00,0x02
};

byte cry[]={ //哭泣表情
0x00,0x00,0x00,0x00,0xFC,0x3F,0xFC,0x3F,
0x21,0x84,0x21,0x84,0x23,0xC4,0x26,0x64,
0x24,0x24,0x20,0x04,0x20,0x04,0x20,0x04,
0x20,0x04,0x20,0x04,0x00,0x00,0x00,0x00};



//红外
const int irReceiverPin = 2;// 红外接收器的 OUTPUT 引脚接在 PIN2 接口 定义irReceiverPin变量为PIN2接口
IRrecv irrecv(irReceiverPin); // 设置irReceiverPin定义的端口为红外信号接收端口
decode_results results;    // 定义results变量为红外结果存放位置

long IRright=0x00FF5AA5;    //right 6
long IRleft= 0x00FF10EF;   //left 4
long IRfire= 0x00FF18E7;         //fire 2
long IRreset=0x00FF6897;      //reset 0

void spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
    //SPSR:程序状态保存寄存器
{
    ;
}
}

//输出行
void hc138sacn(byte r){
digitalWrite(RowA,!(r & 0x01));
digitalWrite(RowB,!(r & 0x02));
digitalWrite(RowC,!(r & 0x04));
digitalWrite(RowD,!(r & 0x08));
}

void setup () {
pinMode(RowA, OUTPUT);
pinMode(RowB, OUTPUT);
pinMode(RowC, OUTPUT);
pinMode(RowD, OUTPUT); //138片选
pinMode(hc138en, OUTPUT); //138 使能
pinMode(R1, OUTPUT);//DI
pinMode(CLK, OUTPUT); //时钟
pinMode(STB, OUTPUT); //Latch锁存
pinMode(DATAIN, INPUT); //无用,但SPI必须写
Serial.begin(19200);
//SPI硬件设置
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
//sample on leading edge of clk,system clock/4 rate (fastest)
SPCR = (1<<SPE)|(1<<MSTR);
delay(10);

irrecv.enableIRIn();   // 启动红外解码
}

byte row;
int count;
//子弹部分
byte rowb;//子弹所在行数
int time;//计时
int post;//position(column)
int number;//计数
int temp;//交换用
//洞穴部分
int timec; //计时
int numberc;//计数
byte cave={ //洞穴初始化数据
0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,
0xE0,0x07,0xFC,0x3F,0xE0,0x07,0xE0,0x07,
0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,
0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07};

int fail=1;      
void loop () {
if(fail==1)
{      //哭泣表情
    for(int i=15;i>=0;i--)
    {
      spi_transfer(~(cry));
      spi_transfer(~(cry));

      digitalWrite(hc138en, 1); //关闭显示
      hc138sacn(15-i); //换行
      digitalWrite(STB, 0); //595刷新
      digitalWrite(STB, 1);
      delayMicroseconds(500) ; //节电用,
      digitalWrite(hc138en, 0); //开启显示
      delayMicroseconds(500) ; //刷新频率调
    }
    if (irrecv.decode(&results)) {   // 解码成功,把数据放入results变量中
      // 把数据输入到串口
      if (results.value ==IRreset ) //reset
      {   
      fail=0;
      //飞机部分
      count=8;
      //子弹部分
      byte rowb={
          2,2,2,2,2,2      };//子弹所在行数
      int time={
          0,0,0,0,0,0      };//计时
      int post={
          0,0,0,0,0,0      };//position(column)
      number=0;//计数
      temp=0;//交换用
      //洞穴部分
      timec=0; //计时
      numberc=0;//计数
      byte cave={ //洞穴初始化数据
          0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,
          0xE0,0x07,0xFC,0x3F,0xE0,0x07,0xE0,0x07,
          0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,
          0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07      };

      }
      irrecv.resume();    // 继续等待接收下一组信号
    }
}
else
{
    int fire=0;
    if (irrecv.decode(&results))
    {         
      // 解碼成功,收到一組紅外線訊號
      if (results.value ==IRright ) //right
      {      
      count=count-1;      
      }
      else if (results.value ==IRleft ) //left
      {      
      count=count+1;      
      }
      if (results.value ==IRfire ) //fire
      {      
      fire=1;            
      }

      if(count>14)
      count=14;
      if(count<1)
      count=1;
      irrecv.resume();    // 继续等待接收下一组信号
    }
    //飞机部分
    for(row=1;row<3;row++)
    {
      if(row==1)   
      {
      spi_transfer(~(plane2));
      spi_transfer(~(plane2));
      }
      if(row==2)
      {
      spi_transfer(~(plane2));
      spi_transfer(~(plane2));
      }            

      digitalWrite(hc138en, 1); //关闭显示
      hc138sacn(row); //换行
      digitalWrite(STB, 0); //595刷新
      digitalWrite(STB, 1);
      delayMicroseconds(350) ; //节电用,
      digitalWrite(hc138en, 0); //开启显示
      delayMicroseconds(350) ; //
    }

    //多发炮弹部分
    if(fire==1)
    {
      number=temp;
      rowb=3;
      post=count;
      temp=number+1;
      if(temp==6)
      temp=0;
    }
    for(int i=0;i<=5;i++)
    {
      if(rowb>=3)
      {
      spi_transfer(~(dots*2]));
      spi_transfer(~(dots*2+1]));
      time++;
      digitalWrite(hc138en, 1); //关闭显示
      hc138sacn(rowb); //换行
      digitalWrite(STB, 0); //595刷新
      digitalWrite(STB, 1);
      delayMicroseconds(250) ; //节电用,
      digitalWrite(hc138en, 0); //开启显示
      delayMicroseconds(250) ; //刷新频率调,差不多120HZ,1/32间隔

      if(time==30)
      {
          rowb=rowb+1;
          time=0;
      }
      if(rowb>15)
          rowb=2;
      }
    }

    //洞穴部分

    for(int i=0;i<=15;i++)
    {
      spi_transfer(~(cave));
      spi_transfer(~(cave));

      digitalWrite(hc138en, 1); //关闭显示
      hc138sacn(i); //换行
      digitalWrite(STB, 0); //595刷新
      digitalWrite(STB, 1);
      delayMicroseconds(100) ; //节电用,
      digitalWrite(hc138en, 0); //开启显示
      delayMicroseconds(100) ; //刷新频率调

      if(i==0) {
      timec=(timec+1)%100;
      if(numberc<200){
          cave=(random(0,3)<<random(0,5)|0x80);
          cave=(random(0,3)<<random(1,6)|0x01);
      }
      else if(numberc<500){
          cave=(random(0,4)<<random(0,5)|0x80);
          cave=(random(0,4)<<random(1,6)|0x01);
      }
      else if(numberc<=900){
          cave=(random(0,8)<<random(0,4)|0x80);
          cave=(random(0,8)<<random(1,5)|0x01);
      }
      else{
          numberc=900;
          cave=(random(0,8)<<random(0,4)|0x80);
          cave=(random(0,8)<<random(1,5)|0x01);
      }         
      }

      if(timec==0)
      {   
      cave=cave;
      cave=cave;
      numberc++;
      }

    }

    for(int j=0;j<=15;j++)
    {
      for(int k=0;k<=5;k++)
      {
      if(rowb==j)
      {
          //用于判断子弹打下哪个B是子弹,C是目标 B^C 异或   
          if((dots*2]&cave)||(dots*2+1]&cave))
          {
            cave=dots*2]^cave;
            cave=dots*2+1]^cave;
            rowb=2;
          }
      }   
      }
      //判断飞机是否接触洞穴   
      if(j==1)
      if((plane2&cave)||(plane2&cave))
          fail=1;
      if(j==2)
      if((plane2&cave)||(plane2&cave))   
          fail=1;
    }
}
}

幻生幻灭 发表于 2013-4-24 21:43:47

我不过是看个视频,结果沙发就丢了、

lyili 发表于 2013-4-24 21:15:43

哇,妹子做的给力呀~ 16×16点阵板上的是595吧?

duocool 发表于 2013-4-24 21:23:46

妹子威武。。。。。

弘毅 发表于 2013-4-24 21:40:50

:funk:妹子好威武。。。你们啥专业。。。居然布置这种作业。。

JasmineL 发表于 2013-4-24 22:11:46

lyili 发表于 2013-4-24 21:15 static/image/common/back.gif
哇,妹子做的给力呀~ 16×16点阵板上的是595吧?

这是两个妹子的工作成果~~
我们专业叫工业设计......悄悄的说,其实老师要求的没有这么难

LED点阵是网上直接买的,用的595和138

JasmineL 发表于 2013-4-24 22:15:10

弘毅 发表于 2013-4-24 21:40 static/image/common/back.gif
妹子好威武。。。你们啥专业。。。居然布置这种作业。。

对各位大神敬仰已久!老师推荐的初学的教程就是这个论坛上面的,还有Cookbook

应该说,这个论坛对我们的帮助很大~~

弘毅 发表于 2013-4-24 22:16:04

JasmineL 发表于 2013-4-24 22:15 static/image/common/back.gif
对各位大神敬仰已久!老师推荐的初学的教程就是这个论坛上面的,还有Cookbook

应该说,这个论坛对我们 ...

弱弱的问问。。是不是浙大的妹纸。。。

JasmineL 发表于 2013-4-24 22:17:18

弘毅 发表于 2013-4-24 22:16 static/image/common/back.gif
弱弱的问问。。是不是浙大的妹纸。。。

被发现了么......

弘毅 发表于 2013-4-24 22:18:29

JasmineL 发表于 2013-4-24 22:17 static/image/common/back.gif
被发现了么......

{:soso_e104:} 看来我第六感还是很准的

JasmineL 发表于 2013-4-24 22:20:16

弘毅 发表于 2013-4-24 22:18 static/image/common/back.gif
看来我第六感还是很准的

有机会欢迎来看我们课程的大作业展览~在紫金港

JasmineL 发表于 2013-4-24 22:22:17

突然发现加精了...好开心~~

弘毅 发表于 2013-4-24 22:22:24

JasmineL 发表于 2013-4-24 22:20 static/image/common/back.gif
有机会欢迎来看我们课程的大作业展览~在紫金港

{:soso_e103:} 居然有展览。。。几号开始呀在紫金港啥地方。。。偶们走绕城过去也不远。。。这要去看的。。。

JasmineL 发表于 2013-4-24 22:26:32

弘毅 发表于 2013-4-24 22:22 static/image/common/back.gif
居然有展览。。。几号开始呀在紫金港啥地方。。。偶们走绕城过去也不远。。。这要去看的。 ...

应该是定在5月9号,与上一届的毕设一起展览。应该是在月牙楼1层

我们都是初学,软硬件基础基本为零...大神期待不要太高嘛...会有压力的~~

咯小3虽 发表于 2013-4-24 22:27:00

{:soso_e183:}学姐威武!!!
页: [1] 2 3 4 5
查看完整版本: 复古像素游戏《雷电》前传(红外遥控&16*16 LED点阵)