先等上来一个文件,还有几个以后登。算法参考了毛建忠的ToyBricks.c,在此表示感谢。
#include "Lcd_ks0108.h"
#define LINE 12//12行
#define ROW 8//8列
volatile unsigned char Block_Old[4][2],Block_Now[4][2];//记录方块原先的位置和现在的位置
,4,代表一个图形由4个方块组成,2代表x,y
volatile unsigned char MapCell[LINE+1][ROW+2];// =
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0};//方块活动区
volatile unsigned char flag;
volatile unsigned char top;
volatile unsigned char NumNow,NumNext;
volatile unsigned int Score;
volatile unsigned char IsEnd;
volatile unsigned char IsStart;
//************************************************************************/
//*屏幕使用区域
// |----------x(0-95)------------|
// - |
// | |
// | |
96*64
// y(0-63) |
// | |
// | |
// - |
// |-----------------------------|
//每个方块8*8,屏幕上总共有12*8个方格,这样安排是由于液晶一页是8位,为了便于计算,取此值。
//可以建立一个12*8的数组,标记此块是否为使用,使用的话,增加新块的时候原先的块不被占用
// */
//************************************************************************/
/**********************************************/
//write command
/**********************************************/
void Lcd_Command(unsigned char code)
{
LOW(E); //following the timing , first, start E.
LOW(RS);
LOW(RW);
delay_nus(150);
DATA = code;
HIGH(E);
delay_nms(1);
LOW(E);
delay_nus(300);
}
/**********************************************/
//write data
/**********************************************/
void Lcd_Data(unsigned char data)
{
LOW(E);
HIGH(RS);
LOW(RW);
delay_nus(150);
DATA = data;
HIGH(E);
delay_nms(1);
LOW(E);
delay_nus(300);
}
/********************************************/
//initial
/********************************************/
void initial_lcd()
{
Control_DDR = 0xFF; //as output
Data_DDR = 0xFF;
Control_PORT = 0x00;
Data_PORT = 0x00;
HIGH(LCD_CS1);
HIGH(LCD_CS2);
Lcd_Command(OPEN_DISP); //open display
//Lcd_Command(DISP_RAM_YROW); //Y position is 0;
}
void ks0108cls (void) //清屏,光标回到左半屏左上角
{
unsigned char i0,i1;
LOW(LCD_CS1);
LOW(LCD_CS2);
Lcd_Command(OPEN_DISP); //打开显示
Lcd_Command(DISP_RAM_YROW); //列地址回到0
for(i0=0;i0<8;i0++) //页地址由0变到7
{
Lcd_Command(DISP_RAM_PAGE + i0);
for(i1=0;i1<64;i1++)//对某一行全写入0
Lcd_Data(0);
}
}
/********************************************/
//Draw a line
//
//
//
// 0 *****************************************
// * *
*
// * part1 * part2 *
// * *
*
// * 0 - 64 * 0 - 64 *
// * *
*
// * *
*
// * *
*
// 63 *****************************************
//
/********************************************/
void Lcd_DrawLine(unsigned char x,unsigned char y,unsigned char linelength)
{
Lcd_Command(OPEN_DISP);
Lcd_Command(DISP_RAM_STARTLINE);
unsigned char i,temp,data;
data = 0;
x = (x>127)? 127:x;
y = (y>63)? 63:y;
//judge by the position and length
switch (x>64)
{
case 1://this line is in part2
HIGH(LCD_CS1);
LOW(LCD_CS2);
Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商
就是页数
Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪一列,it has restriction
before,
//no less than 64, no more than 127.
if (x + linelength > 128) linelength = 128 - x;//长度过长,就让他
在最右端结束
data |= (1<<y%8);//we have confirm the page , now ,we need to know the
exactitude position
for(i=0;i<linelength;i++)
Lcd_Data(data);
break;
case 0://this line is in part1
LOW(LCD_CS1);
HIGH(LCD_CS2);
Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商
就是页数
Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列
data |= (1<<y%8);
switch(x + linelength > 64)
{
case 1://too long
temp = 64 - x;
for(i=0;i<temp;i++)//the part1
Lcd_Data(data);
LOW(LCD_CS2);
HIGH(LCD_CS1);
Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页
,取其商就是页数
Lcd_Command(DISP_RAM_YROW);//确定在哪一列
if (x + linelength < 128) //longer than part1,shorter than
part2
linelength = linelength + x - 64;
else
linelength = 64;
for(i=0;i<linelength;i++)//the part2
Lcd_Data(data);
break;
case 0://not long
for(i=0;i<linelength;i++)//the part1
Lcd_Data(data);
break;
}
break;
}
}
/********************************************/
//Draw a vertical line
//
//
// 0 63
127
// *****************************************
// * *
*
// * part1 * part2 *
// * *
*
// * 0 - 64 * 0 - 64 *
// * *
*
// * *
*
// * *
*
// *****************************************
// 63
/********************************************/
void Lcd_DrawVerticalLine(unsigned char x,unsigned char y,unsigned char linelength)
{
unsigned char i,data,fullpagenum;
Lcd_Command(OPEN_DISP);
Lcd_Command(DISP_RAM_STARTLINE);
x = (x>127)? 127:x;
y = (y>63)? 63:y;
data = 0;
//this function is easier than top one,for he no need to judge the part1 or part2.
fullpagenum = (linelength - 1 - (7 - (y%8)))/8;//how many full pages
switch (x<64)
{
case 1://in part 1
LOW(LCD_CS1);
HIGH(LCD_CS2);
Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商
就是页数
Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列
//接下来这个判断还挺麻烦,用英语更麻烦,还是写汉语吧.需要判断这根线有多高
//写数据是一次写8位,应该又要和商和余数纠缠了
//
// --------------------*----------------
-----------------
// page1 * * *
* *
// * *
* * *
// ----*-------*-------*-------*--------
------------------
// page2 * * *
// *
*
// ------------*-------*----------------
----------------
// page3 * *
//
// -------------------------------------
---------------- //
//
//起始点不用判断,主要是判断跨越了多少个完整page
if ((linelength - 1 + y%8) < 8)//只在一个page内
{
for (i = 0;i < linelength - y%8 + 1;i++)
{
Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列,列地址会
变,所以得改回来
data |= (1<<(y%8 + i));
}
Lcd_Data(data);//把第一个page显示出来
}
else//在不只一个page内
{
if(fullpagenum > 0)//在不只一个page内,而且至少包含一个完整page
{
//在很多个page里,那么就先写第一个page
for(i = 0;i < 7 - y%8 + 1;i++)
{
Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列,
列地址会变,所以得改回来
data |= (1<<(y%8 + i));
}
Lcd_Data(data);//先把第一个page显示出来
//then we display the leaving pages,注意!,these are
full pages
for (i = 0;i < fullpagenum;i++)
{
Lcd_Command(DISP_RAM_PAGE + y/8 + 1 + i);//确
定在哪一页
Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列,
列地址会变,所以得改回来
Lcd_Data(0xFF);
}
//last ,we display the last page
if (((linelength - 1 - (7 - (y%8)))%8)!=0)//表示下面还
突出去一页
{
for(i = 0;i < ((linelength - 1 - (7 - (y%
8)))%8);i++)
{
Lcd_Command(DISP_RAM_PAGE + y/8 +
fullpagenum + 1);//确定在哪一页
Lcd_Command(DISP_RAM_YROW + x);//确定
在哪一列,列地址会变,所以得改回来
data |= (1<<i);
Lcd_Data(data);
}
}
}
else//在不只一个page内,but the second one is not full
{
for (i = 0;i < (linelength - 1 - (7 - (y%8)));i++)
{
Lcd_Command(DISP_RAM_PAGE + y/8 + 1);
Lcd_Command(DISP_RAM_YROW + x);
data |= (1<<i);
Lcd_Data(data);
}
}
}
break;
case 0://in part 2 两部分代码完全一样,就是改了改x,这样很傻,但是容易看懂
LOW(LCD_CS2);
HIGH(LCD_CS1);
Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商
就是页数
Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪一列
if ((linelength - 1 + y%8) < 8)//只在一个page内
{
for (i = 0;i < linelength - y%8 + 1;i++)
{
Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪一列,列地
址会变,所以得改回来
data |= (1<<(y%8 + i));
}
Lcd_Data(data);//把第一个page显示出来
}
else//在不只一个page内
{
if(fullpagenum > 0)//在不只一个page内,而且至少包含一个完整page
{
//在很多个page里,那么就先写第一个page
for(i = 0;i < 7 - y%8 + 1;i++)
{
Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪
一列,列地址会变,所以得改回来
data |= (1<<(y%8 + i));
}
Lcd_Data(data);//先把第一个page显示出来
//then we display the leaving pages,注意!,these are
full pages
for (i = 0;i < fullpagenum;i++)
{
Lcd_Command(DISP_RAM_PAGE + y/8 + 1 + i);//确
定在哪一页
Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪
一列,列地址会变,所以得改回来
Lcd_Data(0xFF);
}
//last ,we display the last page
if (((linelength - 1 - (7 - (y%8)))%8)!=0)//表示下面还
突出去一页
{
for(i = 0;i < ((linelength - 1 - (7 - (y%
8)))%8);i++)
{
Lcd_Command(DISP_RAM_PAGE + y/8 +
fullpagenum + 1);//确定在哪一页
Lcd_Command(DISP_RAM_YROW + x - 64);//
确定在哪一列,列地址会变,所以得改回来
data |= (1<<i);
Lcd_Data(data);
}
}
}
else//在不只一个page内,but the second one is not full
{
for (i = 0;i < (linelength - 1 - (7 - (y%8)));i++)
{
Lcd_Command(DISP_RAM_PAGE + y/8 + 1);
Lcd_Command(DISP_RAM_YROW + x - 64);
data |= (1<<i);
Lcd_Data(data);
}
}
}
break;