高级会员 
  
	- 积分
 - 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] 
 |   
 
 
 
 |