《单片机原理与实践》课程大作业
“老鼠吃蛋糕”技术报告
摘 要
单片机开发小游戏很普遍,而且网上也有各种开源文件。至于我,开始想实现个迷宫,后来发觉迷宫太静态了,拓展空间不大。后来想到了方块扩散,感觉方块扩散实现步数存在着最优路径,但尝试后发现难度极大且涉及深度学习算法,于是就两者结合设计了“老鼠吃蛋糕”这存在最优路径且拓展性高的游戏。
该游戏采用触摸屏、显示屏、红外遥控、串口通信、数码管、定时器、蜂鸣器、LED灯等外设来实现该游戏,功能相对广泛。其中显示屏用作游戏界面以及交互界面的显示,红外用来控制,串口是信息显示,定时器实时处理并作相应的反馈,蜂鸣器和LED则是指示作用。其中各个模块的功能相对简单,但结合起来就不简单了,具体的困难会在后续章节中提出。
关键词: 迷宫;方块扩散;最优路径;串口;定时器
本系统主要由显示屏、触摸屏、红外遥控、串口通信、数码管等模块组成。由于是在学校下发的单片机开发板上设计,所以并不涉及各个模块的品牌、类型选择,下面简述一下游戏某一功能实现模块的选择。
方案一:触摸屏控制。触摸屏控制是比较普遍的,比如我们的智能手机以及部分笔记本电脑,但对于该开发板来说并不适用。主要有两点:① 由于制作工艺及器件的老化存在着噪点,即使采用中值法去噪效果较好,但那么小的显示屏摆放好几个操作按键也不免会误触碰;② 由于显示屏本身就是240*400大小,若再放置好几个按键则对后期的游戏设计界面有很大的影响。
方案二:红外遥控。比如以前的彩色电视就可以通过红外遥控来玩自带的俄罗斯方块、推箱子之类的游戏。用红外来控制效果也确实不错,既不用那么近盯着显示屏,也可以选择个舒服的姿势玩游戏,唯一的缺点就是偶尔会解码错误,主要是因为人为按按键不规则以及信号传送过程会有干扰。
经过对以上两种方案的对比,选择方案二相对来说更为可靠。既可以避免触摸屏的噪点问题和游戏界面的影响,红外遥控的解码错误也是在可接受的范围内。
方案一:显示屏显示。提示信息和游戏界面在一处显示对玩家来说比较方便,边观察游戏界面就可以看到提示信息。但同样出现界面大小问题,不能显示太多信息,同时由于不支持输出显示中文,所以对于游戏玩家不太方便。
方案二:串口助手显示。可以通过PC端串口助手接受单片机串口传送的信息,既能输出显示中文,又有较大的显示界面,查看信息比较容易,但是游戏玩家需要不断地在显示屏和PC端串口助手界面间转换视角,容易分神,不利于游戏的控制。
方案三:数码管显示。数码管只能显示数字及字符,显示内容比较单一,但是数码管比较醒目,可以用来显示时间之类的信息。
综合以上三种方案,决定使用三种方案来显示不同的信息。用方案一中显示屏来显示游戏开始界面、关卡选择以及游戏结束界面;方案二串口助手来显示游戏开始,游戏操作说明,游戏操作过程的步数、时间信息以及游戏的相关提示信息;方案三数码管醒目地显示倒计时,对游戏玩家有提示作用。
1.3.1.系统方框图
1.3.2系统工作原理
本系统开始在显示屏显示指导信息,等待玩家触摸显示屏或红外遥控来进行游戏相关的选择和控制,在游戏开始后定时器开始计时并通过数码管来显示,在操纵期间显示屏右上角也会提供倒计时的显示来提示玩家,PC端串口助手会显示相关操作信息来帮助玩家进行游戏。其中红外接收管接受遥控信息(PN4中断),进行解码得到控制信息并进行相应的程序处理,如此循环反复。玩家若及时地控制“老鼠”吃到“蛋糕”则挑战成功,显示屏和PC端串口助手会显示胜利的相关信息,蜂鸣器和LED也会作出反应;反之则挑战失败,会有失败的相应信息输出显示。
由于使用的单片机开发板为学校下发,故没有进行系统的硬件设计,
只是进行了硬件模块的使用选择。
由于使用的单片机开发板为学校下发,故没有进行系统的硬件设计,只是进行了硬件模块的性能测试及性能测试,下面主要对触摸屏及红外遥控的性能进行简要说明。
触摸屏:由于制作工艺及器件的老化存在着噪点,即使采用中值法去噪效果较好,但那么小的显示屏若要真正设计几个触控按键难免会误触碰,对于时间紧张的游戏来说无疑是不适用的,所以只是在开始界面提供了触摸功能。
红外遥控:用红外来控制效果也确实不错,既能较远距离进行控制,又能有个好姿态。唯一不足的就是偶尔会出现解码错误的情况,这跟程序中有多个中断以及红外信号传输存在干扰有关,经过对解码时序进行合理的修改后,虽然效果改善了,但仍存在,不过是在可接受范围内。
该游戏的特色主要有三点:
① 数码管多位数字同时显示。该开发板上的五个米字管是由三块PCA9557PWR芯片同时控制一片LEDS05441芯片来进行显示的,所以一次只能控制一个米字管,所以很多同学的10~15只用16进制的A~F来表达。所以要“同时”显示两个米字管,只能通过让它们交替显示的频率非常快,快到我们人眼观察不到。刚开始把程序段放在主程序的while(1)循环里,但这样严重干扰了红外遥控的中断信号接收,整个程序的时序是乱的,然后开了个定时器,通过设置定时器的频率来控制米字管,但又碰到了中断优先级问题,于是又折腾了一番,一切解决之后,终于可以同时显示两位数字了,三位、四位也同理。现在回过头感觉这几个问题很简单,但开始遇到问题、分析问题、解决问题花费了较多时间,感觉收获蛮多。
② 游戏本身的设定。刚开始想实现个迷宫,后来发觉迷宫太静态了,拓展空间不大。后来想到了方块扩散,感觉方块扩散实现步数存在着最优路径,于是就想把最优路径找出来,但尝试后发现难度极大且涉及深度学习算法,于是就两者结合设计了“老鼠吃蛋糕”这存在最优路径且拓展性高的游戏。第一关是最基础的,也没什么亮点;第二关也只是加了常见的“转向块”,对游戏难度有一定的提升;第三关则采用了三个分块区域,只有经过一定路径使用“传送块”功能才能进行区域的跳转,为什么要区域跳转呢?因为我在定时器里设计了一个随机函数,定时器的频率决定了蛋糕在三个区域跳转的频率,然后随机函数则是进一步决定蛋糕跳转频率以及跳转区域,这游戏玩法想了挺久才想到的,自身感觉这样的游戏设定蛮好的。
③ 模块的集成。该游戏涉及了课上实验的较多模块,如触摸屏、显示屏、红外遥控、串口通信、数码管、定时器、蜂鸣器、LED灯,虽然这些模块并不那么难,但是要把各个模块结合起来用并应用在游戏当中就不那么容易了,之间有严格的逻辑关系以及单独情况的处理,就像上面说的中断优先级问题一样,其他模块也存在相互干扰的情况,比如中断里面不能再嵌套中断服务函数以及延时函数,否则严重影响程序的时序,严重可能使板子进入自锁状态。
测试结果在视频和附录二中有详细说明,这里就不再重复了。
4.参考文献
1)陈朋. Cortex-M4实验指导书. 浙江工业大学出版社. 2014.9
2)陈朋. Cortex-M4原理与实践. 浙江工业大学出版社. 2014.9
3) 王日明, 廖锦松, 申柏化. 轻松玩转ARM 微控制器--基于Kinetis K60. 北京航空航天大学出版社. 2014.9
4) 刘火良, 杨森. STM32库开发实战指南. 机械工业出版社. 2017.2
附录一 电路原理图
米字管电路图
红外IR电路图
蜂鸣器电路图
TFTLCD液晶显示电路图
注:第三关游戏界面,其中黄色箭头指的是“传送块”,红色箭头是“蛋糕”随机出现的位置,深蓝色箭头是“老鼠”所在位置。
注:游戏说明界面,深蓝色箭头所指内容是游戏说明,黄色箭头是“退出”键,品红箭头是关卡“easy”键,黑色箭头是关卡“mid”键,白色箭头是关卡“hard”键。
注:这是游戏开始界面,白色是游戏名,黑色是游戏说明引导键,红色是“退出”键,黄色是“easy”键,绿色是“mid”键,橙色是“hard”键。
注:PC端串口助手关于游戏相关信息的显示界面。
注:游戏第二关界面,红色箭头为“转向块”,黄色箭头为“蛋糕”,橙色箭头为“老鼠”。
注:游戏第一关界面,红色箭头为“老鼠”,黄色箭头为“蛋糕”。
附录
#include
#include
#include
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_epi.h"
#include "inc/hw_nvic.h"
#include "inc/hw_ints.h"
#include "driverlib/epi.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "driverlib/systick.h"
#include "driverlib/interrupt.h"
#include "driverlib/ssi.h"
#include "driverlib/fpu.h"
#include "driverlib/timer.h"
#include "utils/uartstdio.h"
#include "TFTinit/TFT_400x240_OTM4001A_16bit.h"
//#include "TFTinit/picture.h"
#include "TOUCHinit/TOUCH_TSC2046.h"
#include "EPIinit/EPIinit.h"
#include "math.h"
#include "inc/hw_i2c.h"
#include "driverlib/i2c.h"
*********************************************************************
// System clock rate in Hz.
//
//*****************************************************************************
/触摸屏//
uint32_t g_ui32SysClock;
extern uint32_t GetData[6];
uint32_t N=0;//打中的只数
uint32_t TouchXData[6];
uint32_t TouchYData[6];
uint32_t TouchZData[6]; //Z is for pressure measurement
#define _NOP() _nop()
//*********************************************************************
//*********************************************************************
#define I2C0_MASTER_BASE 0x40020000
#define I2C0_SLAVE_BASE 0x40020000
//*********************************************************************
// 地址、寄存器等定义部分
//*********************************************************************
//*********************************************************************
//
// 设定slave(从)模块的地址。这是一个7-bit的地址加上RS位,具体形式如下:
// [A6:A5:A4:A3:A2:A1:A0:RS]
// RS位是一个指示位,如果RS=0,则说明是主发送数据,从接收数据;RS=1说明是主接收数据,从发送数据
//
//*********************************************************************
//U21控制4个米字管和特殊管脚的亮灭
#define I2C0_ADDR_TUBE_SEL 0x30 //00110000
//U22控制米字管7~14管脚对应的码段
#define I2C0_ADDR_TUBE_SEG_LOW 0x32 //00110010
//U23控制米字管15~18管脚对应的码段
#define I2C0_ADDR_TUBE_SEG_HIGH 0x34 //00110100
//U24控制LED光柱
//PCA9557内部寄存器,也称子地址
#define PCA9557_REG_INPUT 0x00
#define PCA9557_REG_OUTPUT 0x01
#define PCA9557_REG_PolInver 0x02
#define PCA9557_REG_CONFIG 0x03
//*************************************************************************************
#define NUM 0
#define EASY_I 8
#define EASY_J 7
#define MID_I 14
#define MID_J 8
#define HARD_I 26
#define HARD_J 12
/红外///
volatile uint32_t ui32SysClock;
volatile uint32_t error= 0;
volatile uint32_t count= 0;
unsigned char IrData[4];
int begin_easy_x=50,begin_easy_y=120;
int begin_mid_x=40,begin_mid_y=60;
int begin_hard_x=30,begin_hard_y=2;
int easy_i = 1,easy_j = 3,easy_end_x=6,easy_end_y=3;
int mid_i = 9,mid_j = 1,mid_end_x=6,mid_end_y=3;
int hard_i = 6,hard_j = 3;hard_cake_i=2,hard_cake_j=7;
int easy_time = 70,mid_time = 230,hard_time = 600,easy_R,easy_G,easy_B;
int mid_tra_x1 = 4,mid_tra_x2 = 6,mid_tra_y1=4,mid_tra_y2=5;
int easy_end = 0,mid_end=0;hard_end=0,easy_begin=0,mid_begin=0,hard_begin=0;
int hand_u=0,hand_d=0,hand_r=0,hand_l=0;
int kong_flag=0,time=0,time_flag=0;
int flag=0,cake_flag;
int touch_flag=0;
int level=0;
int min(int a,int b)
{
if(a
else return b;
}
int max(int a,int b)
{
if(a
else return a;
}
long hand(int color)
{
if((color==1)||(color==2)||(color==4)) return 0X7D7C;//浅蓝色
if(color==5) return 0xF800;//蓝色
if(color==3) return 0xFFFF;//白
}
//1 背景;2 老鼠;3 蛋糕;4 转向块;5 传送洞
int piexl_easy_ori[8][7]={ {0,0,0,0,0,0,0},
{0,0,1,2,0,0,0},
{0,1,1,1,1,1,0},
{0,1,1,1,0,1,0},
{0,0,0,0,0,1,0},
{0,1,1,1,1,1,0},
{0,1,1,3,0,0,0},
{0,0,0,0,0,0,0} };
int piexl_mid_ori[14][8]={{0,0,0,0,0,0,0,0},{0,0,1,1,0,1,0,0},{0,0,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,1,1,0,4,1,0,0},
{0,1,1,1,1,1,1,0},{0,0,1,3,1,4,1,0},{0,0,1,0,1,1,1,0},{0,0,1,0,0,0,0,0},{0,2,1,1,1,0,0,0},
{0,0,1,1,1,1,1,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,0,0,0},{0,0,0,0,0,0,0,0} };
int piexl_hard_ori[26][12]={{0,0,0,0,0,0,0,0,0,0,0,0},{0,1,1,1,0,1,1,0,0,0,0,0},
{0,1,0,1,1,1,1,3,0,0,0,0},{0,1,1,1,0,1,1,0,0,0,0,0},
{0,1,1,1,1,1,1,5,0,0,0,0},{0,1,0,1,1,1,1,0,0,0,0,0},
{0,1,1,2,1,1,1,0,0,0,0,0},{0,1,0,0,1,1,1,1,0,0,0,0},
{0,1,1,1,1,1,1,1,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,0,0,0,1,1,1,0,0},{0,0,5,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,0,1,1,0},{0,1,1,1,1,1,1,0,0,0,0,0},
{0,1,0,1,1,1,1,1,0,0,0,0},{0,1,1,1,1,1,0,1,0,0,0,0},
{0,1,1,1,1,1,1,1,0,0,0,0},{0,0,0,1,3,1,0,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,0,0,0,1,1,0,0,0},{0,1,0,1,1,1,1,1,1,0,0,0},
{0,1,1,1,1,5,0,1,1,0,0,0},{0,1,1,0,1,1,1,1,0,0,0,0},
{0,1,0,1,1,0,1,3,1,0,0,0},{0,1,1,1,1,0,1,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0} };
int piexl_easy[8][7],piexl_mid[14][8],piexl_hard[26][12];
void recover(int a,int b)
{
int i,j;
if(a==8)
{
for(j=0;j
{
piexl_easy[i][j] = piexl_easy_ori[i][j];
// piexl_easy[i][j][1] = 0;
}
easy_i=1;
easy_j=3;
}
else if(a==14)
{
for(j=0;j
piexl_mid[i][j] = piexl_mid_ori[i][j];
mid_i=9;
mid_j=1;
}
else if(a==26)
{
for(j=0;j
{
piexl_hard[i][j]= piexl_hard_ori[i][j];
}
hard_i=6;
hard_j=3;
}
}
void exit_recover()
{
TFTLCD_ShowString(52,180," exit(0) ",RED,LIGHTBLUE);
TFTLCD_ShowString(52,230," easy(1) ",RED,LIGHTBLUE);
TFTLCD_ShowString(52,280," mid (3) ",RED,LIGHTBLUE);
TFTLCD_ShowString(52,330," hard(9) ",RED,LIGHTBLUE);
easy_begin=0;
mid_begin=0;
hard_begin=0;
easy_time = 80;
mid_time = 200;
hard_time = 600;
hand_u=0;
hand_l=0;
hand_r=0;
hand_d=0;
touch_flag=0;
recover(8,7);
recover(14,8);
recover(26,12);
IntDisable(INT_TIMER0B);
TimerDisable(TIMER0_BASE, TIMER_B);
}
void end_game()
{
TFTLCD_CLEAR(BLACK);
TFTLCD_ShowString(52,30," Time over ! ",WHITE,LIGHTBLUE);
TFTLCD_ShowString(52,80," you fail ",RED,LIGHTBLUE);
UARTprintf("很遗憾,游戏时间到,闯关失败!可重玩一次或进入下一关或直接退出。\n");
UARTprintf("退出--0;简单--1;中等--3;困难--9\n");
exit_recover();
}
void instructions()
{
TFTLCD_CLEAR(BLACK);
TFTLCD_ShowString(52,20,"this is a instructions about games:you need to control the mouse by 2|4|6|8 to eat the cake. Only complete the game within a certain time, can you beat the game.",RED,LIGHTBLUE);
UARTprintf("游戏说明:该游戏总共有三关,通过红外遥控可选择关卡。你所假扮的“老鼠”必须在规定时间内通过利用各种道具“吃到蛋糕”,这样才算挑战成功.其中有转向块和传送块,可以对“老鼠”位置进行改变,然后最后一关蛋糕还用到的随机函数来确定蛋糕在哪个位置。\n");
TFTLCD_ShowString(52,180," exit(0) ",RED,LIGHTBLUE);
TFTLCD_ShowString(52,230," easy(1) ",RED,LIGHTBLUE);
TFTLCD_ShowString(52,280," mid (3) ",RED,LIGHTBLUE);
TFTLCD_ShowString(52,330," hard(9) ",RED,LIGHTBLUE);
}
void begin(int a,int b)
{
TFTLCD_CLEAR(BLACK);
int i,j;
if(level==1)
{
for(j=0;j
TFTLCD_FillBlock(begin_easy_x+20*j,begin_easy_x+20*j+20,begin_easy_y+i*20,begin_easy_y+21+20*i,hand(piexl_easy[i][j]));
TFTLCD_FillBlock(begin_easy_x+20*easy_j,begin_easy_x+20*easy_j+20,begin_easy_y+easy_i*20,begin_easy_y+21+20*easy_i,hand(1));
CREATEMOUSE(begin_easy_x+easy_j*20+10,begin_easy_y+easy_i*20+10);
TFTLCD_DrawCake(begin_easy_x+20*easy_end_y,begin_easy_y+easy_end_x*20);
}
else if(level==3)
{
for(j=0;j
TFTLCD_FillBlock(begin_mid_x+20*j,begin_mid_x+20*j+20,begin_mid_y+i*20,begin_mid_y+21+20*i,hand(piexl_mid[i][j]));
TFTLCD_FillBlock(begin_mid_x+20*mid_j,begin_mid_x+20*mid_j+20,begin_mid_y+mid_i*20,begin_mid_y+21+20*mid_i,hand(1));
CREATEMOUSE(begin_mid_x+mid_j*20+10,begin_mid_y+mid_i*20+10);
TFTLCD_DrawCake(begin_mid_x+20*mid_end_y,begin_mid_y+mid_end_x*20);
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+50,begin_mid_y+mid_end_x*20+10,DARKBLUE,10);
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+30,begin_mid_y+mid_end_x*20-30,DARKBLUE,10);
}
else if(level==9)
{
for(j=0;j
TFTLCD_FillBlock(begin_hard_x+15*j,begin_hard_x+15*j+15,begin_hard_y+i*15,begin_hard_y+16+15*i,hand(piexl_hard[i][j]));
TFTLCD_FillBlock(begin_hard_x+15*hard_j,begin_hard_x+15*hard_j+15,begin_hard_y+hard_i*15,begin_hard_y+16+15*hard_i,hand(1));
CREATEMOUSE(begin_hard_x+hard_j*15+7,begin_hard_y+hard_i*15+8);
TFTLCD_DrawSmallCake(begin_hard_x+15*hard_cake_j,begin_hard_y+hard_cake_i*15);
TFTLCD_FillBlock(begin_hard_x+105,begin_hard_x+120,begin_hard_y+60,begin_hard_y+76,BLUE);
TFTLCD_FillBlock(begin_hard_x+30,begin_hard_x+45,begin_hard_y+165,begin_hard_y+181,BLUE);
TFTLCD_FillBlock(begin_hard_x+75,begin_hard_x+90,begin_hard_y+315,begin_hard_y+331,BLUE);
}
}
void exit()
{
TFTLCD_CLEAR(BLACK);
TFTLCD_ShowString(32,30," Mouse eat Cake ",YELLOW,LIGHTBLUE);
TFTLCD_ShowString(32,80," Instructions(5) ",RED,LIGHTBLUE);
exit_recover();
}
void hand_R(int a,int b)
{
if(level==1)
{
while(piexl_easy[a][b+1]==1) b=b+1;
piexl_easy[a][easy_j]=1;
piexl_easy[a][b]=2;
TFTLCD_FillBlock(begin_easy_x+20*easy_j,begin_easy_x+20*easy_j+20,begin_easy_y+a*20,begin_easy_y+21+20*a,hand(piexl_easy[a][easy_j]));
// TFTLCD_FillBlock(begin_easy_x+20*b,begin_easy_x+20*b+20,begin_easy_y+a*20,begin_easy_y+21+20*a,hand(piexl_easy[a][b]));
CREATEMOUSE(begin_easy_x+b*20+10,begin_easy_y+a*20+10);
easy_j=b;
}
else if(level==3)
{
while(piexl_mid[a][b+1]==1) b=b+1;
piexl_mid[a][mid_j]=1;
piexl_mid[a][b]=2;
TFTLCD_FillBlock(begin_mid_x+20*mid_j,begin_mid_x+20*mid_j+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][mid_j]));
// TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][b]));
CREATEMOUSE(begin_mid_x+b*20+10,begin_mid_y+a*20+10);
mid_j=b;
if(piexl_mid[a][mid_j+1]==4)
{
TFTLCD_FillBlock(begin_mid_x+20*(mid_j+1),begin_mid_x+20*(mid_j+1)+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(1));
hand_D(a,mid_j+1);
if(mid_begin!=0)
{
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+50,begin_mid_y+mid_end_x*20+10,DARKBLUE,10);
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+30,begin_mid_y+mid_end_x*20-30,DARKBLUE,10);
}
}
}
else if(level==9)
{
while(piexl_hard[a][b+1]==1) b=b+1;
piexl_hard[a][hard_j]=1;
piexl_hard[a][b]=2;
TFTLCD_FillBlock(begin_hard_x+15*hard_j,begin_hard_x+15*hard_j+15,begin_hard_y+a*15,begin_hard_y+16+15*a,hand(piexl_hard[a][hard_j]));
// TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][b]));
CREATEMOUSE(begin_hard_x+b*15+7,begin_hard_y+a*15+8);
hard_j=b;
if(piexl_hard[a][hard_j+1]==5)
{
if(a<8)
{piexl_hard[4][6]=1;
TFTLCD_FillBlock(begin_hard_x+15*6,begin_hard_x+15*6+15,begin_hard_y+4*15,begin_hard_y+16+15*4,hand(1));
CREATEMOUSE(begin_hard_x+150+7,begin_hard_y+165+8);
hard_i=11;
hard_j=10;
}
else if(a>15)
{
piexl_hard[21][4]=1;
TFTLCD_FillBlock(begin_hard_x+15*4,begin_hard_x+15*4+15,begin_hard_y+21*15,begin_hard_y+16+15*21,hand(1));
CREATEMOUSE(begin_hard_x+150+7,begin_hard_y+165+8);
hard_i=11;
hard_j=10;
}
}
}
// if(((a==easy_end_x)&&((b+1)==easy_end_y))||((a==mid_end_x)&&((b+1)==mid_end_y))||((piexl_hard[a][b+1])==3))
if(((piexl_easy[a][b+1]==3)&&(level==1))||((piexl_mid[a][b+1]==3)&&(level==3))||((piexl_hard[a][b+1]==3)&&(level==9)))
{
TFTLCD_CLEAR(BLACK);
TFTLCD_ShowString(22,30," congratuation ! ",RED,LIGHTBLUE);
TFTLCD_ShowString(22,80,"you have pass the level !",RED,LIGHTBLUE);
UARTprintf("恭喜您,闯关成功!可进入下一关或直接退出。\n");
UARTprintf("退出--0;简单--1;中等--3;困难--9\n");
GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_5,0x20);
SysCtlDelay(10000000);
GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_5,0x00);
exit_recover();
}
}
void hand_L(int a,int b)
{
if(level==1)
{
while(piexl_easy[a][b-1]==1) b=b-1;
piexl_easy[a][easy_j]=1;
piexl_easy[a][b]=2;
TFTLCD_FillBlock(begin_easy_x+20*easy_j,begin_easy_x+20*easy_j+20,begin_easy_y+a*20,begin_easy_y+21+20*a,hand(piexl_easy[a][easy_j]));
// TFTLCD_FillBlock(begin_easy_x+20*b,begin_easy_x+20*b+20,begin_easy_y+a*20,begin_easy_y+21+20*a,hand(piexl_easy[a][b]));
CREATEMOUSE(begin_easy_x+b*20+10,begin_easy_y+a*20+10);
easy_j=b;
}
else if(level==3)
{
while(piexl_mid[a][b-1]==1) b=b-1;
piexl_mid[a][mid_j]=1;
piexl_mid[a][b]=2;
TFTLCD_FillBlock(begin_mid_x+20*mid_j,begin_mid_x+20*mid_j+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][mid_j]));
// TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][b]));
CREATEMOUSE(begin_mid_x+b*20+10,begin_mid_y+a*20+10);
mid_j=b;
if(piexl_mid[a][mid_j-1]==4)
{
TFTLCD_FillBlock(begin_mid_x+20*mid_j,begin_mid_x+20*mid_j+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(1));
hand_U(a,mid_j-1);
if(mid_begin!=0)
{
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+50,begin_mid_y+mid_end_x*20+10,DARKBLUE,10);
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+30,begin_mid_y+mid_end_x*20-30,DARKBLUE,10);
}
}
}
else if(level==9)
{
while(piexl_hard[a][b-1]==1) b=b-1;
piexl_hard[a][hard_j]=1;
piexl_hard[a][b]=2;
TFTLCD_FillBlock(begin_hard_x+15*hard_j,begin_hard_x+15*hard_j+15,begin_hard_y+a*15,begin_hard_y+16+15*a,hand(piexl_hard[a][hard_j]));
CREATEMOUSE(begin_hard_x+b*15+7,begin_hard_y+a*15+8);
hard_j=b;
if(piexl_hard[a][hard_j-1]==5)
{
piexl_hard[11][3]=1;
flag=rand()%2;
//第一背景
if(flag==1)
{
TFTLCD_FillBlock(begin_hard_x+15*3,begin_hard_x+15*3+15,begin_hard_y+11*15,begin_hard_y+16+15*11,hand(1));
CREATEMOUSE(begin_hard_x+15+7,begin_hard_y+60+8);
//TFTLCD_FillBlock(begin_hard_x+30,begin_hard_x+45,begin_hard_y+165,begin_hard_y+182,hand(1));
hard_i=4;
hard_j=1;
}
//第三背景
else if(flag==0)
{
TFTLCD_FillBlock(begin_hard_x+15*3,begin_hard_x+15*3+15,begin_hard_y+11*15,begin_hard_y+16+15*11,hand(1));
CREATEMOUSE(begin_hard_x+15+7,begin_hard_y+315+8);
//TFTLCD_FillBlock(begin_hard_x+30,begin_hard_x+45,begin_hard_y+165,begin_hard_y+182,hand(1));
hard_i=21;
hard_j=1;
}
}
}
// if(((a==easy_end_x)&&((b-1)==easy_end_y))||((a==mid_end_x)&&((b-1)==mid_end_y))||((piexl_hard[a][b-1])==3))
if(((piexl_easy[a][b-1]==3)&&(level==1))||((piexl_mid[a][b-1]==3&&(level==3)))||((piexl_hard[a][b-1]==3)&&(level==9)))
{
TFTLCD_CLEAR(BLACK);
TFTLCD_ShowString(22,30," congratuation ! ",RED,LIGHTBLUE);
TFTLCD_ShowString(22,80,"you have pass the level !",RED,LIGHTBLUE);
UARTprintf("恭喜您,闯关成功!可进入下一关或直接退出。\n");
UARTprintf("退出--0;简单--1;中等--3;困难--9\n");
GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_5,0x20);
SysCtlDelay(10000000);
GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_5,0x00);
exit_recover();
}
}
void hand_U(int a,int b)
{
hard_i=a;
hard_j=b;
if(level==1)
{
while(piexl_easy[a-1][b]==1) a=a-1;
piexl_easy[easy_i][b]=1;
piexl_easy[a][b]=2;
TFTLCD_FillBlock(begin_easy_x+20*b,begin_easy_x+20*b+20,begin_easy_y+easy_i*20,begin_easy_y+21+20*easy_i,hand(piexl_easy[easy_i][b]));
// TFTLCD_FillBlock(begin_easy_x+20*b,begin_easy_x+20*b+20,begin_easy_y+a*20,begin_easy_y+21+20*a,hand(piexl_easy[a][b]));
CREATEMOUSE(begin_easy_x+b*20+10,begin_easy_y+a*20+10);
easy_i=a;
}
else if(level==3)
{
while(piexl_mid[a-1][b]==1) a=a-1;
piexl_mid[mid_i][b]=1;
piexl_mid[a][b]=2;
TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+mid_i*20,begin_mid_y+21+20*mid_i,hand(piexl_mid[mid_i][b]));
// TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][b]));
CREATEMOUSE(begin_mid_x+b*20+10,begin_mid_y+a*20+10);
mid_i=a;
if(piexl_mid[mid_i-1][b]==4)
{
TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+mid_i*20,begin_mid_y+21+20*mid_i,hand(1));
mid_i=mid_i-1;
hand_R(mid_i,b);
if(mid_begin!=0)
{
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+50,begin_mid_y+mid_end_x*20+10,DARKBLUE,10);
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+30,begin_mid_y+mid_end_x*20-30,DARKBLUE,10);
}
}
}
else if(level==9)
{
while(piexl_hard[a-1][b]==1) a=a-1;
piexl_hard[hard_i][b]=1;
piexl_hard[a][b]=2;
TFTLCD_FillBlock(begin_hard_x+15*b,begin_hard_x+15*b+15,begin_hard_y+hard_i*15,begin_hard_y+16+15*hard_i,hand(piexl_hard[hard_i][b]));
// TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][b]));
CREATEMOUSE(begin_hard_x+b*15+7,begin_hard_y+a*15+8);
hard_i=a;
}
if(((piexl_easy[a-1][b]==3)&&(level==1))||((piexl_mid[a-1][b]==3)&&(level==3))||((piexl_hard[a-1][b]==3)&&(level==9)))
{
TFTLCD_CLEAR(BLACK);
TFTLCD_ShowString(22,30," congratuation ! ",RED,LIGHTBLUE);
TFTLCD_ShowString(22,80,"you have pass the level !",RED,LIGHTBLUE);
UARTprintf("恭喜您,闯关成功!可进入下一关或直接退出。\n");
UARTprintf("退出--0;简单--1;中等--3;困难--9\n");
GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_5,0x20);
SysCtlDelay(10000000);
GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_5,0x00);
exit_recover();
}
}
void hand_D(int a,int b)
{
if(level==1)
{
while(piexl_easy[a+1][b]==1) a=a+1;
piexl_easy[easy_i][b]=1;
piexl_easy[a][b]=2;
TFTLCD_FillBlock(begin_easy_x+20*b,begin_easy_x+20*b+20,begin_easy_y+easy_i*20,begin_easy_y+21+20*easy_i,hand(piexl_easy[easy_i][b]));
//TFTLCD_FillBlock(begin_easy_x+20*b,begin_easy_x+20*b+20,begin_easy_y+a*20,begin_easy_y+21+20*a,hand(piexl_easy[a][b]));
CREATEMOUSE(begin_easy_x+b*20+10,begin_easy_y+a*20+10);
easy_i=a;
}
else if(level==3)
{
while(piexl_mid[a+1][b]==1) a=a+1;
piexl_mid[mid_i][b]=1;
piexl_mid[a][b]=2;
TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+mid_i*20,begin_mid_y+21+20*mid_i,hand(piexl_mid[mid_i][b]));
//TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][b]));
CREATEMOUSE(begin_mid_x+b*20+10,begin_mid_y+a*20+10);
mid_i=a;
if(piexl_mid[mid_i+1][b]==4)
{
TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+mid_i*20,begin_mid_y+21+20*mid_i,hand(1));
hand_L(mid_i+1,b);
if(mid_begin!=0)
{
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+50,begin_mid_y+mid_end_x*20+10,DARKBLUE,10);
TFTLCD_DrawDiamond(begin_mid_x+mid_end_y*20+30,begin_mid_y+mid_end_x*20-30,DARKBLUE,10);
}
}
}
else if(level==9)
{
while(piexl_hard[a+1][b]==1) a=a+1;
piexl_hard[hard_i][b]=1;
piexl_hard[a][b]=2;
TFTLCD_FillBlock(begin_hard_x+15*b,begin_hard_x+15*b+15,begin_hard_y+hard_i*15,begin_hard_y+16+15*hard_i,hand(piexl_hard[hard_i][b]));
//TFTLCD_FillBlock(begin_mid_x+20*b,begin_mid_x+20*b+20,begin_mid_y+a*20,begin_mid_y+21+20*a,hand(piexl_mid[a][b]));
CREATEMOUSE(begin_hard_x+b*15+7,begin_hard_y+a*15+8);
hard_i=a;
}
if(((piexl_easy[a+1][b]==3)&&(level==1))||((piexl_mid[a+1][b]==3)&&(level==3))||((piexl_hard[a+1][b]==3)&&(level==9)))
{
TFTLCD_CLEAR(BLACK);
TFTLCD_ShowString(22,30," congratuation ! ",RED,LIGHTBLUE);
TFTLCD_ShowString(22,80,"you have pass the level !",RED,LIGHTBLUE);
UARTprintf("恭喜您,闯关成功!可进入下一关或直接退出。\n");
UARTprintf("退出--0;简单--1;中等--3;困难--9\n");
GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_5,0x20);
SysCtlDelay(10000000);
GPIOPinWrite(GPIO_PORTM_BASE,GPIO_PIN_5,0x00);
exit_recover();
}
}
void IrOutput()
{
switch(IrData[2])
{
//0
case 22 : exit();
break;
case 12 :
level=1;
easy_begin=1;
IntEnable(INT_TIMER0B);
TimerEnable(TIMER0_BASE, TIMER_B);
TFTLCD_CLEAR(BLACK);
begin(EASY_I,EASY_J);
break;
case 24 :
hand_u++;
UARTprintf("向上移动步数 : %d\n",hand_u);
if((level==1)&&(easy_begin==1)) hand_U(easy_i,easy_j);
else if((level==3)&&(mid_begin==1)) hand_U(mid_i,mid_j);
else if((level==9)&&(hard_begin==1)) hand_U(hard_i,hard_j);
break;
//3
case 94 :
level=3;
mid_begin=1;
IntEnable(INT_TIMER0B);
TimerEnable(TIMER0_BASE, TIMER_B);
TFTLCD_CLEAR(BLACK);
begin(MID_I,MID_J);
break;
case 8 :
hand_l++;
UARTprintf("向左移动步数 : %d\n",hand_l);
if((level==1)&&(easy_begin==1)) hand_L(easy_i,easy_j);
else if((level==3)&&(mid_begin==1)) hand_L(mid_i,mid_j);
else if((level==9)&&(hard_begin==1)) hand_L(hard_i,hard_j);
break;
//5
case 28 :
instructions();
break;
case 90 :
hand_r++;
UARTprintf("向右移动步数 : %d\n",hand_r);
if((level==1)&&(easy_begin==1)) hand_R(easy_i,easy_j);
else if((level==3)&&(mid_begin==1)) hand_R(mid_i,mid_j);
else if((level==9)&&(hard_begin==1)) hand_R(hard_i,hard_j);
break;
case 66 :
break;
//8
case 82 :
hand_d++;
UARTprintf("向下移动步数 : %d\n",hand_d);
if((level==1)&&(easy_begin==1)) hand_D(easy_i,easy_j);
else if((level==3)&&(mid_begin==1)) hand_D(mid_i,mid_j);
else if((level==9)&&(hard_begin==1)) hand_D(hard_i,hard_j);
break;
case 74 :
level=9;
hard_begin=1;
IntEnable(INT_TIMER0B);
TimerEnable(TIMER0_BASE, TIMER_B);
TFTLCD_CLEAR(BLACK);
begin(HARD_I,HARD_J);
break;
default:
break;
}
}
/
//GPIO口初始化
void GPIOInitial(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPION);//
GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0|GPIO_PIN_1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPIOF);//
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPIOM);//
GPIOPinTypeGPIOOutput(GPIO_PORTM_BASE, GPIO_PIN_5);
}
//
//中断初始化
void GPIOIntInitial(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPION);//
GPIOPinTypeGPIOInput(GPIO_PORTN_BASE,GPIO_PIN_4 );
GPIOIntTypeSet(GPIO_PORTN_BASE,GPIO_PIN_4,GPIO_LOW_LEVEL);
GPIOIntEnable(GPIO_PORTN_BASE,GPIO_INT_PIN_4);
}
/
//红外解码
bool getdata()
{
unsigned int i,j,IrAddressData,IrValueData;
volatile uint32_t temp = 0x00;
IrAddressData = 0x00;
IrValueData = 0x00;
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
temp = temp>>1;
while((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
{
}
SysCtlDelay(8*50000000/30000);
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x10)
{
temp = temp|0x80;
while((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x10)
{
count++;
if(count>0x400000)
{
count=0;
return 0;
}
}
}
else
{
temp = temp&0x7f;
}
}
IrData[i] = temp;
}
//abc = IrData[2];
IrAddressData = IrData[0]+IrData[1];
IrValueData = IrData[2]+IrData[3];
if((IrAddressData==0xff)&&(IrValueData==0xff))
return 1;
else
return 0;
}
/
//定时器中断///
void TimerIntInitial(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODIC);
TimerPrescaleSet(TIMER0_BASE,TIMER_B,1500);
TimerLoadSet(TIMER0_BASE, TIMER_B, 30*SysCtlClockGet());
TimerIntEnable(TIMER0_BASE, TIMER_TIMB_TIMEOUT);
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODIC);
TimerPrescaleSet(TIMER1_BASE,TIMER_B,15);
TimerLoadSet(TIMER1_BASE, TIMER_B, SysCtlClockGet());
TimerIntEnable(TIMER1_BASE, TIMER_TIMB_TIMEOUT);
}
void Timer1BIntHandler(void)
{ //volatile uint32_t i;
unsigned long Status;
int ui32Loop;
TimerDisable(TIMER1_BASE, TIMER_B);
Status=TimerIntStatus(TIMER1_BASE,true);
if(Status==TIMER_TIMB_TIMEOUT)
{
if(level==1)
{
I2C0TubeLowSet(0x00);
I2C0TubeHighSet(0x00);
if(flag==0)
{I2C0TubeSelSet(0xf7);
showvalue(((int)(easy_time%100)/10));
flag=1;
}
else
{
I2C0TubeSelSet(0xfb);
showvalue((int)(easy_time/100));
flag=0;;
}
}
else if(level==3)
{
I2C0TubeLowSet(0x00);
I2C0TubeHighSet(0x00);
if(flag==0)
{I2C0TubeSelSet(0xf7);
showvalue(((int)(mid_time%100)/10));
flag=1;
}
else
{
I2C0TubeSelSet(0xfb);
showvalue((int)(mid_time/100));
flag=0;;
}
}
else if(level==9)
{
I2C0TubeLowSet(0x00);
I2C0TubeHighSet(0x00);
if(flag==0)
{I2C0TubeSelSet(0xf7);
showvalue(((int)(hard_time%100)/10));
flag=1;
}
else
{
I2C0TubeSelSet(0xfb);
showvalue((int)(hard_time/100));
flag=0;;
}
}
if((TouchXData[5]>=40)&&(TouchXData[5]<=170)&&(TouchYData[5]<=205)&&(TouchYData[5]>=160)&&(easy_begin==0)&&(hard_begin==0)&&(mid_begin==0))
exit();
if((TouchXData[5]>=40)&&(TouchXData[5]<=170)&&(TouchYData[5]<=255)&&(TouchYData[5]>=206)&&(touch_flag==0))
{
touch_flag=1;
level=1;
easy_begin=1;
IntEnable(INT_TIMER0B);
TimerEnable(TIMER0_BASE, TIMER_B);
TFTLCD_CLEAR(BLACK);
begin(EASY_I,EASY_J);
}
if((TouchXData[5]>=40)&&(TouchXData[5]<=170)&&(TouchYData[5]<=305)&&(TouchYData[5]>=256)&&(touch_flag==0))
{
touch_flag=1;
level=3;
mid_begin=1;
IntEnable(INT_TIMER0B);
TimerEnable(TIMER0_BASE, TIMER_B);
TFTLCD_CLEAR(BLACK);
begin(MID_I,MID_J);
}
if((TouchXData[5]>=40)&&(TouchXData[5]<=170)&&(TouchYData[5]<=360)&&(TouchYData[5]>=306)&&(touch_flag==0))
{
touch_flag=1;
level=9;
hard_begin=1;
IntEnable(INT_TIMER0B);
TimerEnable(TIMER0_BASE, TIMER_B);
TFTLCD_CLEAR(BLACK);
begin(HARD_I,HARD_J);
}
for(ui32Loop=0;ui32Loop<=5;ui32Loop++)
{
SSIDataPut(SSI0_BASE,0x90);
SysCtlDelay(3);
SSIDataGet(SSI0_BASE,&TouchXData[ui32Loop]);
SysCtlDelay(3);
SSIDataPut(SSI0_BASE,0xd0);
SysCtlDelay(3);
SSIDataGet(SSI0_BASE,&TouchYData[ui32Loop]);
SysCtlDelay(3);
}
TouchXData[5] = sort(TouchXData,5); //(TouchXData[0]+TouchXData[1]+TouchXData[2]+TouchXData[3]+TouchXData[4])/5;
TouchYData[5] = sort(TouchYData,5);//(TouchYData[0]+TouchYData[1]+TouchYData[2]+TouchYData[3]+TouchYData[4])/5;
TOUCH_PointAdjust(&TouchXData[5], &TouchYData[5]);
}
TimerIntClear(TIMER1_BASE, Status);
TimerLoadSet(TIMER1_BASE, TIMER_B,SysCtlClockGet() );
TimerEnable(TIMER1_BASE, TIMER_B);
}
void Timer0BIntHandler(void)
{ //volatile uint32_t i;
unsigned long Status;
TimerDisable(TIMER0_BASE, TIMER_B);
Status=TimerIntStatus(TIMER0_BASE,true);
if(Status==TIMER_TIMB_TIMEOUT)
{
time_flag++;
if(level==1)
{
easy_time--;
TFTLCD_ShowData(20,20,(easy_time/10),BLUE,LIGHTBLUE);
if(time_flag>=10)
{
UARTprintf("游戏剩余时间:%d\n",easy_time/10);
time_flag=0;
}
if(easy_time<=0)
{
easy_time = 80;
end_game();
}
}
else if(level==3)
{
mid_time--;
TFTLCD_ShowData(20,20,(mid_time/10),BLUE,LIGHTBLUE);
if(time_flag>=10)
{
UARTprintf("游戏剩余时间:%d\n",mid_time/10);
time_flag=0;
}
if(mid_time<=0)
{
mid_time = 200;
end_game();
}
}
else if(level==9)
{
cake_flag=rand()%200;
switch(cake_flag)
{
case 1 :
piexl_hard[2][7]=3;
piexl_hard[17][4]=1;
piexl_hard[23][7]=1;
TFTLCD_DrawSmallCake(begin_hard_x+15*7,begin_hard_y+2*15);
TFTLCD_FillBlock(begin_hard_x+15*4,begin_hard_x+15*4+16,begin_hard_y+15*17,begin_hard_y+17*15+16,0xFFFF);
TFTLCD_FillBlock(begin_hard_x+15*7,begin_hard_x+15*7+16,begin_hard_y+15*23,begin_hard_y+15*23+16,0xFFFF);
break;
case 2 :
piexl_hard[2][7]=1;
piexl_hard[17][4]=3;
piexl_hard[23][7]=1;
TFTLCD_DrawSmallCake(begin_hard_x+15*4,begin_hard_y+17*15);
TFTLCD_FillBlock(begin_hard_x+15*7,begin_hard_x+15*7+16,begin_hard_y+15*23,begin_hard_y+15*23+16,0xFFFF);
TFTLCD_FillBlock(begin_hard_x+15*7,begin_hard_x+15*7+16,begin_hard_y+15*2,begin_hard_y+15*2+16,0xFFFF);
break;
case 3 :
piexl_hard[2][7]=1;
piexl_hard[17][4]=1;
piexl_hard[23][7]=3;
TFTLCD_DrawSmallCake(begin_hard_x+15*7,begin_hard_y+23*15);
TFTLCD_FillBlock(begin_hard_x+15*4,begin_hard_x+15*4+16,begin_hard_y+15*17,begin_hard_y+17*15+16,0xFFFF);
TFTLCD_FillBlock(begin_hard_x+15*7,begin_hard_x+15*7+16,begin_hard_y+15*2,begin_hard_y+15*2+16,0xFFFF);
break;
default :break;
}
hard_time--;
TFTLCD_ShowData(176,60,(hard_time/10),BLUE,LIGHTBLUE);
if(time_flag>=10)
{
UARTprintf("游戏剩余时间:%d\n",hard_time/10);
time_flag=0;
}
if(hard_time<=0)
{
hard_time = 600;
end_game();
}
}
}
TimerIntClear(TIMER0_BASE, Status);
TimerLoadSet(TIMER0_BASE, TIMER_B,30*SysCtlClockGet() );
TimerEnable(TIMER0_BASE, TIMER_B);
}
//中断
void GPION(void)
{
volatile uint32_t LowTime,HighTime;
unsigned long Status;
LowTime = 0;
HighTime = 0;
IntDisable(INT_GPION);
Status = GPIOIntStatus(GPIO_PORTN_BASE,true);
if(Status==GPIO_INT_PIN_4)
{
SysCtlDelay(4*50000000/3000);
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
{
LowTime = 1;
while((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
{
}
}
else
LowTime = 0;
SysCtlDelay(3*50000000/3000);
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x10)
{
HighTime = 1;
while((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x10)
{
count++;
if(count>0x100000)
{
count=0;
//return 0;
}
}
}
else
HighTime = 0;
if((HighTime==1)&&(LowTime==1))
{
if(getdata()==1)
{
IrOutput();
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 , 0x02);
SysCtlDelay(500*(50000000/3000));//2
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 , 0x00);
SysCtlDelay(500*(50000000/3000));//2
}
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 , 0x02);
SysCtlDelay(500*(50000000/3000));
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 , 0x00);
SysCtlDelay(500*(50000000/3000));
}
}
SysCtlDelay(50000000/3);
GPIOIntClear(GPIO_PORTN_BASE,Status);
}
**********************************************************************
void I2C0PinConfig(void) //配置I2C0模块的IO引脚,使其工作于开漏模式下
{ // Enable GPIO portB containing the I2C pins (PB2&PB3)
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
// GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_2|GPIO_PIN_3);
// GPIOPinConfigure(GPIO_PB2_I2C0SCL);
}
//
// //********预设码段值,方便查找************************************************
static const char tubeCodeTable[14][2]=
{ // SegmLow, SegHigh
{ 0x10, 0x3E }, // 0
{ 0x00, 0x18 }, // 1
{ 0x70, 0x2C }, // 2
{ 0x70, 0x26 }, // 3
{ 0x60, 0x32 }, // 4
{ 0x70, 0x16 }, // 5
{ 0x70, 0x1E }, // 6
{ 0x00, 0x26 }, // 7
{ 0x70, 0x3E }, // 8
{ 0x70, 0x36 }, // 9
{ 0x60, 0x3E }, // a
{ 0x70, 0x3E }, // b
{ 0x10, 0x1C }, // c
{ 0x10, 0x3E }, // d
//{ 0x00, 0x00 }, // d
};
//
//
unsigned char a[2];
//
void setnumber(char value)
{
char b;
b=value;
switch(b){
case 0:{ a[0]=tubeCodeTable[0][0];a[1]=tubeCodeTable[0][1];break;}
case 1:{ a[0]=tubeCodeTable[1][0];a[1]=tubeCodeTable[1][1];break;}
case 2:{ a[0]=tubeCodeTable[2][0];a[1]=tubeCodeTable[2][1];break;}
case 3:{ a[0]=tubeCodeTable[3][0];a[1]=tubeCodeTable[3][1];break;}
case 4:{ a[0]=tubeCodeTable[4][0];a[1]=tubeCodeTable[4][1];break;}
case 5:{ a[0]=tubeCodeTable[5][0];a[1]=tubeCodeTable[5][1];break;}
case 6:{ a[0]=tubeCodeTable[6][0];a[1]=tubeCodeTable[6][1];break;}
case 7:{ a[0]=tubeCodeTable[7][0];a[1]=tubeCodeTable[7][1];break;}
case 8:{ a[0]=tubeCodeTable[8][0];a[1]=tubeCodeTable[8][1];break;}
case 9:{ a[0]=tubeCodeTable[9][0];a[1]=tubeCodeTable[9][1];break;}
case 10:{ a[0]=tubeCodeTable[10][0];a[1]=tubeCodeTable[10][1];break;}
case 11:{ a[0]=tubeCodeTable[11][0];a[1]=tubeCodeTable[11][1];break;}
case 12:{ a[0]=tubeCodeTable[12][0];a[1]=tubeCodeTable[12][1];break;}
case 13:{ a[0]=tubeCodeTable[13][0];a[1]=tubeCodeTable[13][1];break;}
//case 14:{ a[0]=tubeCodeTable[14][0];a[1]=tubeCodeTable[14][1];break;}
}
}
unsigned char I2C_RECV_DATA[] =
{
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
/*******************************************
拉高 SDA 信号
********************************************/
void I2C_Set_sda_high( void )
{
GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_3,GPIO_PIN_3); //拉高PB3
_NOP();
_NOP();
return;
}
/*******************************************
拉低SDA 信号
********************************************/
void I2C_Set_sda_low ( void )
{
GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_3,0X00000000); //拉低PB3
_NOP();
_NOP();
return;
}
/*******************************************
拉高SCL 信号
********************************************/
void I2C_Set_scl_high( void )
{
GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2); //拉高PB2
_NOP();
_NOP();
return;
}
/*******************************************
拉低SCL 信号
********************************************/
void I2C_Set_scl_low ( void )
{
GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,0X00000000); //拉低PB2
_NOP();
_NOP();
return;
}
/*******************************************
IIC 信号结束信号函数
********************************************/
void I2C_STOP(void)
{
int i;
I2C_Set_sda_low();
for(i = NUM;i > 0;i--);
I2C_Set_scl_low();
for(i = NUM;i > 0;i--);
I2C_Set_scl_high();
for(i = NUM;i > 0;i--);
I2C_Set_sda_high();
for(i = NUM+1;i > 0;i--);
return;
}
/*******************************************
IIC 信号初始化
********************************************/
void I2C_Initial( void )
{
I2C_Set_scl_low();
I2C_STOP();
return;
}
/*******************************************
IIC 信号起始信号函数
********************************************/
void I2C_START(void)
{
int i;
I2C_Set_sda_high();
for(i = NUM;i > 0;i--);
I2C_Set_scl_high();
for(i = NUM;i > 0;i--);
I2C_Set_sda_low();
for(i = NUM;i > 0;i--);
I2C_Set_scl_low();
return;
}
/*******************************************
IIC 获取应答函数
********************************************/
int I2C_GetACK(void)
{
int j;
_NOP();
_NOP();
I2C_Set_scl_low();
for(j = NUM;j> 0;j--);
I2C_Set_scl_high();
for(j = NUM;j> 0;j--);
I2C_Set_sda_low();
for(j = NUM;j > 0;j--);
I2C_Set_scl_low();
return 1;
}
/*******************************************
IIC 设置应答函数
********************************************/
void I2C_SetNAk(void)
{
I2C_Set_scl_low();
I2C_Set_sda_high();
I2C_Set_scl_high();
I2C_Set_scl_low();
return;
}
/*******************************************
IIC 发送字节函数
参数 1:要发送字节值
return :无返回
********************************************/
void I2C_TxByte(unsigned char nValue)
{
int i;
int j;
for(i = 0;i < 8;i++)
{
if(nValue & 0x80)
I2C_Set_sda_high();
else
I2C_Set_sda_low();
for(j = NUM;j > 0;j--);
I2C_Set_scl_high();
nValue <<= 1;
for(j = NUM;j > 0;j--);
I2C_Set_scl_low();
}
return;
}
/*******************************************
IIC 接收字节函数
参数 无
return :无返回
********************************************/
unsigned char I2C_RxByte(void)
{
GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_3);//配置PB3为输入口
unsigned char nTemp=0 ;
int i;
I2C_Set_sda_high();
_NOP();
_NOP();
_NOP();
_NOP();
for(i = 0;i < 8;i++)
{
I2C_Set_scl_high(); //模拟SCL信号
if(GPIOPinRead(GPIO_PORTB_BASE,GPIO_PIN_3) == 0x18) //依次判断PB3(SDA)输入
{
nTemp |= (0x01 << (7-i)); //8位SDA数据哪一位为高就置1
}
I2C_Set_scl_low();
//Delay5us();
}
return nTemp;
}
/*******************************************
IIC 发送数组函数
参数 1 num : 发送字节数
2 device_addr : iic目标地址
3 *data:发送数组地址
return :无返回
********************************************/
void i2c_write(int num, unsigned char device_addr,unsigned char *data)
{
int i = 0;
int count = num;
unsigned char *send_data = data;
unsigned char write_addr = device_addr;
I2C_Set_scl_high();
for(i = NUM;i > 0;i--);
I2C_Set_sda_high();
for(i = NUM;i > 0;i--);
for(i = 0;i
{
I2C_START(); //模拟I2C写数据的时序
I2C_TxByte(write_addr);
I2C_GetACK();
I2C_TxByte(send_data[i]);
I2C_GetACK();
i++;
I2C_TxByte(send_data[i]);
I2C_GetACK();
I2C_STOP();
}
}
/*******************************************
IIC 读取数组函数
参数 1 num : 发送字节数
2 device_addr : iic目标地址
3 *data:接收数组地址
return :无返回
********************************************/
void i2c_read(int num, unsigned char device_addr,unsigned char *data)
{
int i = 0;
int count = num;
unsigned char *send_data = data;
unsigned char read_addr = device_addr;
I2C_Set_scl_high();
for(i = NUM;i > 0;i--);
I2C_Set_sda_high();
for(i = NUM;i > 0;i--);
for(i = 0; i < count;i++)
{
I2C_START(); //模拟I2C读数据
I2C_TxByte((read_addr - 1));
I2C_GetACK();
I2C_TxByte(send_data[2*i]);
I2C_GetACK();
I2C_START();
I2C_TxByte(read_addr);
I2C_GetACK();
I2C_RECV_DATA[i] = I2C_RxByte();
data[2*i+1]=I2C_RECV_DATA[i];
I2C_SetNAk();
I2C_STOP();
}
}
//*********************************************************************
//*********************************************************************
//******配置I2C0模块的IO引脚,**********************************************
void I2C0GPIOBEnable(void)
{// Enable GPIO portB containing the I2C pins (PB2&PB3)
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_2|GPIO_PIN_3);
}
******配置PCA9557芯片中连接米字管的各引脚为输出***********************************
void I2C0DeviceInit(void)
{
unsigned char dataBuf[2] = {PCA9557_REG_CONFIG, 0x00};
i2c_write(2,I2C0_ADDR_TUBE_SEL,dataBuf);
i2c_write(2,I2C0_ADDR_TUBE_SEG_LOW,dataBuf);
i2c_write(2,I2C0_ADDR_TUBE_SEG_HIGH,dataBuf);
}
//*******设置米字管的管选信号**************************************************
void I2C0TubeSelSet(char data)
{ //选择1、2、3、4、5哪个米字管亮
unsigned char dataBuf[2] = {PCA9557_REG_OUTPUT, data};
i2c_write(2,I2C0_ADDR_TUBE_SEL,dataBuf);
}
//*******点亮米字管的相应码段**************************************************
void I2C0TubeLowSet(char data)
{ //点亮7-14管脚对应的码段
unsigned char dataBuf[2] = {PCA9557_REG_OUTPUT, data};
i2c_write(2,I2C0_ADDR_TUBE_SEG_LOW,dataBuf);
}
void I2C0TubeHighSet(char data)
{ //点亮15-18管脚对应的码段
unsigned char dataBuf[2] = {PCA9557_REG_OUTPUT, data};
i2c_write(2,I2C0_ADDR_TUBE_SEG_HIGH,dataBuf);
}
void I2C0Tubeset(void)
{
I2C0TubeLowSet(a[0]);
I2C0TubeHighSet(a[1]);
}
void showvalue(char value)
{
setnumber(value);
I2C0Tubeset();
}
uint32_t sort(uint32_t a[],uint32_t b)
{
int i,j;
for(i=0;i
for(j=0;j
return a[(b-1)/2];
}
void
ConfigureUART(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioConfig(0, 115200, g_ui32SysClock);
}
void main()
{
uint16_t ui32Loop = 0;
g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480), 50000000);
TFT_400x240_OTM4001Ainit(g_ui32SysClock);
SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480), 50000000);
GPIOIntInitial();
GPIOInitial();
TimerIntInitial();
IntPrioritySet(INT_GPION, 0x20);
IntPrioritySet(INT_TIMER1B, 0x30);
IntPrioritySet(INT_TIMER0B, 0x40);
IntEnable(INT_GPION);
IntEnable(INT_TIMER1B);
IntMasterEnable();
TimerEnable(TIMER1_BASE, TIMER_B);
I2C0PinConfig();
I2C0DeviceInit();//配置PCA9557芯片中连接米字管的各引脚为输出
I2C0TubeSelSet(0xf7);
showvalue(0);
FPUEnable();
FPULazyStackingEnable();
//
// Run from the PLL at 120 MHz.
//
ConfigureUART();
EPIGPIOinit();
TOUCH_TSC2046init(g_ui32SysClock);
GPIOIntEnable(GPIO_PORTB_BASE,GPIO_INT_PIN_0);
GPIOIntTypeSet(GPIO_PORTB_BASE,GPIO_PIN_0,GPIO_FALLING_EDGE);
UARTprintf("准备开始游戏 !(老鼠吃蛋糕)\n");
TFT_400x240_OTM4001Ainit(g_ui32SysClock);
exit();
SSIDataPut(SSI0_BASE,0xd0);
while(1)
{
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
{
SysCtlDelay(3*50000000/3000);
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
IntEnable(INT_GPION);
}
}
}