• STM32学习之路-LCD(3)<显示图片>


    祝大家端午和六一快乐!原本今天是想歇息歇息的,可是实在无奈没什么事干.所以就来学习学习LCD显示图片的函数

    函数是照搬奋斗的样例,算是些笔记吧.只是奋斗的样例凝视的不是非常具体.今天去看了正点原子的论坛,唉..瞬间感觉正点原子做得真的非常好

    能把全部的资料都开源,而且论坛上大多问题都耐心的解答了.这实在是很很好的售后服务了!!自己也偷偷的去下了写资料来看看,(*^__^*) 嘻嘻……

    好,进入主题:

    开发板:奋斗V5

    LCD:3寸 400X240

    直接上代码吧

    void lcd_DrawPicture(u16 StartX,u16 StartY,u8 Dir,u8 *pic)
    {
      u32  i=8, len;
      u16 temp,x,y;
      	  
      /**************************************/
    	/*a1 长:240 宽:400*/
    	/*a2 长:400 宽:240*/
    	
      x=((uint16_t)(pic[2]<<8)+pic[3])-1;	  	//从图像数组里取出图像的长度
      y=((uint16_t)(pic[4]<<8)+pic[5])-1;	  	//从图像数组里取出图像的高度    
    
      if(Dir==0){
    	LCD_WR_CMD(0x0003,0x1030);   			//图像显示方向为左下起  行递增  列递增
            LCD_WR_CMD(0x0210, StartX); 			//水平显示区起始地址 0-239
      	LCD_WR_CMD(0x0211, StartX+x);           	//水平显示区结束地址 0-239
      	LCD_WR_CMD(0x0212, StartY);     		//垂直显示区起始地址 0-399
      	LCD_WR_CMD(0x0213, StartY+y);         	        //垂直显示区结束地址 0-399
      
      	LCD_WR_CMD(0x0200, StartX);		          	//水平显示区地址
      	LCD_WR_CMD(0x0201, StartY);		      		//垂直显示区地址
      }	 
      else if(Dir==1){
    	LCD_WR_CMD(0x0003,0x1018);   			//图像显示方向为左下起  行递增  列递减
            LCD_WR_CMD(0x0210, StartY); 			//水平显示区起始地址 0-239
      	LCD_WR_CMD(0x0211, StartY+y);           //水平显示区结束地址 0-239
      	LCD_WR_CMD(0x0212, 399-(x+StartX));     //垂直显示区起始地址 0-399
      	LCD_WR_CMD(0x0213, 399-StartX);         //垂直显示区结束地址 0-399
      
      	LCD_WR_CMD(0x200, StartY);		          	//水平显示区地址
      	LCD_WR_CMD(0x201, 399-StartX);		      	//垂直显示区地址
      }	 
      LCD_WR_REG(0x0202);				          	//写数据到显示区
    
       len=2*((uint16_t)(pic[2]<<8)+pic[3])*((uint16_t)(pic[4]<<8)+pic[5]);   //计算出图像所占的字节数  
    
      while(i<(len+8)) {							 //从图像数组的第9位開始递增
      	temp=(uint16_t)( pic[i]<<8)+pic[i+1];		 //16位总线, 须要一次发送2个字节的数据
      	LCD_WR_Data(temp);				 //将取出的16位像素数据送入显示区
    	i=i+2;						 //取模位置加2,以为获取下一个像素数据
      }
    }
    这是奋斗给的原版样例,当中的凝视都给出了各行待会的功能,让我们来看看他们详细是怎么实现的

    x=((uint16_t)(pic[2]<<8)+pic[3])-1;  y=((uint16_t)(pic[4]<<8)+pic[5])-1;

    为什么要这样计算图片的长和宽呢? 这时候就要看看图片的数组了.图片经过取模软件(这里用的是Image2LCD)把图片变成16进制的数组,非常长非常长的一个数组,可是

    我们这里仅仅关心它的前8个字符,这是400X240的一个图片取模出来的结果(当然仅仅是前面一小部分)

    这是240X400的图片的取模:

    我想头8位应该是固定的,并且240X400格式的照片前8位应该是一样的,400X240格式的也应该是一样的,这里我仅仅是自己下了两张照片

    取模的结果和奋斗给的样例中的图片是一样的,所以我猜是一样的,详细我也没去研究.还有就是取模然间要设置得对,取模结果才会和上面

    一样,显示照片才会正常,这个问题以下再说.好,回到上面的长度和宽度的分析:

    这时候你能够拿起笔来计算一下了,以240X400为例, x=((uint16_t)(pic[2]<<8)+pic[3])-1; y=((uint16_t)(pic[4]<<8)+pic[5])-1;

    pic[2] << 8 即 0x00左移8位,还是0x00,然后加上0xF0(十进制240),所以x=240-1=239(为了不超过屏幕范围)

    同理pic[4] <<8 等于0x100,然后加上0x90等于0x190(十进制400),所以y=400-1=399;

    400X240的也是这样算的...

    然后接下来是显示方向的问题,dir=0是竖屏(240x400),dir=1是横屏(400x240),然后接下来就是写数据了,上面已经有凝视了,这里就不说了,不明确的能够看前一篇文章

    len=2*((uint16_t)(pic[2]<<8)+pic[3])*((uint16_t)(pic[4]<<8)+pic[5]); 计算图像所占字节数,这里我似懂非懂,不知道理解的对不正确,这里按我的理解是长X宽,这个easy懂,

    为什么要乘于2,我想应该是求长和宽的时候是用了2个的字符合起来求的,所以这里要分成1个字节就要乘于2(这些是瞎写的,假设真的正确答案的朋友,就请帮忙解答下)

    接下来是

     while(i<(len+8)) {					  //从图像数组的第9位開始递增
      	temp=(uint16_t)( pic[i]<<8)+pic[i+1];		 //16位总线, 须要一次发送2个字节的数据
      	LCD_WR_Data(temp);<span style="white-space:pre">				</span>//将取出的16位像素数据送入显示区
    	i=i+2;					       //取模位置加2,以为获取下一个像素数据
    i的初始值为8,目的也就是为了跳过前8个字符,这也说明了前8个字符应该不是照片的内容,应该是前缀.

    好了,这就完了,接下来说说取模软件的设置吧,不小心这东西也会让你费非常多事情的,这里用的是Image2LCD



    第一个注意的点是输入的设置:最大宽度和最大高度要和你的照片相符,这张相片是400X240的

    第二个注意的点是输出图像:一開始输出图像并非(400,240)的,你要先设置最大宽度和最大高度以后,然后按上面的又一次加载一下,它才会输出正确的大小格式,要不然图像就不能正常显示,或者是不能显示.

    第三个注意的点是高位在前:要勾上它,要不然图像显示就不正常了!

    至于输出多少位的图片,是依据你的LCD接口方式来的.16位并口,就选择16位真彩色

    好了~这样就能够了,开发板图片就不传了,手机烂拍照不好看.


  • 相关阅读:
    SCRIPT7002: XMLHttpRequest: 网络错误 0x2efe, 由于出现错误 00002efe 而导致此项操作无法完成
    经纬转换成point的sql
    build.xml
    ubuntu下安装vsftpd及vsftpd配置文件不见的解决办法
    500 OOPS: could not read chroot() list file:/etc/vsftpd.chroot_list
    【linux】su、sudo、sudo su、sudo -i的用法和区别
    Js获取上一月份
    BigDecimal工具类
    查询重复的记录
    Excel 合并单元格
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4514112.html
Copyright © 2020-2023  润新知