无聊的时候……STM32做个拼图小游戏。。

===========================华丽的main.c分界线====================================

#include "stm32f10x.h"
#include "LCD_driver.h"
#include"chinese.h"
#include"picture.h"
#define    LCD_cs(x)   x ? GPIO_SetBits(GPIOB, LCD_CS) :   GPIO_ResetBits(GPIOB, LCD_CS)

void delay(u32);
int keydown(void);
int keyup(void);
int keyleft(void);
int keyright(void);
void show(void);

GPIO_InitTypeDef GPIO_1;
u16 tu[8][2]={{0,80},{80,80},{160,80},{0,160},{80,160},{160,160},{0,240},{80,240}};
u8 ptx=3,pty=3;    
          
int main(void)
{

        u16  pt[5][5]={{2,2,2,2,2},
                         {2,1,1,1,2},
                         {2,1,1,1,2},
                         {2,1,1,0,2},
                         {2,2,2,2,2}};
              
        u8 i;
    SystemInit();
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_1.GPIO_Pin=GPIO_Pin_All;
    GPIO_1.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_1.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_1);
    GPIO_Init(GPIOB,&GPIO_1);
    GPIO_SetBits(GPIOA,GPIO_Pin_All);
    GPIO_SetBits(GPIOB,GPIO_Pin_All);
            
    LCD_Init();
        Pant(0x0000, 0x0000);
        LCD_cs(0);  //打开片选使能
    
        ChineseChar(0,10,60,240,0xffff,0x0000,hz);
        show();
    LCD_cs(1);  //关闭片选使能

        while (1)
     {
                if(keydown()&&(pt[pty-1][ptx]==1))
         {
    
                        pt[pty][ptx]=1;
             pty--;
                        pt[pty][ptx]=0;
                        for(i=0;i<8;i++)
                                if((tu[i][0]==(ptx-1)*80)&&(tu[i][1]==pty*80))
                         tu[i][1]+=80;
        
                        LCD_cs(0);  //打开片选使能
                 show();

                        LCD_cs(1);  //关闭片选使能*/

         }
    
                if(keyup()&&(pt[pty+1][ptx]==1))
         {
    
                        pt[pty][ptx]=1;
             pty++;
                        pt[pty][ptx]=0;
                        for(i=0;i<8;i++)
                                if((tu[i][0]==(ptx-1)*80)&&(tu[i][1]==pty*80))
                         tu[i][1]-=80;
        
                        LCD_cs(0);  //打开片选使能
                 show();

                        LCD_cs(1);  //关闭片选使能*/

         }
                if(keyright()&&(pt[pty][ptx-1]==1))
         {
    
                        pt[pty][ptx]=1;
             ptx--;
                        pt[pty][ptx]=0;
                        for(i=0;i<8;i++)
                                if((tu[i][0]==(ptx-1)*80)&&(tu[i][1]==pty*80))
                         tu[i][0]+=80;
        
                        LCD_cs(0);  //打开片选使能
                 show();

                        LCD_cs(1);  //关闭片选使能*/

         }
                if(keyleft()&&(pt[pty][ptx+1]==1))
         {
    
                        pt[pty][ptx]=1;
             ptx++;
                        pt[pty][ptx]=0;
                        for(i=0;i<8;i++)
                                if((tu[i][0]==(ptx-1)*80)&&(tu[i][1]==pty*80))
                         tu[i][0]-=80;
        
                        LCD_cs(0);  //打开片选使能
                 show();
        
                        LCD_cs(1);  //关闭片选使能*/

         }
     }
}   
void delay(u32 a)
{
    while(a--);
}
int keydown(void)
{
    if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13))
    {
        delay(10000);
        if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13))
     {
            while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13));
            return 1;
     }
        else
            return  0;
    }
    else
        return 0;
}
int keyright(void)
{
    if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14))
    {
        delay(10000);
        if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14))
     {
            while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14));
            return 1;
     }
        else
            return  0;
    }
    else
        return 0;
}
int keyup(void)
{
    if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9))
    {
        delay(10000);
        if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9))
     {
            while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9));
            return 1;
     }
        else
            return  0;
    }
    else
        return 0;
}
int keyleft(void)
{
    if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12))
    {
        delay(10000);
        if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12))
     {
            while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12));
            return 1;
     }
        else
            return  0;
    }
    else
        return 0;
}
void show(void)
{
        ChineseChar((ptx-1)*80,pty*80,80,80,0xffff,0xffff,black);
        pic_play(tu[0][0],tu[0][0]+79,tu[0][1],tu[0][1]+79,Image1);
        pic_play(tu[1][0],tu[1][0]+79,tu[1][1],tu[1][1]+79,Image2);
        pic_play(tu[2][0],tu[2][0]+79,tu[2][1],tu[2][1]+79,Image3);
        pic_play(tu[3][0],tu[3][0]+79,tu[3][1],tu[3][1]+79,Image4);
        pic_play(tu[4][0],tu[4][0]+79,tu[4][1],tu[4][1]+79,Image5);
        pic_play(tu[5][0],tu[5][0]+79,tu[5][1],tu[5][1]+79,Image6);
        pic_play(tu[6][0],tu[6][0]+79,tu[6][1],tu[6][1]+79,Image7);
        pic_play(tu[7][0],tu[7][0]+79,tu[7][1],tu[7][1]+79,Image8);
}

=======================华丽的lcd.C分界线===========================================

#include "stm32f10x.h"
#include "LCD_driver.h"

#define    LCD_rest(x) x ? GPIO_SetBits(GPIOA, LCD_RST):   GPIO_ResetBits(GPIOA, LCD_RST)
#define    LCD_rd(x)   x ? GPIO_SetBits(GPIOA, LCD_RD) :   GPIO_ResetBits(GPIOA, LCD_RD)
#define    LCD_rs(x)   x ? GPIO_SetBits(GPIOB, LCD_RS) :   GPIO_ResetBits(GPIOB, LCD_RS)
#define    LCD_wr(x)   x ? GPIO_SetBits(GPIOB, LCD_WR) :   GPIO_ResetBits(GPIOB, LCD_WR)
#define    LCD_cs(x)   x ? GPIO_SetBits(GPIOB, LCD_CS) :   GPIO_ResetBits(GPIOB, LCD_CS)

void LCD_Init(void)   //初始化
{

    LCD_rest(1);
    delayms(5); 
    LCD_rest(0);
    delayms(5);
    LCD_rest(1);
    delayms(5);
    
    LCD_rs(1);//打开读写数据
    LCD_cs(0);  //打开片选使能
    LCD_Write_COM(0x00,0x10); LCD_Write_DATA(0x00,0x00);    
    delayms(100);
    LCD_Write_COM(0x00,0x11); LCD_Write_DATA(0x00,0x1c); 
    LCD_Write_COM(0x00,0x12); LCD_Write_DATA(0x12,0x12);  
    LCD_Write_COM(0x00,0x13); LCD_Write_DATA(0x00,0x41);  
    LCD_Write_COM(0x00,0x14); LCD_Write_DATA(0x40,0x50);    
    LCD_Write_COM(0x00,0x10); LCD_Write_DATA(0x08,0x00); 
    LCD_Write_COM(0x00,0x11); LCD_Write_DATA(0x01,0x1c); 
    delayms(3000);
    LCD_Write_COM(0x00,0x11); LCD_Write_DATA(0x03,0x1c);  
    delayms(3000);
    LCD_Write_COM(0x00,0x11); LCD_Write_DATA(0x07,0x1c);  
    delayms(3000);
    LCD_Write_COM(0x00,0x11); LCD_Write_DATA(0x0f,0x1c);  
    delayms(400);
    LCD_Write_COM(0x00,0x11); LCD_Write_DATA(0x0f,0x39);   
    delayms(600);
    LCD_Write_COM(0x00,0x01); LCD_Write_DATA(0x01,0x28);
    LCD_Write_COM(0x00,0x02); LCD_Write_DATA(0x01,0x00);
    LCD_Write_COM(0x00,0x03); LCD_Write_DATA(0x10,0x30);  
    LCD_Write_COM(0x00,0x08); LCD_Write_DATA(0x08,0x08);
    LCD_Write_COM(0x00,0x0b); LCD_Write_DATA(0x11,0x05);
    LCD_Write_COM(0x00,0x0c); LCD_Write_DATA(0x00,0x00);
    LCD_Write_COM(0x00,0x15); LCD_Write_DATA(0x00,0x20);
    LCD_Write_COM(0x00,0x30); LCD_Write_DATA(0x00,0x00);
    LCD_Write_COM(0x00,0x34); LCD_Write_DATA(0x01,0x3f);   //           指定显示的终点和起点
    LCD_Write_COM(0x00,0x35); LCD_Write_DATA(0x00,0x00);   //
    LCD_Write_COM(0x00,0x36); LCD_Write_DATA(0x00,0xef);   //
    LCD_Write_COM(0x00,0x37); LCD_Write_DATA(0x00,0x00);   //
    LCD_Write_COM(0x00,0x38); LCD_Write_DATA(0x01,0x3f);   //
    LCD_Write_COM(0x00,0x39); LCD_Write_DATA(0x00,0x00);   //
    LCD_Write_COM(0x00,0x50); LCD_Write_DATA(0x01,0x01);
    LCD_Write_COM(0x00,0x51); LCD_Write_DATA(0x09,0x03);                                                                                                                                                                                                                                                                             
    LCD_Write_COM(0x00,0x52); LCD_Write_DATA(0x0b,0x08);                                                                                                                                                                                                                                                                            
    LCD_Write_COM(0x00,0x53); LCD_Write_DATA(0x08,0x05);                                                                                                                                                                                                                                                                           
    LCD_Write_COM(0x00,0x54); LCD_Write_DATA(0x01,0x01);                                                                                                                                                                                                                                                        
    LCD_Write_COM(0x00,0x55); LCD_Write_DATA(0x0d,0x06);                                                                                                                                                                                                                                                                
    LCD_Write_COM(0x00,0x56); LCD_Write_DATA(0x0e,0x0a);                                                                                                                                                                                                                                                                                       
    LCD_Write_COM(0x00,0x57); LCD_Write_DATA(0x01,0x00);                                                                                                                                                                                                                                                                                   
    LCD_Write_COM(0x00,0x58); LCD_Write_DATA(0x1f,0x0b);                                                                                                                                                                                                                                                                                       
    LCD_Write_COM(0x00,0x59); LCD_Write_DATA(0x02,0x01);                                                                                                                                                                                                                                                                                       
    LCD_Write_COM(0x00,0x20); LCD_Write_DATA(0x00,0x00);
    LCD_Write_COM(0x00,0x21); LCD_Write_DATA(0x00,0x00);


    LCD_Write_COM(0x00,0x0f); LCD_Write_DATA(0x1f,0x01);
    delayms(3000);
    LCD_Write_COM(0x00,0x07); LCD_Write_DATA(0x00,0x16);                                                                                                                                                                                                                                                                                     
    delayms(320);
    LCD_Write_COM(0x00,0x07); LCD_Write_DATA(0x00,0x17);
    LCD_cs(1);  //关闭片选使能
}  


void delayms(int count)
{
    int i,j;
    for(i=0;i<count;i++)
        for(j=0;j<100;j++);
}


void LCD_Writ_Bus(uint VH , uint VL)   //并行数据写入函数
{

    GPIO_SetBits(GPIOA,  VH & 0x00ff);
    GPIO_ResetBits(GPIOA, (~ VH & 0x00ff));
    GPIO_SetBits(GPIOB,  (VL)<<8 & 0xff00);
    GPIO_ResetBits(GPIOB, ((~VL)<<8) & 0xff00);
    LCD_wr(0);
    LCD_wr(1);////写数据 通过上升沿
}

void LCD_Write_COM(char VH,char VL)  //发送命令
{   
    LCD_rs(0);
    LCD_Writ_Bus(VH,VL);
}


void LCD_Write_DATA(char VH,char VL)    //发送数据
{
    LCD_rs(1);
    LCD_Writ_Bus(VH,VL);
}

void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
    LCD_Write_COM(0x00,0x20);LCD_Write_DATA(x1>>8,x1);    //设置X坐标位置
    LCD_Write_COM(0x00,0x21);LCD_Write_DATA(y1>>8,y1);   //设置Y坐标位置

                          

    LCD_Write_COM(0x00,0x37);LCD_Write_DATA(x1>>8,x1);   //开始X
    LCD_Write_COM(0x00,0x39);LCD_Write_DATA(y1>>8,y1);    //开始Y
    LCD_Write_COM(0x00,0x36);LCD_Write_DATA(x2>>8,x2);   //结束X
    LCD_Write_COM(0x00,0x38);LCD_Write_DATA(y2>>8,y2);   //结束Y

    LCD_Write_COM(0x00,0x22); //开启GRAM 计数器自动增加减少                  
}

void ChineseChar(uint x,uint y,u16 sizex,u16 sizey,uint For_color,uint Bk_color,unsigned char *c)
{
    short  ncols,nrows,i,j;
    ncols =sizex-1;
    nrows =sizey-1;
    
    Address_set(x,  y, x+nrows,y+ncols);
   
    for(i=0;i<sizex*sizey/8;i++)
    {
        for(j=0;j<8;j++)
        {
            if(c[i]>>j&0x01)
                LCD_Write_DATA(For_color>>8 , For_color  );  //填充字颜色
            else
                LCD_Write_DATA( Bk_color>>8 ,  Bk_color);  //填充背景色
        }
    }
}



void Pant(char VH,char VL)//背景填充
{
    short i,j;
    LCD_cs(0);  //打开片选使能
    Address_set(0,0,239,319);
    for(i=0;i<320;i++)
        for (j=0;j<240;j++)
            LCD_Write_DATA(VH,VL);
    LCD_cs(1);  //关闭片选使能
}    
void  pic_play(u16 Start_X, u16 End_X,u16 Start_Y,u16 End_Y,const unsigned char *tu)
{
    u16 i,j;
        u32 m;
    LCD_cs(0);  //打开片选使能
        Address_set(Start_X,Start_Y,End_X,End_Y) ;
    for(i=Start_Y,m=0;i<End_Y+1;i++)
        for (j=Start_X;j<End_X+1;j++,m+=2)
            LCD_Write_DATA(tu[m+1],tu[m]);
    LCD_cs(1);  //关闭片选使能

}
原文地址:https://www.cnblogs.com/hebaichuanyeah/p/3124231.html