寒假在家沒什么事情就在家里做了這個DIY,傳上來供廣大愛好者參觀學習,資料里有源碼等等,這里就不詳細的介紹了,這里面有5個游戲,視頻鏈接http://v.youku.com/v_show/id_XNjcwMTM5Njg4.html
每個模塊的源程序+綜合程序+電路圖
視頻:
感謝那些開源程序的人們!!
全部源代碼下載: http://www.zg4o1577.cn/f/IAP15F2K61S2.zip
項目電路圖下載: http://www.zg4o1577.cn/bbs/dpj-25260-1.html
下面是12864測試程序:
#include "STC15F2K60S2.h"
#include "intrins.h"
#include "ico.h"
#include<rtx51tny.h>
sbit LCD_RS=P4^4;
sbit LCD_WR=P4^2;
sbit LCD_E =P4^1;
void LCD_Busy();//檢測芯片忙不忙
void Write_cmd(unsigned char cmd);//寫指令到lcd
void Write_date(unsigned char date);//寫數(shù)據(jù)到lcd
unsigned char Read_Date();//讀數(shù)據(jù)函數(shù)
void LCD_Init(void);//lcd初始化
void LCD_Inverse(unsigned char x);//反白顯示選擇
void LCD_HangInverse(unsigned char x,unsigned char e);//哪一行進行反白
void LCD_Pos(unsigned char x,unsigned char y);
void LCD_String(unsigned char *s);//發(fā)送字符串
void LCD_Hanzi(unsigned char *hanzi);//整體顯示漢字
void LCD_Picture(unsigned char *picture);//刷圖片
void LCD_ClearGDRAM();//清空GDRAM
unsigned long int LCD_Pow(unsigned char m,unsigned char n);
void LCD_Shownum(unsigned long int num,unsigned char len);
void Delay_ms(unsigned char ms); //@11.0592MHz
void Delay_us(); //@11.0592MHz
void LCD_Point(unsigned char x,unsigned y);//畫點函數(shù)
void LCD_DrawLine(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2);
void LCD_DrawRectangle(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2);
void Draw_Circle(unsigned char x0,unsigned char y0,unsigned char r);
void LCD_RandomPicture(unsigned char x,unsigned char y,unsigned char size,unsigned char *pic);//任意位置顯示任意大小和圖片
unsigned char code Lcd_Con_X_Y[4][2]={{0x80,0x80},{0x80,0x90},{0x88,0x80},{0x88,0x90}}; //LCD行反白顯示坐標
void main()
{
// unsigned char iii=0;
// LCD_Init();
// LCD_Picture(pic);//刷圖片
// LCD_ClearGDRAM();
// LCD_HangInverse(2,1);//哪一行進行反白
// LCD_Hanzi(hanzi);
// LCD_Point(1,2);
// LCD_DrawLine(0,0,50,60);
// LCD_DrawRectangle(0,0,60,60);
// Draw_Circle(30,30,20);
LCD_Pos(1,1);
LCD_Shownum(111,3);
LCD_RandomPicture(0,63,24,Game);
LCD_RandomPicture(50,63,24,Rtc);
LCD_RandomPicture(100,63,24,Music);
LCD_RandomPicture(0,30,24,Picture);
LCD_RandomPicture(50,30,24,System);
LCD_RandomPicture(100,30,24,Contact);
while(1);
}
void LCD_Busy()//檢測芯片忙不忙
{
bit BF=0;
LCD_E =0;
LCD_RS=0;
LCD_WR=1;
P2=0xff;
do
{
LCD_E =1;
BF=P2&0x80;
LCD_E =0;
}while(BF);
}
void Write_cmd(unsigned char cmd)//寫指令到lcd
{
LCD_Busy();
LCD_E =0;
LCD_RS=0;
LCD_WR=0;
P2 =cmd;//Delay_ms(1); //@11.0592MHz
LCD_E =1;//Delay_ms(1); //@11.0592MHz
LCD_E =0;
}
void Write_date(unsigned char date)//寫數(shù)據(jù)到lcd
{
LCD_Busy();
LCD_E =0;
LCD_RS=1;
LCD_WR=0;
P2 =date;//Delay_ms(1); //@11.0592MHz
LCD_E =1;//Delay_ms(1); //@11.0592MHz
LCD_E =0;
}
unsigned char Read_Date()//讀數(shù)據(jù)函數(shù)
{
unsigned char date=0;
LCD_Busy();
P2=0xff;
LCD_E =0;
LCD_RS=1;
LCD_WR=1;
LCD_E =1;
date =P2;
LCD_E =0;
return date;
}
void LCD_Init(void)
{
LCD_E =0;
LCD_RS=0;
LCD_WR=0;
Write_cmd(0x30);//8-BIT 控制接口 基本指令集
Delay_ms(5);
Write_cmd(0x02);//地址歸位
Delay_ms(5);
Write_cmd(0x0c);//整體顯示 光標關 反白關
Write_cmd(0x01);//清除顯示
Delay_ms(5);
Delay_ms(5);
}
void LCD_Inverse(unsigned char x)//反白顯示選擇
{
Write_cmd(0x34);//8-BIT 控制接口 擴充指令集
Write_cmd(0x04+x-1);//選擇哪一行進行反白顯示
Write_cmd(0x30);//8-BIT 控制接口 基本指令集
}
void LCD_Pos(unsigned char x,unsigned char y)//設定坐標函數(shù)
{
switch (x)
{
case 1:x=0x80;
break;
case 2:x=0x90;
break;
case 3:x=0x88;
break;
case 4:x=0x98;
break;
default:
break;
}
Write_cmd(x+y);
}
void LCD_String(unsigned char *s)//發(fā)送字符串
{
while(*s)
{
Write_date(*s++);
}
}
void LCD_Hanzi(unsigned char *hanzi)//整體顯示漢字
{
unsigned char i=0;
LCD_Pos(1,0);
while(*hanzi)
{
Write_date(*hanzi++);
i++;
switch (i)
{
case 16:LCD_Pos(2,0);
break;
case 32:LCD_Pos(3,0);
break;
case 48:LCD_Pos(4,0);
break;
default:
break;
}
}
}
//x行數(shù)
//e使能反白
void LCD_HangInverse(unsigned char x,unsigned char e)//哪一行進行反白
{
unsigned char i=0,j=0;
Write_cmd(0x34);//擴充指令 繪圖顯示關
Delay_ms(1);
for(j=0;j<16;j++)//一大行包含16個小行
{
Write_cmd(Lcd_Con_X_Y[x-1][1]+j);//y
Write_cmd(Lcd_Con_X_Y[x-1][0]);//x
for(i=0;i<8;i++)//沒小行寫8次數(shù)據(jù),每次寫兩個字節(jié)
{
if(e)
{
Write_date(0xff);//D15-D8
Write_date(0xff);//D7-D0
}
else
{
Write_date(0);//D15-D8
Write_date(0);//D7-D0
}
}
}
Write_cmd(0x36);//擴充指令 繪圖顯示開
Delay_ms(1);
Write_cmd(0x30);//基本指令
}
void LCD_Picture(unsigned char *picture)//刷圖片
{
unsigned char i=0,j=0;
Write_cmd(0x34);//擴充指令 繪圖顯示關
for(j=0;j<32;j++)//上半屏
{
Write_cmd(0x80+j);//y
Write_cmd(0x80);//x
for(i=0;i<16;i++)
{
Write_date(*picture++);
}
}
for(j=0;j<32;j++)//下半屏
{
Write_cmd(0x80+j);//y
Write_cmd(0x88);//x
for(i=0;i<16;i++)
{
Write_date(*picture++);
}
}
Write_cmd(0x36);//擴充指令 繪圖顯示開
Delay_ms(1);
Write_cmd(0x30);//基本指令
}
void LCD_ClearGDRAM()//清空GDRAM
{
unsigned char i=0,j=0;
Write_cmd(0x34);//擴充指令 繪圖顯示關
for(j=0;j<32;j++)//上半屏
{
Write_cmd(0x80+j);//y
Write_cmd(0x80);//x
for(i=0;i<16;i++)
{
Write_date(0x00);
}
}
for(j=0;j<32;j++)//下半屏
{
Write_cmd(0x80+j);//y
Write_cmd(0x88);//x
for(i=0;i<16;i++)
{
Write_date(0x00);
}
}
Write_cmd(0x36);//擴充指令 繪圖顯示開
Delay_ms(1);
Write_cmd(0x30);//基本指令
}
//m^n函數(shù)
//返回值m^n
unsigned long int LCD_Pow(unsigned char m,unsigned char n)
{
unsigned long int result=1;
while(n--)result*=m;
return result;
}
//發(fā)送數(shù)字函數(shù)
void LCD_Shownum(unsigned long int num,unsigned char len)
{
unsigned char t,temp;
unsigned char enshow=0;
for(t=0;t<len;t++)
{
temp=(num/LCD_Pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
continue;
}else enshow=1;
}
Write_date(temp+48);
}
}
void Delay_ms(unsigned char ms) //@11.0592MHz
{
unsigned char i, j;
for(;ms>0;ms--)
{
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
void Delay_us() //@11.0592MHz
{
_nop_();
_nop_();
_nop_();
}
void LCD_Point(unsigned char x,unsigned y)//畫點函數(shù)
{
unsigned char x_place,y_place,date1,date2;
y_place=y/16;
x_place=x/16;
switch (y_place)
{
case 0:y_place=0x90+15-y%16;x_place=0x88+x/16;
break;
case 1:y_place=0x80+15-y%16;x_place=0x88+x/16;
break;
case 2:y_place=0x90+15-y%16;x_place=0x80+x/16;
break;
case 3:y_place=0x80+15-y%16;x_place=0x80+x/16;
default:
break;
}
Write_cmd(0x34);//擴充指令 繪圖顯示開
Write_cmd(y_place);//擴充指令 繪圖顯示開
Write_cmd(x_place);//擴充指令 繪圖顯示開
Read_Date();//假讀取數(shù)據(jù)一次
date1=Read_Date();//高 0x0f,0xf0
date2=Read_Date();//低
Write_cmd(y_place);//擴充指令 繪圖顯示開
Write_cmd(x_place);//擴充指令 繪圖顯示開
if(x%16<8)
{
Write_date(date1 | (0x01 << (7 - x%16)) );
Write_date(date2);
}
else
{
Write_date(date1);
Write_date(date2|(0x01 << (15 - x%16)));
}
Write_cmd(0x36);//擴充指令 繪圖顯示開
Write_cmd(0x30);//基本指令集
}
//畫線
//x1,y1:起點坐標
//x2,y2:終點坐標
void LCD_DrawLine(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2)
{
unsigned char t;
char xerr=0,yerr=0,delta_x,delta_y,distance;
char incx,incy,uRow,uCol;
delta_x=x2-x1; //計算坐標增量
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1; //設置單步方向
else if(delta_x==0)incx=0;//垂直線
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;//水平線
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x; //選取基本增量坐標軸
else distance=delta_y;
for(t=0;t<=distance+1;t++ )//畫線輸出
{
LCD_Point(uRow,uCol);//畫點
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
//畫矩形
//(x1,y1),(x2,y2):矩形的對角坐標
void LCD_DrawRectangle(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2)
{
LCD_DrawLine(x1,y1,x2,y1);
LCD_DrawLine(x1,y1,x1,y2);
LCD_DrawLine(x1,y2,x2,y2);
LCD_DrawLine(x2,y1,x2,y2);
}
//在指定位置畫一個指定大小的圓
//(x,y):中心點
//r :半徑
void Draw_Circle(unsigned char x0,unsigned char y0,unsigned char r)
{
char a,b;
char di;
a=0;b=r;
di=3-(r<<1); //判斷下個點位置的標志
while(a<=b)
{
LCD_Point(x0+a,y0-b); //5
LCD_Point(x0+b,y0-a); //0
LCD_Point(x0+b,y0+a); //4
LCD_Point(x0+a,y0+b); //6
LCD_Point(x0-a,y0+b); //1
LCD_Point(x0-b,y0+a);
LCD_Point(x0-a,y0-b); //2
LCD_Point(x0-b,y0-a); //7
a++;
//使用Bresenham算法畫圓
if(di<0)di +=4*a+6;
else
{
di+=10+4*(a-b);
b--;
}
}
}
void LCD_RandomPicture(unsigned char x,unsigned char y,unsigned char size,unsigned char *pic)//任意位置顯示任意大小和圖片
{
unsigned char x_i=x;
unsigned char i,j;
unsigned char value;
Write_cmd(0x34);//擴充指令 繪圖顯示關
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
if(j%8==0)
{
value=*(pic+i*size/8+j/8);
}
if(value&0x80)
LCD_Point(x,y);//畫點函數(shù)
x++;
value<<=1;
}
y--;
x=x_i;
}
Write_cmd(0x36);//擴充指令 繪圖顯示開
Write_cmd(0x30);//基本指令集
}