基于STM32设计的拼图小游戏

简介: 基于STM32设计的拼图小游戏

一、环境介绍

MCU: STM32F103ZET6


编程软件环境: keil5


LCD显示屏:  正点原子的TFT 3.5寸显示屏


完整工程代码下载地址: https://download.csdn.net/download/xiaolong1126626497/20706318


二、运行效果

image.png

image.png

image.png

三、功能介绍

因为代码原来是在2.8寸屏上设计的,但是2.8寸屏摔碎了,现在手上只有块3.5寸的LCD屏。就把代码移植到3.5寸屏上显示了,目前运行的效果可以看上面的效果图。


拼图游戏在小时候还是经常玩,玩法也比较简单,这里就使用STM32设计一个拼图小游戏分享出来一起学习。


目前游戏是通过开发板上4按键进行控制图片的移动,完成最终的拼图效果,如果想要在上面扩充其他游戏功能都还是比较容易。


当然,设计编写这个款小游戏不仅仅是为了玩游戏这么简单,主要是为了通过设计游戏的过程学习STM32编程、LCD的编程、按键、图片等等很多编程知识。


做拼图这款游戏主要的硬件就是LCD显示屏和几个按键,没有其他外设,如果自己有其他STM32最小系统板有LCD显示屏的话,完全可以把代码移植过去运行。当前的代码兼容正点原子战舰开发板,可以直接在正点原子战舰直接编译下载运行。其他的开发板上运行也是一样的道理,底层替换自己LCD画点函数即可。


目前的拼图的游戏工程里图片是提前通过取模软件取好模之后把数据放在工程里的,如果想要动态更加灵活的切换拼图的图片,可以加上SD卡和FATFS文件系统,把图片放在SD卡,通过按键选择指定图片切割进行拼图。


代码分为3个部分:


1. LCD屏驱动代码部分


2. 按键驱动代码部分


3. 拼图的逻辑代码部分


四、LCD屏驱动代码

4.1 LCD介绍

  这款LCD显示屏的驱动芯片型号是NT35310,时序支持8080时序,普通的MCU可以采用IO模拟8080时序驱动,有硬件接口的可以采用硬件接口驱动。STM32F103ZET6的FSMC是可以输出8080时序,为了提高刷屏速度,这里代码就采用FSMC接口来驱动LCD屏。照着LCD的手册指令集,自己编写一遍LCD的初始化代码,可以深入学习一遍LCD编程原理。

image.png

4.2 LCD显示屏的初始化代码示例

/*
函数功能:写寄存器函数
参    数:regval:寄存器值
*/   
void LcdWriteReg(u16 regval)
{
  LCD_REG=regval;//写入要写的寄存器序号  
}
/*
函数功能:写LCD数据
函数参数:data:要写入的值 
*/
void LcdWriteData(u16 data)
{  
  LCD_RAM=data;    
}
/*
函数功能:读LCD数据
返 回 值:读到的值
*/
u16 LcdReadData(void)
{
  vu16 ram;     //防止被优化
  ram=LCD_RAM;  
  return ram;  
}   
/*
函数功能:读寄存器
函数参数:LCD_Reg:寄存器地址
返 回 值:读到的数据
*/
u16 LcdReadReg(u16 LCD_Reg)
{                      
  LcdWriteReg(LCD_Reg);   //写入要读的寄存器序号
  DelayUs(5);     
  return LcdReadData();   //返回读到的值
}
/*
函数功能:开始写GRAM
*/
void LcdWriteRAM_Prepare(void)
{
  LCD_REG=0X2C;   
} 
/*
函数功能:LCD写GRAM
函数参数:RGB_Code:颜色值
*/
void LcdWriteRAM(u16 RGB_Code)
{                 
  LCD_RAM = RGB_Code;//写十六位GRAM
}
/*
函数功能:设置光标位置
函数参数:
         Xpos:横坐标
         Ypos:纵坐标
*/
void LcdSetCursor(u16 Xpos, u16 Ypos)
{  
    LcdWriteReg(0X2A); 
    LcdWriteData(Xpos>>8);
    LcdWriteData(Xpos&0XFF);       
    LcdWriteReg(0X2B); 
    LcdWriteData(Ypos>>8);
    LcdWriteData(Ypos&0XFF); 
}
/*
功能:读取个某点的颜色值  
参数:x,y:坐标
返回值:此点的颜色
*/
u16 LcdReadPoint(u16 x,u16 y)
{
  u16 r=0,g=0,b=0;   
  LcdSetCursor(x,y);      
  LcdWriteReg(0X2E);
  r=LcdReadData();                //dummy Read     
  DelayUs(1);   
  r=LcdReadData();                    //实际坐标颜色
  DelayUs(1);   
  b=LcdReadData(); 
  g=r&0XFF;   //5310第一次读取的是RG的值,R在前,G在后,各占8位
  g<<=8;
  return (((r>>11)<<11)|((g>>10)<<5)|(b>>11));
} 
/*
功  能: 初始化LCD屏幕
说  明: 用于3.5寸屏幕的初始化。 
         LCD ID:5310
*/
void LcdInit(void)
{                       
  RCC->AHBENR|=1<<8;        //使能FSMC时钟    
  RCC->APB2ENR|=1<<3;       //使能PORTB时钟
  RCC->APB2ENR|=1<<5;       //使能PORTD时钟
  RCC->APB2ENR|=1<<6;       //使能PORTE时钟
  RCC->APB2ENR|=1<<8;       //使能PORTG时钟  
  GPIOB->CRL&=0XFFFFFFF0;   //PB0 推挽输出 背光
  GPIOB->CRL|=0X00000003;    
  //PORTD复用推挽输出   
  GPIOD->CRH&=0X00FFF000;
  GPIOD->CRH|=0XBB000BBB; 
  GPIOD->CRL&=0XFF00FF00;
  GPIOD->CRL|=0X00BB00BB;      
  //PORTE复用推挽输出   
  GPIOE->CRH&=0X00000000;
  GPIOE->CRH|=0XBBBBBBBB; 
  GPIOE->CRL&=0X0FFFFFFF;
  GPIOE->CRL|=0XB0000000;                                  
  //PORTG12复用推挽输出                                
  GPIOG->CRH&=0XFFF0FFFF;
  GPIOG->CRH|=0X000B0000; 
  GPIOG->CRL&=0XFFFFFFF0;//PG0->RS
  GPIOG->CRL|=0X0000000B;  
  //寄存器清零
  //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
  //这里我们使用NE4 ,也就对应BTCR[6],[7]。           
  FSMC_Bank1->BTCR[6]=0X00000000;
  FSMC_Bank1->BTCR[7]=0X00000000;
  FSMC_Bank1E->BWTR[6]=0X00000000;
  //操作BCR寄存器  使用异步模式
  FSMC_Bank1->BTCR[6]|=1<<12;   //存储器写使能
  FSMC_Bank1->BTCR[6]|=1<<14;   //读写使用不同的时序
  FSMC_Bank1->BTCR[6]|=1<<4;    //存储器数据宽度为16bit      
  //操作BTR寄存器  
  //读时序控制寄存器                  
  FSMC_Bank1->BTCR[7]|=0<<28;   //模式A                      
  FSMC_Bank1->BTCR[7]|=1<<0;    //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns(实际>200ns)     
  //因为液晶驱动IC的读数据的时候,速度不能太快,尤其对1289这个IC。
  FSMC_Bank1->BTCR[7]|=0XF<<8;    //数据保存时间为16个HCLK     
  //写时序控制寄存器  
  FSMC_Bank1E->BWTR[6]|=0<<28;  //模式A                     
  FSMC_Bank1E->BWTR[6]|=0<<0;   //地址建立时间(ADDSET)为1个HCLK 
  //4个HCLK(HCLK=72M)因为液晶驱动IC的写信号脉宽,最少也得50ns。72M/4=24M=55ns     
  FSMC_Bank1E->BWTR[6]|=3<<8;   //数据保存时间为4个HCLK 
  //使能BANK1,区域4
  FSMC_Bank1->BTCR[6]|=1<<0;    //使能BANK1,区域4 
  DelayMs(50);          // delay 50 ms 
  lcddev.id=LcdReadReg(0x0000); //读ID(9320/9325/9328/4531/4535等IC)   
  LcdWriteReg(0XD4);           
  lcddev.id=LcdReadData();//dummy read  
  lcddev.id=LcdReadData();//读回0X01   
  lcddev.id=LcdReadData();//读回0X53  
  lcddev.id<<=8;   
  lcddev.id|=LcdReadData(); //这里读回0X10   
  printf(" LCD ID:%x\r\n",lcddev.id); //打印LCD ID
    //if(lcddev.id==0x5310)
    LcdWriteReg(0xED);
    LcdWriteData(0x01);
    LcdWriteData(0xFE);
    LcdWriteReg(0xEE);
    LcdWriteData(0xDE);
    LcdWriteData(0x21);
    LcdWriteReg(0xF1);
    LcdWriteData(0x01);
    LcdWriteReg(0xDF);
    LcdWriteData(0x10);
    //VCOMvoltage//
    LcdWriteReg(0xC4);
    LcdWriteData(0x8F);   //5f
    LcdWriteReg(0xC6);
    LcdWriteData(0x00);
    LcdWriteData(0xE2);
    LcdWriteData(0xE2);
    LcdWriteData(0xE2);
    LcdWriteReg(0xBF);
    LcdWriteData(0xAA);
    LcdWriteReg(0xB0);
    LcdWriteData(0x0D);
    LcdWriteData(0x00);
    LcdWriteData(0x0D);
    LcdWriteData(0x00);
    LcdWriteData(0x11);
    LcdWriteData(0x00);
    LcdWriteData(0x19);
    LcdWriteData(0x00);
    LcdWriteData(0x21);
    LcdWriteData(0x00);
    LcdWriteData(0x2D);
    LcdWriteData(0x00);
    LcdWriteData(0x3D);
    LcdWriteData(0x00);
    LcdWriteData(0x5D);
    LcdWriteData(0x00);
    LcdWriteData(0x5D);
    LcdWriteData(0x00);
    LcdWriteReg(0xB1);
    LcdWriteData(0x80);
    LcdWriteData(0x00);
    LcdWriteData(0x8B);
    LcdWriteData(0x00);
    LcdWriteData(0x96);
    LcdWriteData(0x00);
    LcdWriteReg(0xB2);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x02);
    LcdWriteData(0x00);
    LcdWriteData(0x03);
    LcdWriteData(0x00);
    LcdWriteReg(0xB3);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xB4);
    LcdWriteData(0x8B);
    LcdWriteData(0x00);
    LcdWriteData(0x96);
    LcdWriteData(0x00);
    LcdWriteData(0xA1);
    LcdWriteData(0x00);
    LcdWriteReg(0xB5);
    LcdWriteData(0x02);
    LcdWriteData(0x00);
    LcdWriteData(0x03);
    LcdWriteData(0x00);
    LcdWriteData(0x04);
    LcdWriteData(0x00);
    LcdWriteReg(0xB6);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xB7);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x3F);
    LcdWriteData(0x00);
    LcdWriteData(0x5E);
    LcdWriteData(0x00);
    LcdWriteData(0x64);
    LcdWriteData(0x00);
    LcdWriteData(0x8C);
    LcdWriteData(0x00);
    LcdWriteData(0xAC);
    LcdWriteData(0x00);
    LcdWriteData(0xDC);
    LcdWriteData(0x00);
    LcdWriteData(0x70);
    LcdWriteData(0x00);
    LcdWriteData(0x90);
    LcdWriteData(0x00);
    LcdWriteData(0xEB);
    LcdWriteData(0x00);
    LcdWriteData(0xDC);
    LcdWriteData(0x00);
    LcdWriteReg(0xB8);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xBA);
    LcdWriteData(0x24);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xC1);
    LcdWriteData(0x20);
    LcdWriteData(0x00);
    LcdWriteData(0x54);
    LcdWriteData(0x00);
    LcdWriteData(0xFF);
    LcdWriteData(0x00);
    LcdWriteReg(0xC2);
    LcdWriteData(0x0A);
    LcdWriteData(0x00);
    LcdWriteData(0x04);
    LcdWriteData(0x00);
    LcdWriteReg(0xC3);
    LcdWriteData(0x3C);
    LcdWriteData(0x00);
    LcdWriteData(0x3A);
    LcdWriteData(0x00);
    LcdWriteData(0x39);
    LcdWriteData(0x00);
    LcdWriteData(0x37);
    LcdWriteData(0x00);
    LcdWriteData(0x3C);
    LcdWriteData(0x00);
    LcdWriteData(0x36);
    LcdWriteData(0x00);
    LcdWriteData(0x32);
    LcdWriteData(0x00);
    LcdWriteData(0x2F);
    LcdWriteData(0x00);
    LcdWriteData(0x2C);
    LcdWriteData(0x00);
    LcdWriteData(0x29);
    LcdWriteData(0x00);
    LcdWriteData(0x26);
    LcdWriteData(0x00);
    LcdWriteData(0x24);
    LcdWriteData(0x00);
    LcdWriteData(0x24);
    LcdWriteData(0x00);
    LcdWriteData(0x23);
    LcdWriteData(0x00);
    LcdWriteData(0x3C);
    LcdWriteData(0x00);
    LcdWriteData(0x36);
    LcdWriteData(0x00);
    LcdWriteData(0x32);
    LcdWriteData(0x00);
    LcdWriteData(0x2F);
    LcdWriteData(0x00);
    LcdWriteData(0x2C);
    LcdWriteData(0x00);
    LcdWriteData(0x29);
    LcdWriteData(0x00);
    LcdWriteData(0x26);
    LcdWriteData(0x00);
    LcdWriteData(0x24);
    LcdWriteData(0x00);
    LcdWriteData(0x24);
    LcdWriteData(0x00);
    LcdWriteData(0x23);
    LcdWriteData(0x00);
    LcdWriteReg(0xC4);
    LcdWriteData(0x62);
    LcdWriteData(0x00);
    LcdWriteData(0x05);
    LcdWriteData(0x00);
    LcdWriteData(0x84);
    LcdWriteData(0x00);
    LcdWriteData(0xF0);
    LcdWriteData(0x00);
    LcdWriteData(0x18);
    LcdWriteData(0x00);
    LcdWriteData(0xA4);
    LcdWriteData(0x00);
    LcdWriteData(0x18);
    LcdWriteData(0x00);
    LcdWriteData(0x50);
    LcdWriteData(0x00);
    LcdWriteData(0x0C);
    LcdWriteData(0x00);
    LcdWriteData(0x17);
    LcdWriteData(0x00);
    LcdWriteData(0x95);
    LcdWriteData(0x00);
    LcdWriteData(0xF3);
    LcdWriteData(0x00);
    LcdWriteData(0xE6);
    LcdWriteData(0x00);
    LcdWriteReg(0xC5);
    LcdWriteData(0x32);
    LcdWriteData(0x00);
    LcdWriteData(0x44);
    LcdWriteData(0x00);
    LcdWriteData(0x65);
    LcdWriteData(0x00);
    LcdWriteData(0x76);
    LcdWriteData(0x00);
    LcdWriteData(0x88);
    LcdWriteData(0x00);
    LcdWriteReg(0xC6);
    LcdWriteData(0x20);
    LcdWriteData(0x00);
    LcdWriteData(0x17);
    LcdWriteData(0x00);
    LcdWriteData(0x01);
    LcdWriteData(0x00);
    LcdWriteReg(0xC7);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xC8);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xC9);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xE0);
    LcdWriteData(0x16);
    LcdWriteData(0x00);
    LcdWriteData(0x1C);
    LcdWriteData(0x00);
    LcdWriteData(0x21);
    LcdWriteData(0x00);
    LcdWriteData(0x36);
    LcdWriteData(0x00);
    LcdWriteData(0x46);
    LcdWriteData(0x00);
    LcdWriteData(0x52);
    LcdWriteData(0x00);
    LcdWriteData(0x64);
    LcdWriteData(0x00);
    LcdWriteData(0x7A);
    LcdWriteData(0x00);
    LcdWriteData(0x8B);
    LcdWriteData(0x00);
    LcdWriteData(0x99);
    LcdWriteData(0x00);
    LcdWriteData(0xA8);
    LcdWriteData(0x00);
    LcdWriteData(0xB9);
    LcdWriteData(0x00);
    LcdWriteData(0xC4);
    LcdWriteData(0x00);
    LcdWriteData(0xCA);
    LcdWriteData(0x00);
    LcdWriteData(0xD2);
    LcdWriteData(0x00);
    LcdWriteData(0xD9);
    LcdWriteData(0x00);
    LcdWriteData(0xE0);
    LcdWriteData(0x00);
    LcdWriteData(0xF3);
    LcdWriteData(0x00);
    LcdWriteReg(0xE1);
    LcdWriteData(0x16);
    LcdWriteData(0x00);
    LcdWriteData(0x1C);
    LcdWriteData(0x00);
    LcdWriteData(0x22);
    LcdWriteData(0x00);
    LcdWriteData(0x36);
    LcdWriteData(0x00);
    LcdWriteData(0x45);
    LcdWriteData(0x00);
    LcdWriteData(0x52);
    LcdWriteData(0x00);
    LcdWriteData(0x64);
    LcdWriteData(0x00);
    LcdWriteData(0x7A);
    LcdWriteData(0x00);
    LcdWriteData(0x8B);
    LcdWriteData(0x00);
    LcdWriteData(0x99);
    LcdWriteData(0x00);
    LcdWriteData(0xA8);
    LcdWriteData(0x00);
    LcdWriteData(0xB9);
    LcdWriteData(0x00);
    LcdWriteData(0xC4);
    LcdWriteData(0x00);
    LcdWriteData(0xCA);
    LcdWriteData(0x00);
    LcdWriteData(0xD2);
    LcdWriteData(0x00);
    LcdWriteData(0xD8);
    LcdWriteData(0x00);
    LcdWriteData(0xE0);
    LcdWriteData(0x00);
    LcdWriteData(0xF3);
    LcdWriteData(0x00);
    LcdWriteReg(0xE2);
    LcdWriteData(0x05);
    LcdWriteData(0x00);
    LcdWriteData(0x0B);
    LcdWriteData(0x00);
    LcdWriteData(0x1B);
    LcdWriteData(0x00);
    LcdWriteData(0x34);
    LcdWriteData(0x00);
    LcdWriteData(0x44);
    LcdWriteData(0x00);
    LcdWriteData(0x4F);
    LcdWriteData(0x00);
    LcdWriteData(0x61);
    LcdWriteData(0x00);
    LcdWriteData(0x79);
    LcdWriteData(0x00);
    LcdWriteData(0x88);
    LcdWriteData(0x00);
    LcdWriteData(0x97);
    LcdWriteData(0x00);
    LcdWriteData(0xA6);
    LcdWriteData(0x00);
    LcdWriteData(0xB7);
    LcdWriteData(0x00);
    LcdWriteData(0xC2);
    LcdWriteData(0x00);
    LcdWriteData(0xC7);
    LcdWriteData(0x00);
    LcdWriteData(0xD1);
    LcdWriteData(0x00);
    LcdWriteData(0xD6);
    LcdWriteData(0x00);
    LcdWriteData(0xDD);
    LcdWriteData(0x00);
    LcdWriteData(0xF3);
    LcdWriteData(0x00);
    LcdWriteReg(0xE3);
    LcdWriteData(0x05);
    LcdWriteData(0x00);
    LcdWriteData(0xA);
    LcdWriteData(0x00);
    LcdWriteData(0x1C);
    LcdWriteData(0x00);
    LcdWriteData(0x33);
    LcdWriteData(0x00);
    LcdWriteData(0x44);
    LcdWriteData(0x00);
    LcdWriteData(0x50);
    LcdWriteData(0x00);
    LcdWriteData(0x62);
    LcdWriteData(0x00);
    LcdWriteData(0x78);
    LcdWriteData(0x00);
    LcdWriteData(0x88);
    LcdWriteData(0x00);
    LcdWriteData(0x97);
    LcdWriteData(0x00);
    LcdWriteData(0xA6);
    LcdWriteData(0x00);
    LcdWriteData(0xB7);
    LcdWriteData(0x00);
    LcdWriteData(0xC2);
    LcdWriteData(0x00);
    LcdWriteData(0xC7);
    LcdWriteData(0x00);
    LcdWriteData(0xD1);
    LcdWriteData(0x00);
    LcdWriteData(0xD5);
    LcdWriteData(0x00);
    LcdWriteData(0xDD);
    LcdWriteData(0x00);
    LcdWriteData(0xF3);
    LcdWriteData(0x00);
    LcdWriteReg(0xE4);
    LcdWriteData(0x01);
    LcdWriteData(0x00);
    LcdWriteData(0x01);
    LcdWriteData(0x00);
    LcdWriteData(0x02);
    LcdWriteData(0x00);
    LcdWriteData(0x2A);
    LcdWriteData(0x00);
    LcdWriteData(0x3C);
    LcdWriteData(0x00);
    LcdWriteData(0x4B);
    LcdWriteData(0x00);
    LcdWriteData(0x5D);
    LcdWriteData(0x00);
    LcdWriteData(0x74);
    LcdWriteData(0x00);
    LcdWriteData(0x84);
    LcdWriteData(0x00);
    LcdWriteData(0x93);
    LcdWriteData(0x00);
    LcdWriteData(0xA2);
    LcdWriteData(0x00);
    LcdWriteData(0xB3);
    LcdWriteData(0x00);
    LcdWriteData(0xBE);
    LcdWriteData(0x00);
    LcdWriteData(0xC4);
    LcdWriteData(0x00);
    LcdWriteData(0xCD);
    LcdWriteData(0x00);
    LcdWriteData(0xD3);
    LcdWriteData(0x00);
    LcdWriteData(0xDD);
    LcdWriteData(0x00);
    LcdWriteData(0xF3);
    LcdWriteData(0x00);
    LcdWriteReg(0xE5);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x02);
    LcdWriteData(0x00);
    LcdWriteData(0x29);
    LcdWriteData(0x00);
    LcdWriteData(0x3C);
    LcdWriteData(0x00);
    LcdWriteData(0x4B);
    LcdWriteData(0x00);
    LcdWriteData(0x5D);
    LcdWriteData(0x00);
    LcdWriteData(0x74);
    LcdWriteData(0x00);
    LcdWriteData(0x84);
    LcdWriteData(0x00);
    LcdWriteData(0x93);
    LcdWriteData(0x00);
    LcdWriteData(0xA2);
    LcdWriteData(0x00);
    LcdWriteData(0xB3);
    LcdWriteData(0x00);
    LcdWriteData(0xBE);
    LcdWriteData(0x00);
    LcdWriteData(0xC4);
    LcdWriteData(0x00);
    LcdWriteData(0xCD);
    LcdWriteData(0x00);
    LcdWriteData(0xD3);
    LcdWriteData(0x00);
    LcdWriteData(0xDC);
    LcdWriteData(0x00);
    LcdWriteData(0xF3);
    LcdWriteData(0x00);
    LcdWriteReg(0xE6);
    LcdWriteData(0x11);
    LcdWriteData(0x00);
    LcdWriteData(0x34);
    LcdWriteData(0x00);
    LcdWriteData(0x56);
    LcdWriteData(0x00);
    LcdWriteData(0x76);
    LcdWriteData(0x00);
    LcdWriteData(0x77);
    LcdWriteData(0x00);
    LcdWriteData(0x66);
    LcdWriteData(0x00);
    LcdWriteData(0x88);
    LcdWriteData(0x00);
    LcdWriteData(0x99);
    LcdWriteData(0x00);
    LcdWriteData(0xBB);
    LcdWriteData(0x00);
    LcdWriteData(0x99);
    LcdWriteData(0x00);
    LcdWriteData(0x66);
    LcdWriteData(0x00);
    LcdWriteData(0x55);
    LcdWriteData(0x00);
    LcdWriteData(0x55);
    LcdWriteData(0x00);
    LcdWriteData(0x45);
    LcdWriteData(0x00);
    LcdWriteData(0x43);
    LcdWriteData(0x00);
    LcdWriteData(0x44);
    LcdWriteData(0x00);
    LcdWriteReg(0xE7);
    LcdWriteData(0x32);
    LcdWriteData(0x00);
    LcdWriteData(0x55);
    LcdWriteData(0x00);
    LcdWriteData(0x76);
    LcdWriteData(0x00);
    LcdWriteData(0x66);
    LcdWriteData(0x00);
    LcdWriteData(0x67);
    LcdWriteData(0x00);
    LcdWriteData(0x67);
    LcdWriteData(0x00);
    LcdWriteData(0x87);
    LcdWriteData(0x00);
    LcdWriteData(0x99);
    LcdWriteData(0x00);
    LcdWriteData(0xBB);
    LcdWriteData(0x00);
    LcdWriteData(0x99);
    LcdWriteData(0x00);
    LcdWriteData(0x77);
    LcdWriteData(0x00);
    LcdWriteData(0x44);
    LcdWriteData(0x00);
    LcdWriteData(0x56);
    LcdWriteData(0x00);
    LcdWriteData(0x23); 
    LcdWriteData(0x00);
    LcdWriteData(0x33);
    LcdWriteData(0x00);
    LcdWriteData(0x45);
    LcdWriteData(0x00);
    LcdWriteReg(0xE8);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x99);
    LcdWriteData(0x00);
    LcdWriteData(0x87);
    LcdWriteData(0x00);
    LcdWriteData(0x88);
    LcdWriteData(0x00);
    LcdWriteData(0x77);
    LcdWriteData(0x00);
    LcdWriteData(0x66);
    LcdWriteData(0x00);
    LcdWriteData(0x88);
    LcdWriteData(0x00);
    LcdWriteData(0xAA);
    LcdWriteData(0x00);
    LcdWriteData(0xBB);
    LcdWriteData(0x00);
    LcdWriteData(0x99);
    LcdWriteData(0x00);
    LcdWriteData(0x66);
    LcdWriteData(0x00);
    LcdWriteData(0x55);
    LcdWriteData(0x00);
    LcdWriteData(0x55);
    LcdWriteData(0x00);
    LcdWriteData(0x44);
    LcdWriteData(0x00);
    LcdWriteData(0x44);
    LcdWriteData(0x00);
    LcdWriteData(0x55);
    LcdWriteData(0x00);
    LcdWriteReg(0xE9);
    LcdWriteData(0xAA);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0x00);
    LcdWriteData(0xAA);
    LcdWriteReg(0xCF);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xF0);
    LcdWriteData(0x00);
    LcdWriteData(0x50);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteData(0x00);
    LcdWriteReg(0xF3);
    LcdWriteData(0x00);
    LcdWriteReg(0xF9);
    LcdWriteData(0x06);
    LcdWriteData(0x10);
    LcdWriteData(0x29);
    LcdWriteData(0x00);
    LcdWriteReg(0x3A);
    LcdWriteData(0x55); //66
    LcdWriteReg(0x11);
    DelayMs(100);
    LcdWriteReg(0x29);
    LcdWriteReg(0x35);
    LcdWriteData(0x00);
    LcdWriteReg(0x51);
    LcdWriteData(0xFF);
    LcdWriteReg(0x53);
    LcdWriteData(0x2C);
    LcdWriteReg(0x55);
    LcdWriteData(0x82);
    LcdWriteReg(0x2c);
    lcddev.width=320;
    lcddev.height=480;
    LCD_LED=1;        //点亮背光
} 

4.3 LCD相关的绘图函数代码示例

/*
函数功能:画点函数
参    数:x,y坐标
          color颜色值
*/
void LcdDrawPoint(u16 x,u16 y,u16 color)
{
  LcdSetCursor(x,y);      //设置光标位置 
  LcdWriteRAM_Prepare();  //开始写入GRAM
  LCD_RAM=color; 
}
/*
函数功能:清屏函数
参    数:color颜色值
*/
void LcdClear(u16 color)
{
  u32 i;
  LcdSetCursor(0,0);      //设置光标位置 
  LcdWriteRAM_Prepare();  //开始写入GRAM
  for(i=0;i<320*480;i++)LCD_RAM=color; 
}
/*
函数功能:显示一个指定大小的汉字
参    数:
          x,y :汉字的坐标
          font:取模数据
          size:字体大小尺寸
*/
void LcdShowFont(u16 x,u16 y,u8 *dzk,u8 size)
{
  u8 temp,t,t1;
  u16 x0=x; 
  u8 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数  
      for(t=0;t<csize;t++)
      {                              
        temp=dzk[t];                       
       for(t1=0;t1<8;t1++)
       {
          if(temp&0x80)LcdDrawPoint(x,y,0x0);
          else 
          {
             LcdDrawPoint(x,y,0xffff);
          }
          temp<<=1;
          x++;
          if((x-x0)==size)
          {
            x=x0;
            y++;
            break;
          }
      }      
    }    
}
/*
函数功能:矩形颜色填充
参    数:(sx,sy),(ex,ey):矩形对角坐标
          color:要填充的颜色
*/
void LcdFill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)
{          
  u16 i,j;
  u16 xlen=0;
  xlen=ex-sx+1;  
  for(i=sy;i<=ey;i++)
  {
    LcdSetCursor(sx,i);             //设置光标位置 
    LcdWriteRAM_Prepare();          //开始写入GRAM    
    for(j=0;j<xlen;j++)LcdWriteData(color);     
  }  
} 
/*
函数功能:画直线
参    数:x1,y1:起点坐标
          x2,y2:终点坐标 
*/
void LcdDrawLine(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
{
  u16 t; 
  int xerr=0,yerr=0,delta_x,delta_y,distance; 
  int 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++ )//画线输出 
  {  
    LcdDrawPoint(uRow,uCol,color);//画点 
    xerr+=delta_x ; 
    yerr+=delta_y ; 
    if(xerr>distance) 
    { 
      xerr-=distance; 
      uRow+=incx; 
    } 
    if(yerr>distance) 
    { 
      yerr-=distance; 
      uCol+=incy; 
    } 
  }  
}  
/*
函数功能:任意角度画直线 
参    数:
          w  :线段的长度
          len:半径
          c  :颜色
          x,y:坐标
*/
#include <math.h>
void LcdDrawAngleLine(u32 x,u32 y,float du,u32 len,u32 w,u16 c)
{
  int i;
  int x0,y0;
  float k=du*(3.1415926535/180);  
  for(i=len-w;i<len;i++)
  {
    x0=cos(k)*i;
    y0=sin(k)*i;
    LcdDrawPoint(x+x0,y+y0,c);
  } 
}
/*
函数功能:画矩形  
参    数:(x1,y1),(x2,y2):矩形的对角坐标
*/
void LcdDrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
{
  LcdDrawLine(x1,y1,x2,y1,color);
  LcdDrawLine(x1,y1,x1,y2,color);
  LcdDrawLine(x1,y2,x2,y2,color);
  LcdDrawLine(x2,y1,x2,y2,color);
}
/*
函数功能:在指定位置画一个指定大小的圆
参    数:
          (x,y):中心点
          r    :半径
*/
void LcdDrawCircle(u16 x0,u16 y0,u8 r,u16 color)
{
  int a,b;
  int di;
  a=0;b=r;    
  di=3-(r<<1);             //判断下个点位置的标志
  while(a<=b)
  {
    LcdDrawPoint(x0+a,y0-b,color);             //5
    LcdDrawPoint(x0+b,y0-a,color);             //0           
    LcdDrawPoint(x0+b,y0+a,color);             //4               
    LcdDrawPoint(x0+a,y0+b,color);             //6 
    LcdDrawPoint(x0-a,y0+b,color);             //1       
    LcdDrawPoint(x0-b,y0+a,color);             
    LcdDrawPoint(x0-a,y0-b,color);             //2             
    LcdDrawPoint(x0-b,y0-a,color);             //7               
    a++;  
    if(di<0)di +=4*a+6; //Bresenham画圆算法   
    else
    {
      di+=10+4*(a-b);   
      b--;
    }                 
  }
}
/*
函数功能:显示图片
参    数:(图片起始横坐标,图片起始纵坐标,图片横像素,图片纵像素,要显示的图片首地址)
*/
void LcdShowPicture(u32 x,u32 y,u32 x1,u32 x2,const unsigned char * p)
{ 
  u32 x0,y0;   
  for(y0=0;y0<x2;y0++)
   { 
     for(x0=0;x0<x1;x0++)
      { 
         LcdDrawPoint(x+x0,y+y0,(*p<<8)+*(p+1));  //图片取模方式-->高位在前
        //画点LCD的像素是16位的,所以需要将2个8位像素合成16位像素。
         p+=2;
      }
   }
}

五、按键驱动代码示例

拼图的时候,通过4个按键控制上下左右方向的,按键的代码如下:

功能    :按键的初始化
硬件连接:
KEY1:PA0  --按下是高电平
KEY2:PE2  --按下是低电平
KEY3:PE3  --按下是低电平
KEY4:PE4  --按下是低电平
返回值:无
*/
void KeyInit(void)
{
   /*1. 开时钟*/
   RCC->APB2ENR|=1<<2; //PA
   RCC->APB2ENR|=1<<6; //PE 
   /*2. 配置GPIO口模式*/
   GPIOA->CRL&=0xFFFFFFF0;
   GPIOA->CRL|=0x00000008; //上下拉输入模式
   GPIOE->CRL&=0xFFF000FF;
   GPIOE->CRL|=0x00088800; //上下拉输入模式
   /*3. 上下拉控制*/
   //GPIOA->ODR&=~(1<<0); //PA0下拉
   GPIOE->ODR|=1<<2;
   GPIOE->ODR|=1<<3;
   GPIOE->ODR|=1<<4;
}
/*
功  能:获取按键值
返回值:
    1表示按键1按下
    2表示按键2按下
    3表示按键3按下
    4表示按键4按下
    0表示没有按键按下
实现单次按下模式(上一次按下的按键没有松开,就不做检测)和连续按下的模式。
模式:
   mode=1; //表示单击
   mode=0; //表示连续
*/
u8 GetKeyValue(u32 mode)
{
   static int stat=0; //保存上一次按键的状态
   if(mode==0)stat=0;
   if((KEY1||KEY2==0||KEY3==0||KEY4==0) && stat==0)
   {
      DelayMs(20); //延时消抖
      stat=1;      //表示上次有按键按下
      if(KEY1)return 1;
      if(KEY2==0)return 2;
      if(KEY3==0)return 3;
      if(KEY4==0)return 4;
   }
   else
   {
      if(KEY1==0&&KEY2&&KEY3&&KEY4)stat=0; //判断所有的按键是否已经松开
   }
   return 0;
}

六、拼图的逻辑代码

分隔图片: 这里是按照320*240---2.8寸计算的

//           0,0         60,0         120,0         180,0
//           0,80        60,80        120, 80        180,80
//           0,160       60,160,      120, 160,      180,160
//           0,240,      60,240       120, 240       180,240
//显示位置起始坐标。
u32 record[16][2];
int pic[16][2]=      
{//第i张图片的屏幕所在位置。
  {60,160},{180,80},{0,80},
 {180,0},{180,160},{180,240},
 {0,160},{120,160},{60,80},{120,0},
 {120,240},{120,80},{0,0},{60,240},{60,0},{0,240}}; 

循环里处理图片移动逻辑:

while(1)
  {
      //【1】产生随机图片ID号:0--15,   4号图片用作空白图片。
 //ID号和图片首地址固定。图片所在的位置不固定。  
    picture_production(tu32,pic);
    while(1)
    {
        key=GetKeyValue(1);
       if(key==1)      //右移动
        {if(record[4][0]>0)              //180,160
          {
            number=lookingfor_blankblock(record[4][0]-60,record[4][1],tu32);
            show_picture_(record[4][0],record[4][1],tu32,number);//空白左边图覆盖空白
            show_picture_(record[4][0]-60,record[4][1],tu32,4);  //出现新空白
            k=record[number][0];
            record[number][0]=record[4][0];
            record[4][0]=k;
          }
        }
        if(key==3)    //左移动
        {if(record[4][0]<180)              //180,160
          {
            number=lookingfor_blankblock(record[4][0]+60,record[4][1],tu32);
            show_picture_(record[4][0],record[4][1],tu32,number);//空白左边图覆盖空白
            show_picture_(record[4][0]+60,record[4][1],tu32,4);  //出现新空白
            k=record[number][0];
            record[number][0]=record[4][0];
            record[4][0]=k;
                                //新空白横坐标
          }
        }
        if(key==2)    //下移动
        {if(record[4][1]>0)  
           { 
            number=lookingfor_blankblock(record[4][0],record[4][1]-80,tu32);
            show_picture_(record[4][0],record[4][1],tu32,number);//空白左边图覆盖空白
            show_picture_(record[4][0],record[4][1]-80,tu32,4);  //出现新空白
            k=record[number][1];
            record[number][1]=record[4][1];
            record[4][1]=k;
           }
        }
        if(key==4)    //上移动
        {
          if(record[4][1]<240)
            {
            number=lookingfor_blankblock(record[4][0],record[4][1]+80,tu32);
            show_picture_(record[4][0],record[4][1],tu32,number);//空白左边图覆盖空白
            show_picture_(record[4][0],record[4][1]+80,tu32,4);  //出现新空白
            k=record[number][1];
            record[number][1]=record[4][1];
            record[4][1]=k;
            }
        }
      }
  }
目录
相关文章
|
传感器 数据采集 监控
上千个完整设计的单片机、8086、STM32制作教程和资料-转发分享
在网上收集了接近上千个完整设计的单片机、8086、STM32制作教程和资料-转发分享(涵盖了大部分的毕设课设题目),学习单片机的最好教程,也可以作为帮助大家在做电子课设毕设时有利的帮助,可以从以下百度网盘下载(按照编号下载)。
1949 0
上千个完整设计的单片机、8086、STM32制作教程和资料-转发分享
|
传感器 网络协议 物联网
基于STM32设计的智能家居系统(采用ESP8266+OneNet云平台)
基于STM32设计的智能家居系统(采用ESP8266+OneNet云平台)
1319 1
基于STM32设计的智能家居系统(采用ESP8266+OneNet云平台)
|
存储 JSON 移动开发
基于STM32+ESP8266的奥运会奖牌榜设计之经典
基于STM32+ESP8266的奥运会奖牌榜设计之经典
201 0
基于STM32+ESP8266的奥运会奖牌榜设计之经典
|
定位技术 异构计算
|
传感器 数据采集 编解码
基于STM32设计的环境检测设备
设计以STM32微控制器为平台,采用DHT11温湿度传感器、烟雾传感器MQ-2、易燃气体传感器MQ-4、空气质量检测传感器MQ-135对室内温湿度和危险气体进行采集。通过wifi无线网络将数据传送给微控制器,STM32微控制器处理数据后,由自带oled液晶屏显示。当室内温度达到预警值或有危险气体时,系统将会自动警报并将警报信息通过wifi网络传输给客户手机。且每隔一段时间会通过wifi自动发送监测信息到手机,从而实现对室内环境的监测及报警功能。
709 0
|
算法 芯片
基于STM32设计的计算器(实现基本运算)
当前文章介绍的是STM32+LCD触摸屏设计的一个触摸计算器功能,实现基本的加减乘除,二进制转换显示等功能。LCD屏使用的是3.5寸带触摸屏的显示屏,方便操作屏幕,MCU采用STM32F103ZET6。设计的这个计算器用到的硬件不多,主要是LCD屏和触摸屏,用到了一个W25Q64存储芯片。
416 0
|
传感器 算法
基于STM32设计的健康检测设备(测温心率计步)
本文介绍的项目是基于STM32设计的健康检测设备,支持体温测量,心率检测,支持运动计步(采用MPU6050陀螺仪实现),支持WIFI传输数据到手机APP打印显示。
350 0
|
传感器 数据采集 前端开发
基于STM32设计的数字电子秤
当前项目是采用采用STM32+称重模块+OLED实现了简单的电子秤项目,称重模块上采用24位的ADC芯片,精度较高。实现了称重,校准、去皮等功能。
681 0
|
物联网 数据安全/隐私保护 芯片
基于STM32设计的校园一卡通项目
本文介绍通过STM32 微控制器+RFID RC522设计的一个**校园一卡通消费充值机的项目**,可以模拟实现充值、消费、修改密码、挂失、登录、查询.......等操作。
434 0
|
传感器 算法 芯片
基于STM32设计的指针式电子钟与日历
这是基于STM32设计的一个指针式电子钟+万年历小项目,采用3.5寸的LCD屏显示时钟,日历、温度、天气,支持触摸屏调整设置时间,设置闹钟,查看日历等等。整体项目主要是技术点就是LCD屏的图形绘制。比如: 时钟的时针绘制、分针、秒针、表盘、日历绘制等等。
654 0