嵌入式系统概论综合设计报告书.docx
《嵌入式系统概论综合设计报告书.docx》由会员分享,可在线阅读,更多相关《嵌入式系统概论综合设计报告书.docx(24页珍藏版)》请在冰豆网上搜索。
![嵌入式系统概论综合设计报告书.docx](https://file1.bdocx.com/fileroot1/2023-1/31/135af8d6-8204-44ff-9520-de51755bced0/135af8d6-8204-44ff-9520-de51755bced01.gif)
嵌入式系统概论综合设计报告书
《嵌入式系统概论》综合设计报告书
设计题目:
基于嵌入式Linux点阵和键盘的贪吃蛇游戏
学院:
信息工程学院
班级:
学号:
姓名:
指导老师:
中央民族大学
二零一三年十二月二十七日
一、设计目的
1、学习了解Linux系统各组成部分的作用以及Linux系统LED点阵驱动和键盘驱动程序的编写;
2、熟悉基本的嵌入式开发过程,进一步掌握Linux下的C语言以及深入理解嵌入式Linux系统编程的步骤;
3、以PXA270EP实验板为基础,用C语言编写贪吃蛇游戏的应用程序实现通过控制8*8LED点阵中各灯亮暗来进行游戏操作。
二、设计内容
1、设计原理:
(1)8X8点阵数码管发光原理:
从图中可以看出,8X8点阵共需要64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上。
当对应的某一列置1电平,某一行置0电平,则相应的二极管就亮;因此要实现一根柱形的亮法,如下图所示,对应的一列为一根竖柱,或者对应的一行为一根横柱,因此实现柱的亮的方法如下所述:
(图1)
(图2)
系统电路如上图2所示。
显示部分用的是一个8×8发光二极管点阵,我们常见的用于发布消息、显示汉字的点阵式LED显示屏通常由若干块LED点阵显示模块组成,8×8显示点阵模块,每块有64个独立的发光二极管,为了减少引脚且便于封装,各种LED显示点阵模块都采用阵列形式排布,即在行列线的交点处接有显示LED。
在本开发板上,整个LED显示模块是作为一个I/O进行控制的。
如电路原理图所示,DATA[0..7],DATA[8..15]分别对应系统数据线的低16位,LED_LOCK信号是由系统总线的写信号和地址信号经简单的逻辑组合而得,在板载的CPLD内完成,控制该显示模块的I/O地址为0x08000000。
(2)目标板的键盘驱动原理:
键盘的结构通常有两种形式:
线性键盘和矩阵键盘。
在不同的场合下,这两种键盘均得到了广泛的应用。
线性键盘由若干个独立的按键组成,每个按键的一端与微机的一个I/O口相连。
有多少个键就要有多少根连线与微机的I/O口相连,因此,只适用于按键少的场合。
矩阵键盘的按键按N行M列排列,每个按键占据行列的一个交点,需要的I/O口数目是N+M,容许的最大按键数是N×M。
显然,矩阵键盘可以减少与微机接口的连线数、简化结构,是一般微机常用的键盘结构。
根据矩阵键盘的识键和译键方法的不同,矩阵键盘又可以分为非编码键盘和编码键盘两种。
非编码键盘:
非编码键盘主要用软件的方法识键和译键。
根据扫描方法的不同,可以分为行扫描法、列扫描法和反转法三种。
编码键盘:
编码键盘主要用硬件来实现键的扫描和识别,通常使用8279专用接口芯片,在硬件上要求较高。
PXA270EP采用的是4×6的矩阵键盘。
其原理图如图3:
(图3)
键盘扫描程序的流程图如图4:
(图4)
(图5)
(图6)
如图5为键盘的真实布线图,如图6只是将线拉直,以便您更好的理解程序扫描所代表的含义,我们说,若要让程序确定您所按下的键是哪个,分别是要在扫描四列四行后,然后再通过扫描所得数据来判断具体是哪个键。
程序是先扫描第0列,依次第1列,第2列,第3列。
在扫描第0列的过程中,再先后扫描第0行,第1行,第2行,第3行,第4行,第5行。
若在扫描完第0列后,没有扫描到任何键按下。
则再扫描第1列,在这过程中,再先后扫描第0行,第1行,第2行,第3行,第4行,第5行。
若在扫描完第1列后,没有扫描到任何键按下。
则再扫描第2列,在这过程中,再先后扫描第0行,第1行,第2行,第3行,第4行,第5行。
若在扫描完第2列后,没有扫描到任何键按下。
则再扫描第3列,在这过程中,再先后扫描第0行,第1行,第2行,第3行,第4行,第5行。
在扫描过程中,只要在符合某种条件下,则会停止后续列的扫描操作,而退出程序。
通过上面二维表19~1判断,将定您现在按下数字9键,则此时对应In1位为0,且Out2位为0。
若您按下数字2键,则此时对应的In2位为0,且Out4位为0。
其它按键的判断结果是以相同的方法判断。
In3,In2,In1,In0的值是通过outbyte=值,outb(outbyte,ioremap_addr)来指定值。
Out5,Out4,Out3,Out2,Out1,Out0的值是通过函数inbyte=inb(ioremap_addr)来获取。
例如:
outbyte=0xfe;outb(outbyte,ioremap_addr);则:
。
。
。
。
In3In2In1In0
11111110
此时:
通过inbyte=inb(ioremap_addr)获取值,若读出的值为inbyte=0xef,则:
。
。
Out5Out4Out3Out2Out1Out0
11101111
很显然,这时有In0=0,Out4=0,所以查表,此时,系统判断应该是Enter键被按下。
2、设计过程:
根据对贪吃蛇游戏结构和步骤的分析设计出相应的贪吃蛇流程,设计在目标板上的8*8LED点阵上显示贪吃蛇游戏的主要过程包括:
(1)游戏开始(有3、2、1倒计时的显示);
(2)随机出现食物,定点出现初始贪吃蛇;
(3)贪吃蛇移动;
(4)贪吃蛇吃食物;
(5)暂停游戏;
(6)恢复游戏;
(7)贪吃蛇碰边界游戏结束重新开始;
(8)数码管显示分数。
三、设计方案
1、贪吃蛇游戏源程序如下:
#include
#include
#include
//#include///开线程
#include//open()close()
#include//read()write()
#defineDEVICE_NAME"/dev/led_ary_ctl"
#include
#defineDEVICE_NAME1"/dev/keypad"
#defineDEVICE_NAME_SERIAL_LED"/dev/serial_led"
unsignedshortpo[8]={1,2,4,8,16,32,64,128};
//pthread_ttid;
intfd_led,fd_key;
intscore;
unsignedshortout[64];//表示8*8点阵
shortgetx(shortz)
{
returnz%8;
}
shortgetz(shortx,shorty)
{
returnx+(y<<3);//x+y*8
}
unsignedshortck;//ck置为3时,暂停游戏;如果蛇正常的移动了一步,它的值置为0;若蛇死了,它的值置为1;若蛇吃了某个食物,它的值置为2
unsignedshortfx;//行进方向0123上下左右
unsignedshortfod;//food
shortscd;//蛇长度
typedefstructsn
{
shortwzz;//位置z坐标
structsn*nxt;//下一个位置
}Snk;
Snk*stz;//蛇头坐标
intgetrandom(intmax)//取得在[0,max]的随机整数
{
intnum=-1;
intran;
while(num<0)
num=rand();
ran=num%(max+1);//取余得随机数法
returnran;
}//01
voidledouta(shortx,shorty)//x表示行号y表示该行亮的灯的编码,例子:
x=0y=3则第一行第0,1个亮,x-[0,7],y[0-255]
{
//intfd;
//intret;
unsignedcharbuf[2];
buf[0]=(y);
buf[1]=~(1<return;
}
voidledout()
{
shorti,j;shortlia;
for(i=0;i<8;i++)
{
lia=0;
for(j=0;j<8;j++)
{
if(out[getz(j,i)]==1)
{
lia+=po[j];
}
}
ledouta(i,lia);
}
}
voidserialled(intcount)
{
intfd;
intret;
//0123456789
intbuf[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
intdata[2];
fd=open(DEVICE_NAME_SERIAL_LED,O_RDWR);
if(fd==-1)
{
printf("opendevice%serror\n",DEVICE_NAME_SERIAL_LED);
}
else
{
if(count>=10)
{
data[0]=0x00;
ret=write(fd,data,1);
ret=write(fd,data,1);
data[0]=buf[count/10];
ret=write(fd,data,1);
data[0]=buf[count%10];
ret=write(fd,data,1);
}
else
{if(count<0){
data[0]=0x00;
ret=write(fd,data,1);
ret=write(fd,data,1);
printf("==================================");
data[0]=0x40;
ret=write(fd,data,1);
data[0]=buf[0-count];
ret=write(fd,data,1);}
else{
data[0]=0x00;
ret=write(fd,data,1);
ret=write(fd,data,1);
ret=write(fd,data,1);
data[0]=buf[count];
ret=write(fd,data,1);}
}
}
ret=close(fd);
}
voidin_it()//初始化全局变量
{
shorti;
for(i=0;i<64;i++)
{
out[i]=0;
}
//ck=1;
ck=0;
stz=(Snk*)malloc(sizeof(Snk));
stz->nxt=NULL;
stz->wzz=0;
}
voidloadsnk()//per显示蛇
{
Snk*tmp;
tmp=stz;
while(tmp->nxt!
=NULL)
{
out[tmp->wzz]=1;
tmp=tmp->nxt;
}
}
voidnewfood()//per显示食物,也可以理解为产生食物
{
shortran;
ran=46;/////////////////////////////////
while
(1)
{
if(out[ran]!
=1)
{
out[ran]=1;
fod=ran;
return;
}
else
{
ran=getrandom(63);
}
}
}
voiddspl()//display
{
loadsnk();
}
voidinitGame()//初始化游戏
{
in_it();
score=0;
fx=3;
scd=3;
stz->wzz=getz(2,5);//初始化蛇头位置;
stz->nxt=(Snk*)malloc(sizeof(Snk));
stz->nxt->wzz=getz(1,5);
stz->nxt->nxt=(Snk*)malloc(sizeof(Snk));
stz->nxt->nxt->wzz=getz(0,5);
stz->nxt->nxt->nxt=NULL;
loadsnk();
newfood();
serialled(score);
}
voiderro()
{
printf("---ERROR---\n");
ck=0;
}
voideat()
{
printf("---EATFOOD---\n");
scd++;
newfood();
score++;
serialled(score);
}
voiddie()
{
printf("---GAMEOVER---\n");
ck=0;
Snk*tmp;
tmp=stz;
stz=stz->nxt;
while(stz->nxt!
=NULL)
{
free(tmp);
tmp=stz;
stz=stz->nxt;
}
free(tmp);
free(stz);
}
shortmove()//正常返回0,死了返回1,吃了返回2
{
Snk*nst,*tmp;
nst=(Snk*)malloc(sizeof(Snk));
nst->nxt=stz;
switch(fx)//方向
{
case0:
{
nst->wzz=stz->wzz-8;
if(nst->wzz<0)
{die();return1;}
break;}
case1:
{nst->wzz=stz->wzz+8;if(nst->wzz>63){die();return1;}break;}
case2:
{nst->wzz=stz->wzz-1;if((nst->wzz)%8==7||nst->wzz<0){die();return1;}break;}
case3:
{nst->wzz=stz->wzz+1;if((nst->wzz)%8==0){die();return1;}break;}
default:
erro();
}
stz=nst;
if(stz->wzz==fod)//吃了
{
eat();
return2;
}
else
{
if(out[stz->wzz]==1)//吃了自己
{
die();
return1;
}
}
nst=stz->nxt;
tmp=stz;
while(nst->nxt!
=NULL)
{
tmp=nst;
nst=nst->nxt;
}
out[tmp->nxt->wzz]=0;
free(tmp->nxt);
tmp->nxt=NULL;
return0;
}
voidto_up()
{
fx=0;
}
voidto_down()
{
fx=1;
}
voidto_lift()
{
fx=2;
}
voidto_right()
{
fx=3;
}
voidreset()
{
initGame();
}
voidds3()//显示3
{
out[0]=0;out[1]=1;out[2]=1;out[3]=1;out[4]=1;out[5]=1;out[6]=1;out[7]=0;
out[8]=0;out[9]=0;out[10]=0;out[11]=0;out[12]=0;out[13]=0;out[14]=1;out[15]=0;
out[16]=0;out[17]=0;out[18]=0;out[19]=0;out[20]=0;out[21]=0;out[22]=1;out[23]=0;
out[24]=0;out[25]=1;out[26]=1;out[27]=1;out[28]=1;out[29]=1;out[30]=1;out[31]=0;
out[32]=0;out[33]=0;out[34]=0;out[35]=0;out[36]=0;out[37]=0;out[38]=1;out[39]=0;
out[40]=0;out[41]=0;out[42]=0;out[43]=0;out[44]=0;out[45]=0;out[46]=1;out[47]=0;
out[48]=0;out[49]=0;out[50]=0;out[51]=0;out[52]=0;out[53]=0;out[54]=1;out[55]=0;
out[56]=0;out[57]=1;out[58]=1;out[59]=1;out[60]=1;out[61]=1;out[62]=1;out[63]=0;
}
voidds2()
{
out[0]=0;out[1]=1;out[2]=1;out[3]=1;out[4]=1;out[5]=1;out[6]=1;out[7]=0;
out[8]=0;out[9]=0;out[10]=0;out[11]=0;out[12]=0;out[13]=0;out[14]=1;out[15]=0;
out[16]=0;out[17]=0;out[18]=0;out[19]=0;out[20]=0;out[21]=0;out[22]=1;out[23]=0;
out[24]=0;out[25]=1;out[26]=1;out[27]=1;out[28]=1;out[29]=1;out[30]=1;out[31]=0;
out[32]=0;out[33]=1;out[34]=0;out[35]=0;out[36]=0;out[37]=0;out[38]=0;out[39]=0;
out[40]=0;out[41]=1;out[42]=0;out[43]=0;out[44]=0;out[45]=0;out[46]=0;out[47]=0;
out[48]=0;out[49]=1;out[50]=0;out[51]=0;out[52]=0;out[53]=0;out[54]=0;out[55]=0;
out[56]=0;out[57]=1;out[58]=1;out[59]=1;out[60]=1;out[61]=1;out[62]=1;out[63]=0;
}
voidds1()
{
out[0]=0;out[1]=0;out[2]=0;out[3]=0;out[4]=1;out[5]=0;out[6]=0;out[7]=0;
out[8]=0;out[9]=0;out[10]=0;out[11]=1;out[12]=1;out[13]=0;out[14]=0;out[15]=0;
out[16]=0;out[17]=0;out[18]=0;out[19]=0;out[20]=1;out[21]=0;out[22]=0;out[23]=0;
out[24]=0;out[25]=0;out[26]=0;out[27]=0;out[28]=1;out[29]=0;out[30]=0;out[31]=0;
out[32]=0;out[33]=0;out[34]=0;out[35]=0;out[36]=1;out[37]=0;out[38]=0;out[39]=0;
out[40]=0;out[41]=0;out[42]=0;out[43]=0;out[44]=1;out[45]=0;out[46]=0;out[47]=0;
out[48]=0;out[49]=0;out[50]=0;out[51]=0;out[52]=1;out[53]=0;out[54]=0;out[55]=0;
out[56]=0;out[57]=0;out[58]=0;out[59]=1;out[60]=1;out[61]=1;out[62]=0;out[63]=0;
}
voidrepat_dis(inttimes)
{
inti;
for(i=0;iledout();
}
voiddisplay_321()
{
ds3();
repat_dis(10);
ds2();
repat_dis(10);
ds1();
repat_dis(10);
}
voidpause1()
{
ck=3;
}
voidresume1()
{
ck=0;
}
intmain(void)
{
inti=4;
intret_led,ret_key;
unsignedcharbuf[2];
doublex;
charpre_scancode=0xff;
//fd=open(DEVICE_NAME1,O_RDWR);
fd_led=open(DEVICE_NAME,O_RDWR);
fd_key=open(DEVICE_NAME1,O_RDWR);
if(fd_key==-1)
{
printf("opendevice%serror\n",DEVICE_NAME1);
}
elseif(fd_led==-1)
{
printf("opendevice%serror\n",DEVICE_NAME);
}
else
{
buf[0]=0x22;
reset();
dspl();
ledout();
while
(1)
{
if(ck==0||ck==2)
{
if(i==4)
{
i=0;
ck=move();
}
i++;
//usleep(100000);
read(fd_key,buf,1);
if(buf[0]!
=pre_scancode)
{
if(buf[0]!
=0xff)
{
switch(buf[0])
{
case0x08:
to_up();break;
case0x04:
to_lift();break;
case0x05:
to_down();break;
case0x06:
to_right();break