本帖最后由 shenzhigang 于 2011-12-8 23:16 编辑
LM3S811使用心得
基于EK-LM3S811+12864实现贪吃蛇
中断设置:在start.s中找到
DCD
IntDefaultHandler
; SysTick Handler
将其替换为:
extern
SysTick_ISR
DCD
SysTick_ISR
源代码:
//
main.c
#include "12864.h"
#include "sysinit.h"
unsigned long TheSysClock = 12000000UL;
/*
定义全局系统时钟变量
*/
void SnakeStart(void);
void SnakeGo(void);
void Rand(void);
/*
伪随机点产生函数
*/
int main(void)
{
//液晶接口
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/*
使能GPIOA
*/
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOD );
/*
GPIOD为液晶数据接口
GPIOA为液晶控制接口
*/
GPIOPinTypeGPIOOutput( GPIO_PORTA_BASE, 0x0f);
GPIOPadConfigSet( GPIO_PORTA_BASE,
0x0f, GPIO_STRENGTH_8MA,
GPIO_PIN_TYPE_STD_WPU);
GPIOPinTypeGPIOOutput( GPIO_PORTD_BASE, 0xff);
GPIOPadConfigSet( GPIO_PORTD_BASE,
0xff, GPIO_STRENGTH_8MA,
GPIO_PIN_TYPE_STD_WPU);
SysCtlLDOSet(SYSCTL_LDO_2_75V);
// 配置PLL前须将LDO设为2.75V
SysCtlClockSet( SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ | SYSCTL_SYSDIV_4 );
//PLL倍频200M
四分频为50M
M3最高频率
TheSysClock = SysCtlClockGet( );
// 获取当前的系统时钟频率
SysCtlDelay( 500000 );
jtagWait();
/*
防止J_TAG死锁程序
*/
SnakeStart();
/*
启动游戏
*/
sysTickInit();
/*
系统时钟初始化
*/
//
Timer0A_ISR_Init();
/*
timer0A初始化
*/
for(;;)
{
Rand();
SnakeGo();
SysCtlDelay( 850000-(snake.node-10)*4000 );
/*
减去由于蛇身的增长而增加的延时
*/
}
}
void Rand(void)
{
rand_x+=1;rand_y+=1;
if( rand_x>63 ) rand_x=2;
/*
随机点坐标 x(2~63)
*/
if( rand_y>127 ) rand_y=2;
/*
随机点坐标 y(2~127)
*/
if( food.yes==1 )
{
snake.node++;
/*
没吃到一个点 长度加一
*/
snake.X[snake.node-1]=randx;
/*
增加点得坐标即为食物坐标
*/
snake.Y[snake.node-1]=randy;
randx=rand_x;randy=rand_y;
/*
保存以判断是否吃到
*/
GUI_point( rand_x,rand_y,1 );
/*
画出一个新点
*/
food.yes=0;
}
}
void SnakeStart()
{
char
i;
unsigned char x_1=32;
unsigned char y_1=1;
LcdInit();
/*
12864液晶屏初始化
*/
SysCtlDelay( 1600 );
clear_img();
SysCtlDelay( 1600 );
GUI_line(1,1,1,128,1);
/*
下面为四行画线代码为外框
*/
SysCtlDelay( 160 );
GUI_line(1,128,64,128,1);
SysCtlDelay( 160 );
GUI_line(64,128,64,1,1);
SysCtlDelay( 160 );
GUI_line(64,1,1,1,1);
SysCtlDelay( 160 );
/*
清一下屏幕中间
*/
String(2,2,"
");
SysCtlDelay( 160 );
String(3,1,"
");
SysCtlDelay( 160 );
String(4,2,"
");
SysCtlDelay( 160 );
for(i=0;i<10;i++)
/*
初始化十个点
*/
{
snake.X=x_1;
snake.Y=++y_1;
GUI_point(snake.X,snake.Y,1);
SysCtlDelay( 160 );
}
/*
初始状态
*/
SS=Right;
/*
初始状态
*/
snake.state=Right;
/*
初始没有食物产生标志
*/
food.yes=0;
/*
初始蛇活
*/
snake.life=0;
/*
初始结点长度
*/
snake.node=10;
GUI_point( randx,randy,1 );
SysCtlDelay( 160 );
}
void SnakeGo()
{
int j;
if( !snake.life )
/*
如果没有越界与犯规 则进入此内*/
{
GUI_point(snake.X[0],snake.Y[0],0);
/*
向前走一步 要清除最后一个点
*/
for(j=1;j<snake.node;j++)
/*
整体向前走一步
*/
{
snake.X[j-1]=snake.X[j];
snake.Y[j-1]=snake.Y[j];
GUI_point(snake.X[j-1],snake.Y[j-1],1);
}
/*
蛇头将要移动的方向
*/
switch( SS )
{
case Up:
snake.X[snake.node-1]--;
break;
case Down: snake.X[snake.node-1]++;
break;
case Left: snake.Y[snake.node-1]--;
break;
case Right: snake.Y[snake.node-1]++;
break;
default:
break;
}
GUI_point(snake.X[snake.node-1],snake.Y[snake.node-1],1);
/*
画出蛇头那个点
*/
SysCtlDelay( 160 );
}
if( snake.life )
/*
如果是越界或犯规则结束进入此 */
{
SysTickIntDisable();
clear_img();
SysCtlDelay( 1600 );
String(2,2," GAME OVER");
SysCtlDelay( 160 );
String(3,1," press any key ");
SysCtlDelay( 160 );
String(4,2,"to replay! ");
SysCtlDelay( 160 );
GUI_line(1,1,1,128,1);
/*
下面为四行画线代码为外框
*/
SysCtlDelay( 160 );
GUI_line(1,128,64,128,1);
SysCtlDelay( 160 );
GUI_line(64,128,64,1,1);
SysCtlDelay( 160 );
GUI_line(64,1,1,1,1);
SysCtlDelay( 160 );
while( snake.life )
{
SS=0;
snake.state=0;
if( KeyCheck()!=0 )
{
SnakeStart();
/*
重新启动游戏
*/
}
}
SysTickIntEnable();
}
}
void SysTick_ISR(void)
/*
系统时钟函数
*/
{
SysTickIntDisable();
/*
除能系统时钟中断
*/
snake.state = KeyCheck();
/*
按键扫描
*/
snake.life = ( snake.X[snake.node-1]==64
|| snake.Y[snake.node-1]==128
|| snake.Y[snake.node-1]==1
|| snake.X[snake.node-1]==1
);
/*
吃掉点后
产生标志信号
*/
for(k=snake.node-4;k>=0;k--)
/*
判断是否和自身相撞
*/
{
if( snake.X[snake.node-1]==snake.X[k] && snake.Y[snake.node-1]==snake.Y[k] )
{
snake.life=1;
break;
}
}
food.yes = ( snake.X[snake.node-1]==randx && snake.Y[snake.node-1]==randy );
SysTickIntEnable();
/*
使能系统时钟中断
*/
} |