GUI开发--LCD屏幕的使用(非第三方库)--笔记_gui液晶屏-程序员宅基地

技术标签: 图片显示  字体显示  gui  st7789  嵌入式c  

导:界面交互需要GUI,GUI需要文字和图片,所有此处总结在M4芯片上实现GUI的基本操作!该芯片具有160K大小的内存,有512K的flash;故而没有使用第三方库! 

LCD屏幕的使用--笔记

           1.汉字显示-两种方式

                      ·字符数组格式

                      ·汉字库格式

          2.双色2位图显示

          3.真彩色16位图显示

条件:

                屏幕:ST7789   尺寸:320*240

                配置软件:

      基础的驱动可以实现:LCD_Address_Set 和 LCD_WR_DATA的接口可以用软件或硬件spi实现

可实现的基本效果

1.汉字显示(数组形式)

文字显示格式设置

 存放在一个数据结果中:如下

const typFNT_GB16 tfont16[]={
"升",0x80,0x04,0xE0,0x05,0x3C,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0xFF,0x7F,
0x20,0x04,0x20,0x04,0x20,0x04,0x10,0x04,0x10,0x04,0x08,0x04,0x04,0x04,0x02,0x04,/*"升",0*/
/* (16 X 16 , 宋体 )*/

"级",0x08,0x00,0xC8,0x3F,0x04,0x21,0x04,0x11,0x12,0x11,0x1F,0x09,0x08,0x39,0x04,0x21,
0x82,0x22,0x9F,0x22,0x82,0x14,0x80,0x14,0x58,0x08,0x47,0x14,0x22,0x22,0x80,0x41,/*"级",1*/
/* (16 X 16 , 宋体 )*/

"中",0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFC,0x1F,0x84,0x10,0x84,0x10,0x84,0x10,
0x84,0x10,0x84,0x10,0xFC,0x1F,0x84,0x10,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,/*"中",2*/
/* (16 X 16 , 宋体 )*/
}

其中,对汉字显示定义结构体如下:

结构体定义:

typedef struct 
{
    unsigned char Index[2];    //汉字索引号
    unsigned char Msk[32];  //对应汉字的
}typFNT_GB16; 

汉字显示驱动

/******************************************************************************
      函数说明:显示单个16x16汉字
      入口数据:x,y显示坐标
                *s 要显示的汉字
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:  0非叠加模式  1叠加模式
      返回值:  无
******************************************************************************/
void LCD_ShowChinese16x16(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
	uint8_t i,j,m=0;
	uint16_t k;
	uint16_t HZnum;//汉字数目
	uint16_t TypefaceNum;//一个字符所占字节大小
	uint16_t x0=x;
  TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
	HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);	//统计汉字数目
	for(k=0;k<HZnum;k++) 
	{
		if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1)))
		{ 	
			LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
			for(i=0;i<TypefaceNum;i++)
			{
				for(j=0;j<8;j++)
				{	
					if(!mode)//非叠加方式
					{
						if(tfont16[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
						else LCD_WR_DATA(bc);
						m++;
						if(m%sizey==0)
						{
							m=0;
							break;
						}
					}
					else//叠加方式
					{
						if(tfont16[k].Msk[i]&(0x01<<j))	LCD_DrawPoint(x,y,fc);//画一个点
						x++;
						if((x-x0)==sizey)
						{
							x=x0;
							y++;
							break;
						}
					}
				}
			}
		}
		continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
	}
} 

2. 数值和符号assic码定义

const unsigned char ascii_1608[][16]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x18,0x18,0x00,0x00},/*"!",1*/
{0x00,0x48,0x6C,0x24,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/
{0x00,0x00,0x00,0x24,0x24,0x24,0x7F,0x12,0x12,0x12,0x7F,0x12,0x12,0x12,0x00,0x00},/*"#",3*/
{0x00,0x00,0x08,0x1C,0x2A,0x2A,0x0A,0x0C,0x18,0x28,0x28,0x2A,0x2A,0x1C,0x08,0x08},/*"$",4*/
{0x00,0x00,0x00,0x22,0x25,0x15,0x15,0x15,0x2A,0x58,0x54,0x54,0x54,0x22,0x00,0x00},/*"%",5*/
{0x00,0x00,0x00,0x0C,0x12,0x12,0x12,0x0A,0x76,0x25,0x29,0x11,0x91,0x6E,0x00,0x00},/*"&",6*/
{0x00,0x06,0x06,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00},/*"(",8*/
{0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00},/*")",9*/
{0x00,0x00,0x00,0x00,0x08,0x08,0x6B,0x1C,0x1C,0x6B,0x08,0x08,0x00,0x00,0x00,0x00},/*"*",10*/
{0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0x08,0x00,0x00,0x00},/*"+",11*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x04,0x03},/*",",12*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x00},/*".",14*/
{0x00,0x00,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x00},/*"/",15*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00},/*"0",16*/
{0x00,0x00,0x00,0x08,0x0E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"1",17*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x20,0x20,0x10,0x08,0x04,0x42,0x7E,0x00,0x00},/*"2",18*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x20,0x18,0x20,0x40,0x40,0x42,0x22,0x1C,0x00,0x00},/*"3",19*/
{0x00,0x00,0x00,0x20,0x30,0x28,0x24,0x24,0x22,0x22,0x7E,0x20,0x20,0x78,0x00,0x00},/*"4",20*/
{0x00,0x00,0x00,0x7E,0x02,0x02,0x02,0x1A,0x26,0x40,0x40,0x42,0x22,0x1C,0x00,0x00},/*"5",21*/
{0x00,0x00,0x00,0x38,0x24,0x02,0x02,0x1A,0x26,0x42,0x42,0x42,0x24,0x18,0x00,0x00},/*"6",22*/
{0x00,0x00,0x00,0x7E,0x22,0x22,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00},/*"7",23*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00},/*"8",24*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x64,0x58,0x40,0x40,0x24,0x1C,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00}/*":",26*/
};

字符和数组的驱动 --- 检索方式:根据字符和空格的间隔进行检索

/******************************************************************************
      函数说明:显示单个字符
      入口数据:x,y显示坐标
                num 要显示的字符
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:  0非叠加模式  1叠加模式
      返回值:  无
******************************************************************************/
void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
	uint8_t temp,sizex,t,m=0;
	uint16_t i,TypefaceNum;//一个字符所占字节大小
	uint16_t x0=x;
	sizex=sizey/2;
	TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;
	num=num-' ';    //得到偏移后的值
	LCD_Address_Set(x,y,x+sizex-1,y+sizey-1);  //设置光标位置 
	for(i=0;i<TypefaceNum;i++)
	{ 
		if(sizey==12)temp=ascii_1206[num][i];		       //调用6x12字体
		else if(sizey==16)temp=ascii_1608[num][i];		 //调用8x16字体
		else if(sizey==24)temp=ascii_2412[num][i];		 //调用12x24字体
		else if(sizey==32)temp=ascii_3216[num][i];		 //调用16x32字体
		else return;
		for(t=0;t<8;t++)
		{
			if(!mode)//非叠加模式
			{
				if(temp&(0x01<<t))LCD_WR_DATA(fc);
				else LCD_WR_DATA(bc);
				m++;
				if(m%sizex==0)
				{
					m=0;
					break;
				}
			}
			else//叠加模式
			{
				if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
				x++;
				if((x-x0)==sizex)
				{
					x=x0;
					y++;
					break;
				}
			}
		}
	}   	 	  
}


/******************************************************************************
      函数说明:显示字符串
      入口数据:x,y显示坐标
                *p 要显示的字符串
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:  0非叠加模式  1叠加模式
      返回值:  无
******************************************************************************/
void LCD_ShowString(uint16_t x,uint16_t y,char *p,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{         
	while(*p!='\0')
	{       
		LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
		x+=sizey/2;
		p++;
	}  
}

填充函数:

//局部清屏
void LcdClrRect(INT16 usLeft, INT16 usTop, INT16 usRight, INT16 usBottom, INT32U ucColor)
{
	INT16 i,j;

    LCD_WindowsSet(usLeft,usRight,usTop,usBottom);
	for(i = usTop; i <= usBottom; i++)
	{
		for(j = usLeft; j <= usRight; j++)
		{
			LCD_Write_Data(ucColor);
		}
	}
}

app的代码演示(使用上述的汉字显示和字符显示)

#if TEST_DEMO_HZ
			{
    			u8Process = 50;//升级进度[0:100]
                LcdClrRect(0, 0, 320, 240, BLACK);//黑背景
                LCD_ShowChinese16x16(60,100,"升",WHITE,BLACK,16,1);
                LCD_ShowChinese16x16(80,100,"级",WHITE,BLACK,16,1);
                LCD_ShowChinese16x16(100,100,"中",WHITE,BLACK,16,1);
                LCD_ShowString(180, 100,"50%",WHITE,BACKCOLOR,16,1);

                LcdClrRect(60, 120, 260,140,WHITE);
                LcdClrRect(60, 120, 60+2*u8Process,140,RED);
			}
#endif

效果显示:

优点:不依赖外部flash,根据自己喜欢的汉字裁剪并显示、灵活可控

确定:汉字太少,一旦确定不能改变;汉字一旦多消耗太多的ram或rom;造成负担

3.汉字显示--(汉字 字库显示)

实现的方式:先将汉字字库文件存放在某一个存储器的位置a

然后当要显示某一个汉字的时候,会根据汉字,先将汉字的16进制码(比如汉字“你”对应的16进制为C4 E3),根据根据偏移量计算区码和位码(类似算出在x、y坐标或者类似住的地址-某个区的某个栋);然后计算出该字的具体偏移位置ulOffset;

16进制:
        qm = *(s) - 0xaf;        //区码 -161->A1
        wm = *(s + 1) - 0xa0;//位码 -A1
        ulOffset = (INT32U)((qm-1) * 94 + (wm-1)) * 72;//计算区位码
然后从位置a(汉字字库存储的位置)的偏移ulOffset处读取出该汉字的点阵16进制码
        ExFlash_SeekHzk("HZK.BIN",hzflashbuf,ulOffset,sizeof(hzbuf));
接下来就是显示的情况和数组的显示方式一样:
        memcpy(hzbuf,hzflashbuf,sizeof(hzbuf));

for(y = 0; y < 16; y++)
        {
            for(x = 0; x < 16; x++) 
            {
                k = x % 8;
                if (hzbuf[y * 2 + x / 8]  & (0x80 >> k))
                {
                    xx = x0 + x;
                    LCD_DrawPoint( xx, y + y0, ForeColor);
                }
            }
        }

最终调用画点函数实现具体的点阵点亮操作; 
显示的效果和数组的一模一样;

上述的驱动是16进制,其他进制的,比如24进制的不一样了(主要是计算区码和位码,同一个子需要的点阵数量不一样就要在点阵画点操作有所区别了)

qm = *(s) - 0xaf;    //161->A1
		wm = *(s + 1) - 0xa0;//A1
		ulOffset = (INT32U)((qm-1) * 94 + (wm-1)) * 72;//计算区位码
ExFlash_SeekHzk("HZK.BIN",hzflashbuf,ulOffset,sizeof(hzbuf));
			memcpy(hzbuf,hzflashbuf,sizeof(hzbuf));
 for( i = 0; i < 24; ++i)
        for( j = 0; j < 3; ++j)
        for( k = 0; k < 8; k++)
        if(((hzbuf[i* 3 + j] >> (7 - k)) & 0x1) != NULL)
        {
            current_start_x = x0 + i ;//24*24的是纵向排列的i对应的是x
            current_start_y = y0 + j * 8 + k;
            LCD_DrawPoint( current_start_x,current_start_y , ForeColor);

        }

 附加:汉字字库如何生成(需要软件0点阵字库生成器-自行网上下载,免费的有很多!)

注意:汉字字库文件,存储大小,常用的16号字体,需要260多k,24号字体需要400k左右(提供参考),对空间要求严格者需要慎重!!!

4.双色图(除开背景色-也可以叫单色图)-图像实现

显示双色图--的这个操作--对于图片很多的芯片,相对余全真彩色--节省空间会很有很大助力!
打开软件:安装图中的要求进行设置(图中的要求会对应到后面的驱动和画点函数顺序的操作)

上述的配置对应到驱动如下(驱动不一样--配置也要修改)

/******************************************************************************
      函数说明:在指定位置画点
      入口数据:x,y 画点坐标
                color 点的颜色
      返回值:  无
******************************************************************************/
void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color)
{
	LCD_Address_Set(x,y,x,y);//设置光标位置 
	LCD_WR_DATA(color);
} 
/******************************************************************************
      函数说明:显示双色图,比如黑白-图片,或红-绿图-双色图
      入口数据:x,y起点坐标
                length 图片长度
                width  图片宽度
                pic[]  图片数组    
      返回值:  无

    注意:length长度和length宽度,必须是8的整数比如40*40 或 224*40
******************************************************************************/

void LCD_ShowPic4(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[],uint16_t fc,uint16_t bc)
{
	uint16_t i,j,t=0;
	uint16_t h=0;
    if(length>320)
    {
     
        printf("参数错误%d in[%s]",length,__func__);
        length = 320;
    }
    if(width>240)
    {
        printf("参数错误%d in[%s]",width,__func__);
        width = 240;
    }
    
	LCD_Address_Set(x,y,x+length-1,y+width-1);
	for(i=0;i<length;i++)
	{
		for(j=0;j<width;j++)
		{
			h= (i*width + j)/8;
			t= (i*width + j)%8;
				if(pic[h]&(0x01<<t)) 
					LCD_DrawPoint(x+i,y+j,fc);//画一个点
				else 
					LCD_DrawPoint(x+i,y+j,bc);//画一个点
		}
	}			
}

比如:(对一个图片只有两重颜色前景色和后景色--比如下图只有黑和白)

 实现结果

const unsigned char gImage_OutOne[] = { 
#if 1
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x01,0xE0,
0xFF,0xFF,0xFF,0x07,0xF0,0xFF,0xFF,0xFF,0x0F,0xF0,0x00,0x00,0x00,0x0F,0x78,0x00,
0x00,0x00,0x0E,0x78,0x00,0x00,0x00,0x1E,0x78,0x00,0x00,0x00,0x1E,0x78,0x00,0x00,
0x00,0x1E,0x78,0x00,0x00,0x00,0x1E,0x78,0x00,0x00,0x00,0x1E,0x78,0x00,0x00,0x00,
0x1E,0x78,0x00,0x00,0x00,0x1E,0x78,0x00,0x00,0x00,0x1E,0x78,0x00,0x00,0x00,0x1E,
0x78,0x00,0x00,0x00,0x1E,0x78,0x00,0xFF,0x00,0x1E,0x78,0xC0,0xFF,0x07,0x1E,0x30,
0xE0,0xFF,0x1F,0x1E,0x20,0x78,0xFC,0x0F,0x1E,0x60,0x3C,0x7E,0x00,0x1E,0xF0,0x9F,
0x0F,0x00,0x1E,0xF0,0xCF,0x03,0x00,0x1E,0xF0,0xE7,0x01,0x00,0x1E,0x70,0xF3,0x00,
0x00,0x1E,0x70,0x70,0x00,0x00,0x1E,0x30,0x78,0x00,0x00,0x1E,0x30,0xF8,0x01,0x00,
0x1E,0x38,0xE0,0x03,0x00,0x1E,0x38,0xE0,0x07,0x00,0x1E,0x38,0xFC,0x01,0x00,0x0E,
0x38,0x7F,0xFF,0xFF,0x0F,0xD8,0x0F,0xFF,0xFF,0x07,0xF8,0x03,0xFF,0xFF,0x03,0xFC,
0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"1.bmp",0*/
#endif 
};

实现的项目demo--播放器界面
实际效果  

如下这些图标都是采用这个方式来实现的

具体代码实现(部分)

const unsigned char g_IMAGE_GO_HEAD[] ={
0x00,0x00,0xFC,0x1F,0xF8,0x0F,0xF8,0x0F,0xF0,0x07,0xE0,0x03,0xC0,0x01,0x00,0x00,
0xFC,0x1F,0xFC,0x1F,0xF8,0x0F,0xF0,0x07,0xE0,0x03,0xC0,0x01,0x00,0x00,0x00,0x00,
};
const unsigned char g_IMAGE_PLAY[] ={
#if 1
0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,
0xFC,0xFF,0x3F,0x00,0x00,0x3F,0x00,0xFC,0x00,0x80,0x0F,0x00,0xF0,0x01,0xC0,0x07,
0x00,0xE0,0x03,0xE0,0x01,0x00,0x80,0x07,0xF0,0x00,0x00,0x00,0x0F,0x70,0x00,0x00,
0x00,0x0E,0x78,0x00,0x00,0x00,0x1E,0x3C,0x00,0x00,0x00,0x3C,0x1C,0x00,0x00,0x00,
0x38,0x1C,0x00,0x00,0x00,0x38,0x1E,0x00,0x00,0x00,0x78,0x0E,0x00,0x00,0x00,0x70,
0x0E,0xFC,0xFF,0x0F,0x70,0x0E,0xFC,0xFF,0x0F,0x70,0x0E,0xF8,0xFF,0x07,0x70,0x0E,
0xF0,0xFF,0x03,0x70,0x0E,0xF0,0xFF,0x03,0x70,0x0E,0xE0,0xFF,0x01,0x70,0x0E,0xC0,
0xFF,0x00,0x70,0x0E,0x80,0xFF,0x00,0x70,0x0E,0x80,0x7F,0x00,0x70,0x1E,0x00,0x3F,
0x00,0x78,0x1C,0x00,0x1E,0x00,0x38,0x1C,0x00,0x1E,0x00,0x38,0x3C,0x00,0x00,0x00,
0x3C,0x78,0x00,0x00,0x00,0x1E,0x70,0x00,0x00,0x00,0x0E,0xF0,0x00,0x00,0x00,0x0F,
0xE0,0x01,0x00,0x80,0x07,0xC0,0x07,0x00,0xE0,0x03,0x80,0x0F,0x00,0xF0,0x01,0x00,
0x3F,0x00,0xFC,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,0xC0,
0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
#endif
};
const unsigned char g_IMAGE_STOP[] ={
#if 1
0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,
0xFC,0xFF,0x3F,0x00,0x00,0x3F,0x00,0xFC,0x00,0x80,0x0F,0x00,0xF0,0x01,0xC0,0x07,
0x00,0xE0,0x03,0xE0,0x01,0x00,0x80,0x07,0xF0,0x00,0x00,0x00,0x0F,0x70,0x00,0x00,
0x00,0x0E,0x78,0x00,0x00,0x00,0x1E,0x3C,0x00,0x00,0x00,0x3C,0x1C,0x00,0x00,0x00,
0x38,0x1C,0x00,0x00,0x00,0x38,0x1E,0xE0,0xFF,0x07,0x78,0x0E,0xE0,0xFF,0x07,0x70,
0x0E,0xE0,0xFF,0x07,0x70,0x0E,0xE0,0xFF,0x07,0x70,0x0E,0x00,0x00,0x00,0x70,0x0E,
0x00,0x00,0x00,0x70,0x0E,0x00,0x00,0x00,0x70,0x0E,0x00,0x00,0x00,0x70,0x0E,0x00,
0x00,0x00,0x70,0x0E,0xE0,0xFF,0x07,0x70,0x0E,0xE0,0xFF,0x07,0x70,0x1E,0xE0,0xFF,
0x07,0x78,0x1C,0xE0,0xFF,0x07,0x38,0x1C,0x00,0x00,0x00,0x38,0x3C,0x00,0x00,0x00,
0x3C,0x78,0x00,0x00,0x00,0x1E,0x70,0x00,0x00,0x00,0x0E,0xF0,0x00,0x00,0x00,0x0F,
0xE0,0x01,0x00,0x80,0x07,0xC0,0x07,0x00,0xE0,0x03,0x80,0x0F,0x00,0xF0,0x01,0x00,
0x3F,0x00,0xFC,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,0xC0,
0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
/* (40 X 40 ) */
#endif
};
const unsigned char g_IMAGE_Volumn[] ={ //音量
0xE0,0x0F,0xE0,0x0F,0xE0,0x0F,0xF0,0x0F,0xF8,0x1F,0xFC,0x3F,0xFC,0x3F,0xFC,0x7F,
0x00,0x00,0x30,0x0C,0x70,0x0E,0xF0,0x0F,0xC4,0x63,0x1C,0x78,0xFC,0x3F,0xF0,0x0F,
};
const unsigned char g_IMAGE_Progress[] ={ //进度
0x00,0x00,0x02,0x00,0x02,0x80,0x02,0x80,0x7E,0xFC,0x7E,0xFC,0xE2,0xFE,0xC2,0xFF,
0x82,0xFF,0xC2,0xFF,0xE2,0xFE,0xFE,0xFE,0x7E,0xFC,0x02,0xF0,0x02,0x80,0x02,0x80,
};
//初始化播放页面
void show_play_menu_init()
{
    LCD_Fill(0,22,320,220-1,BACKCOLOR);
    Lcd_Printf(13, 40,WHITE,"录音回放和导出");
    Lcd_Printf(77, 166,WHITE,"后退");
    
    Lcd_Printf(216, 166,WHITE,"前进");
    LCD_ShowPic4(83,133,16,16,g_IMAGE_GO_BACK,WHITE,BACKCOLOR);
    
    LCD_ShowPic4(222,133,16,16,g_IMAGE_GO_HEAD,WHITE,BACKCOLOR);
    LCD_ShowPic4(29,192,16,16,g_IMAGE_Progress,WHITE,BACKCOLOR);
    LCD_ShowPic4(287,194,16,16,g_IMAGE_Volumn,WHITE,BACKCOLOR);

    Lcd_Printf(36,68,WHITE,"正在播放:");
    Lcd_Printf(54,194,WHITE,"播放进度");
    Lcd_Printf(125, 195,WHITE,"00:00:20/00:12:36");
    LCD_Fill(0,220,320,240,BACKCOLOR);
    Lcd_Printf2(20,224,WHITE,"【确认】导出  ←左调 右调→",1,BACKCOLOR); 
}

4.16位真彩色图的实现 推荐两款软件

推荐两款软件。

第一个如下的这个软件Img2Lcd.exe(需要设置驱动的参数--包含头,高低位...等)

软件特色
  Image2Lcd 能把各种来源的图片转换成特定的数据格式以用来匹配单片机系统所需要的显示数据格式
  Image2Lcd支持的输入图像格式包括:BMP, WBMP, JPG, GIF, WMF, EMF, ICO, 等等。           Image2Lcd的输出数据类型包括定制的二进制类型、C语言数组类型和标准的BMP格式、WBMP格式
  Image2Lcd能可视调节输入图象的数据扫描方式、灰度(颜色数)、图像数据排列方式、亮度、对比度、等等
  对于包含了图像头数据保存的图像数据文件,Image2Lcd能重新打开作为输入图像
****支持所有的点阵LCD所需要的特殊显示数据格式。
  可视调节输出图像效果。
  256色模式下支持用户调色板(TIFF格式)。
  支持4096色图像输出。
  以二进制类型和C语言数组类型(文本)两种方式保存数据,方便单片机开发者的不同需要。
  保存的数据支持LSB First/MSB First(很多单片机系统WORD高低字节排列与PC相反)。
  可以保存图像为指定颜色数的BMP格式图像。
  即时图示当前设置的数据格式。
        

第二个软件是bmp2h.exe(规定好了驱动的方式)
                                            

位图变换(bmp2h)是一款可以把bmp格式的图片转化成64K色的数组数据信息

应用:

点一下功能键“添加将一个bmp图片添加进去,随后点一下功能键“变换就会转化成图片数组文档。表明:假如要应用转化成的图片数组数据信息,必须在转化成的c文档开始添加一条句子:#define WIN32

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xiaoxilang/article/details/127029173

智能推荐

hdu 1229 还是A+B(水)-程序员宅基地

文章浏览阅读122次。还是A+BTime Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 24568Accepted Submission(s): 11729Problem Description读入两个小于10000的正整数A和B,计算A+B。...

http客户端Feign——日志配置_feign 日志设置-程序员宅基地

文章浏览阅读419次。HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息。FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。BASIC:仅记录请求的方法,URL以及响应状态码和执行时间。NONE:不记录任何日志信息,这是默认值。配置Feign日志有两种方式;方式二:java代码实现。注解中声明则代表某服务。方式一:配置文件方式。_feign 日志设置

[转载]将容器管理的持久性 Bean 用于面向服务的体系结构-程序员宅基地

文章浏览阅读155次。将容器管理的持久性 Bean 用于面向服务的体系结构本文将介绍如何使用 IBM WebSphere Process Server 对容器管理的持久性 (CMP) Bean的连接和持久性逻辑加以控制,使其可以存储在非关系数据库..._javax.ejb.objectnotfoundexception: no such entity!

基础java练习题(递归)_java 递归例题-程序员宅基地

文章浏览阅读1.5k次。基础java练习题一、递归实现跳台阶从第一级跳到第n级,有多少种跳法一次可跳一级,也可跳两级。还能跳三级import java.math.BigDecimal;import java.util.Scanner;public class Main{ public static void main(String[]args){ Scanner reader=new Scanner(System.in); while(reader.hasNext()){ _java 递归例题

面向对象程序设计(荣誉)实验一 String_对存储在string数组内的所有以字符‘a’开始并以字符‘e’结尾的单词做加密处理。-程序员宅基地

文章浏览阅读1.5k次,点赞6次,收藏6次。目录1.串应用- 计算一个串的最长的真前后缀题目描述输入输出样例输入样例输出题解2.字符串替换(string)题目描述输入输出样例输入样例输出题解3.可重叠子串 (Ver. I)题目描述输入输出样例输入样例输出题解4.字符串操作(string)题目描述输入输出样例输入样例输出题解1.串应用- 计算一个串的最长的真前后缀题目描述给定一个串,如ABCDAB,则ABCDAB的真前缀有:{ A, AB,ABC, ABCD, ABCDA }ABCDAB的真后缀有:{ B, AB,DAB, CDAB, BCDAB_对存储在string数组内的所有以字符‘a’开始并以字符‘e’结尾的单词做加密处理。

算法设计与问题求解/西安交通大学本科课程MOOC/C_算法设计与问题求解西安交通大学-程序员宅基地

文章浏览阅读68次。西安交通大学/算法设计与问题求解/树与二叉树/MOOC_算法设计与问题求解西安交通大学

随便推点

[Vue warn]: Computed property “totalPrice“ was assigned to but it has no setter._computed property "totalprice" was assigned to but-程序员宅基地

文章浏览阅读1.6k次。问题:在Vue项目中出现如下错误提示:[Vue warn]: Computed property "totalPrice" was assigned to but it has no setter. (found in <Anonymous>)代码:<input v-model="totalPrice"/>原因:v-model命令,因Vue 的双向数据绑定原理 , 会自动操作 totalPrice, 对其进行set 操作而 totalPrice 作为计..._computed property "totalprice" was assigned to but it has no setter.

basic1003-我要通过!13行搞定:也许是全网最奇葩解法_basic 1003 case 1-程序员宅基地

文章浏览阅读60次。十分暴力而简洁的解决方式:读取P和T的位置并自动生成唯一正确答案,将题给测点与之对比,不一样就给我爬!_basic 1003 case 1

服务器浏览war文件,详解将Web项目War包部署到Tomcat服务器基本步骤-程序员宅基地

文章浏览阅读422次。原标题:详解将Web项目War包部署到Tomcat服务器基本步骤详解将Web项目War包部署到Tomcat服务器基本步骤1 War包War包一般是在进行Web开发时,通常是一个网站Project下的所有源码的集合,里面包含前台HTML/CSS/JS的代码,也包含Java的代码。当开发人员在自己的开发机器上调试所有代码并通过后,为了交给测试人员测试和未来进行产品发布,都需要将开发人员的源码打包成Wa..._/opt/bosssoft/war/medical-web.war/web-inf/web.xml of module medical-web.war.

python组成三位无重复数字_python组合无重复三位数的实例-程序员宅基地

文章浏览阅读3k次,点赞3次,收藏13次。# -*- coding: utf-8 -*-# 简述:这里有四个数字,分别是:1、2、3、4#提问:能组成多少个互不相同且无重复数字的三位数?各是多少?def f(n):list=[]count=0for i in range(1,n+1):for j in range(1, n+1):for k in range(1, n+1):if i!=j and j!=k and i!=k:list.a..._python求从0到9任意组合成三位数数字不能重复并输出

ElementUl中的el-table怎样吧0和1改变为男和女_elementui table 性别-程序员宅基地

文章浏览阅读1k次,点赞3次,收藏2次。<el-table-column prop="studentSex" label="性别" :formatter="sex"></el-table-column>然后就在vue的methods中写方法就OK了methods: { sex(row,index){ if(row.studentSex == 1){ return '男'; }else{ return '女'; }..._elementui table 性别

java文件操作之移动文件到指定的目录_java中怎么将pro.txt移动到design_mode_code根目录下-程序员宅基地

文章浏览阅读1.1k次。java文件操作之移动文件到指定的目录_java中怎么将pro.txt移动到design_mode_code根目录下

推荐文章

热门文章

相关标签