高级会员
- 积分
- 680
- 金钱
- 680
- 注册时间
- 2015-12-13
- 在线时间
- 243 小时
|
楼主 |
发表于 2016-1-31 17:10:59
|
显示全部楼层
[mw_shl_code=c,true]/*==========================================
运行频率30MHZ 带SPI接口的STC单片机
彩屏320*240带触摸,控制芯片9431,SPI接口
触摸芯片PTX2046
============================================*/
#include<stc15f2k60s2.h>
#include <stdlib.h>
#define u8 unsigned char
#define u16 unsigned int
#define up 1
#define zuo 2
#define xia 3
#define you 4
sbit LCD_CS =P1^2; //片选
sbit LCD_DC =P5^5; //数据/命令切换
sbit LCD_REST =P5^4; //复位
sbit PT_CS=P1^0;
sbit PT_PN=P3^3;
sbit PT_MO=P3^6;
sbit PT_MI=P3^7;
sbit PT_CK=P1^1;
u16 xdata snake[30];
u16 ptx,pty;
u8 fx,length;
u16 food,food_x;
bit ptfalg,END,time_falg;
void LCD_WR_DATA8(u8 da);
void LCD_WR_REG(u8 da);
void Address_set(u16 x1,y1,x2,y2);
void Lcd_Init(void);
u16 PT_ADC(u8 x);
void PT_scan();
void LCD_write(u16 x,y,LH,H,C);
void delay(u16 t);
void delayms(u8 t);
void she_write(u16 m,u8 a);
void zhongzi();
void snake_manage();
void time_start();
u16 contrast(u16 a,b,c);
u8 direction(); //方向判断
void w_color(u8 x,u16 c);
void snake_start();
void main()
{
u8 i,j;
bit start;
SPDAT=0;
SPSTAT=0xFF;
SPCTL=0xD0;
Lcd_Init();
LCD_write(0,0,320,240,0XFFFF);
LCD_write(160,0,6,240,0);
END=1;
time_start();
while(1)
{
if(END)
{
snake_start();
start=0;
}
food_x++;
PT_scan();
if(ptfalg)
{
ptfalg=0;
i=direction();
j=fx>i?(fx-i)i-fx);
if(2==j)i=fx;
if(fx!=i)
{
w_color(fx,0);
fx=i;
w_color(fx,0xF800);
}
if(start==0)start=1;
}
if(start)
if(time_falg)
{
snake_manage();
time_falg=0;
}
}
}
void LCD_write(u16 x,y,L,H,C)
{
u16 i;
u8 j,a,b;
a=C>>8;
b=C;
Address_set(x,y,x+L-1,y+H-1);
LCD_DC=1;
for(i=0;i<L;i++)
{
for (j=0;j<H;j++)
{
SPDAT=a;
while(SPSTAT<0x80);
SPSTAT=0xFF;
SPDAT=b;
while(SPSTAT<0x80);
SPSTAT=0xFF;
}
}
}
void delay(u16 t)
{
while(t--);
}
void delayms(u8 t)
{
while(t--)delay(333);
}
void LCD_WR_DATA8(u8 da)
{
LCD_DC=1;
SPDAT=da;
while(SPSTAT<0x80);
SPSTAT=0xFF;
}
void LCD_WR_REG(u8 da)
{
LCD_DC=0;
SPDAT=da;
while(SPSTAT<0x80);
SPSTAT=0xFF;
}
void Address_set(u16 x1,y1,x2,y2)
{
LCD_WR_REG(0x2a);
LCD_WR_DATA8(x1>>8);
LCD_WR_DATA8(x1);
LCD_WR_DATA8(x2>>8);
LCD_WR_DATA8(x2);
LCD_WR_REG(0x2b);
LCD_WR_DATA8(y1>>8);
LCD_WR_DATA8(y1);
LCD_WR_DATA8(y2>>8);
LCD_WR_DATA8(y2);
LCD_WR_REG(0x2C);
}
void Lcd_Init(void)
{
LCD_REST=0;
delayms(200);
LCD_REST=1;
delayms(200);
LCD_CS =0;
LCD_WR_REG(0xCF);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0xD9);
LCD_WR_DATA8(0X30);
LCD_WR_REG(0xED);
LCD_WR_DATA8(0x64);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0X12);
LCD_WR_DATA8(0X81);
LCD_WR_REG(0xE8);
LCD_WR_DATA8(0x85);
LCD_WR_DATA8(0x10);
LCD_WR_DATA8(0x78);
LCD_WR_REG(0xCB);
LCD_WR_DATA8(0x39);
LCD_WR_DATA8(0x2C);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x34);
LCD_WR_DATA8(0x02);
LCD_WR_REG(0xF7);
LCD_WR_DATA8(0x20);
LCD_WR_REG(0xEA);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0xC0);
LCD_WR_DATA8(0x21);
LCD_WR_REG(0xC1);
LCD_WR_DATA8(0x12);
LCD_WR_REG(0xC5);
LCD_WR_DATA8(0x32);
LCD_WR_DATA8(0x3C);
LCD_WR_REG(0xC7);
LCD_WR_DATA8(0XC1);
LCD_WR_REG(0x36);
LCD_WR_DATA8(0x6c);
LCD_WR_REG(0x3A);
LCD_WR_DATA8(0x55);
LCD_WR_REG(0xB1);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x18);
LCD_WR_REG(0xB6);
LCD_WR_DATA8(0x0A);
LCD_WR_DATA8(0xA2);
LCD_WR_REG(0xF2);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0x26);
LCD_WR_DATA8(0x01);
LCD_WR_REG(0xE0);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x20);
LCD_WR_DATA8(0x1E);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x12);
LCD_WR_DATA8(0x0B);
LCD_WR_DATA8(0x50);
LCD_WR_DATA8(0XBA);
LCD_WR_DATA8(0x44);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x14);
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x23);
LCD_WR_DATA8(0x21);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0XE1);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x19);
LCD_WR_DATA8(0x19);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x12);
LCD_WR_DATA8(0x07);
LCD_WR_DATA8(0x2D);
LCD_WR_DATA8(0x28);
LCD_WR_DATA8(0x3F);
LCD_WR_DATA8(0x02);
LCD_WR_DATA8(0x0A);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x25);
LCD_WR_DATA8(0x2D);
LCD_WR_DATA8(0x0F);
LCD_WR_REG(0x11);
delayms(120);
LCD_WR_REG(0x29);
}
u16 PT_ADC(u8 x)
{
u16 j;
u8 i;
PT_CS=0;
PT_CK=0;
for(i=0;i<8;i++)
{
if(x&0x80)PT_MI=1;
else PT_MI=0;
PT_CK=0;
x<<=1;
PT_CK=1;
}
PT_CK=1;
j++;
PT_CK=0;
j=0;
for(i=0;i<12;i++)
{
PT_CK=1;
j<<=1;
PT_CK=0;
if(PT_MO)j++;
}
PT_CS=1;
return j;
}
void PT_scan() //触摸屏扫描函数
{
u16 x,y,ax,bx,cx,ay,by,cy;
u8 i;
static bit k;
if(PT_PN==1)
{
k=0;
return;
}
if(k)return;
x=0;
y=0;
for(i=0;i<16;i++)
{
x+=PT_ADC(0x90);
y+=PT_ADC(0xd0);
if(PT_PN==1)return;
}
ax=x>>4;
ay=y>>4;
x=0;
y=0;
for(i=0;i<16;i++)
{
x+=PT_ADC(0x90);
y+=PT_ADC(0xd0);
if(PT_PN==1)return;
}
bx=x>>4;
by=y>>4;
x=0;
y=0;
for(i=0;i<16;i++)
{
x+=PT_ADC(0x90);
y+=PT_ADC(0xd0);
if(PT_PN==1)return;
}
cx=x>>4;
cy=y>>4;
ptx=contrast(ax,bx,cx);
pty=contrast(ay,by,cy);
ptfalg=1;
k=1;
}
void she_write(u16 m,u8 a)
{
u8 i;
u16 x,y;
x=(m%20)*8;
y=m/20*8;
Address_set(x,y,x+6,y+6);
LCD_DC=1;
for(i=0;i<49;i++)
{
SPDAT=a;
while(SPSTAT<0x80);
SPSTAT=0xFF;
SPDAT=a; //24
while(SPSTAT<0x80);
SPSTAT=0xFF;
}
}
void snake_start()
{
u8 i;
LCD_write(0,0,160,240,0XFFFF);
w_color(up,0); //上 y=600 x=1350
w_color(zuo,0); //左 y=900 x=1100
w_color(xia,0); //下 y=1250 x=1350
w_color(you,0); //右 y=900 x=1600
fx=you;
time_falg=0;
END=0;
for(i=0;i<5;i++)
{
snake=i;
she_write(snake,0);
length=i;
}
zhongzi();
w_color(fx,0xF800);
}
void snake_manage()
{
u8 a; //临时变量
bit k; //标志位
u16 m;
k=0; //标志位清零
switch(fx) //方向处理
{
case up : if(snake[length]<20)k=1; //如果已经在最顶端,标志位置1
else m=snake[length]-20; //否则计算出下个位置的坐标
break; //返回
case xia : if(snake[length]>579)k=1; //方向(下)
else m=snake[length]+20;
break;
case zuo : if(snake[length]%20==0)k=1; //方向(左)
else m=snake[length]-1;
break;
case you : if(snake[length]%20==19)k=1; //方向(右)
else m=snake[length]+1;
break;
}
if(k!=1)
for(a=0;a<length;a++) //判断蛇是否咬到自己
if(m==snake[a])k=1;
if(k) //如果符合结束条件
{ //则置位结束标志并退出当前函数
END=1;
return;
}
snake[length+1]=m; //保存下个位置的坐标
if(m==food) //如果吃到了食物
{
length++; //蛇的长度加1
if(length>28)END=1; //如果达到过关条件,则结束
else //否则放置新的食物(种子)
zhongzi();
return; //退出当前函数,如果没吃到食物则执行下面的指令
}
she_write(snake[length+1],0); //蛇头向前移动一个坐标
she_write(snake[0],0xff); //蛇尾也跟着前进一个坐标
for(a=0;a<length+1;a++)snake[a]=snake[a+1];
//将储存蛇的数组全体移动一个位置
}
void zhongzi()
{
u16 m;
u8 a;
bit k;
do
{
k=0;
srand(food_x);
food_x++;
m=rand()%600;
for(a=0;a<length;a++)
if(m==snake[a])k=1;
}
while(k);
food=m;
she_write(m,0);
}
void time_start()
{
TMOD = 0;
TH0 = (65536-25000)/256; //10ms 30Mhz
TL0 = (65536-25000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void timer0 () interrupt 1
{
static u8 i;
i++;
if(i>39) //每0.4s移动一次
{
i=0;
time_falg=1;
}
}
u16 contrast(u16 a,b,c) //比较3个数值的大小,取中间那个
{
if(a>b)
if(b>c)return b;
else
if(a>c)return c;
else return a;
else
if(a>c)return a;
else
if(b>c)return c;
else return b;
}
u8 direction() //方向判断,对触摸屏扫描回来的坐标进行计算
{
u16 i;
i=ptx>1350?(ptx-1350)1350-ptx);
if(i<150)
{
i=pty>600?(pty-600)600-pty);
if(i<150)return up;
i=pty>1250?(pty-1250)1250-pty);
if(i<150)return xia;
return fx;
}
i=pty>900?(pty-900)900-pty);
if(i<150)
{
i=ptx>1100?(ptx-1100)1100-ptx);
if(i<150)return zuo;
i=ptx>1600?(ptx-1600)1600-ptx);
if(i<150)return you;
}
return fx;
}
void w_color(u8 x,u16 c)
{
switch(x)
{
case up : LCD_write(223,40,40,40,c);break;
case xia : LCD_write(223,140,40,40,c);break;
case zuo : LCD_write(176,90,40,40,c);break;
case you : LCD_write(270,90,40,40,c);break;
}
}
[/mw_shl_code]
|
|