STM32使用1.69寸液晶显示模块使用缓冲区实现快速刷新全屏显示字符串功能

一个1.69寸SPI接口的液晶显示模块,有320*240=76800个点,每个点有2个字节表示RGB的颜色,所以需要153.6K个字节的数据来刷新全屏,如果SPI口输出数据不是高速并且不紧密排列的话,刷新就会比较慢,有从下到下的肉眼可见的刷新过程,现就是希望使用数据缓冲区(我理解这就是显存的概念吧)来快速刷新显示区域。

原始的单个字符的显示程序:

c 复制代码
/******************************************************************************
      函数说明:显示单个字符
      入口数据: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);		//每一个点发送2个字节数据
				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;
				}
			}
		}
	}   	 	  
}

由if(temp&(0x01<<t))LCD_WR_DATA(fc); //每一个点发送2个字节数据

else LCD_WR_DATA(bc);

这几句说明每个点,由SPI发送2个字节的数据出去,而且是一边计算数据,一边发送数据,速度较慢,可以肉眼可见的逐字显示的。

改用缓冲区显示单个字符:

c 复制代码
void LCD_ShowChar_new(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);  	//设置光标位置
	//uint8_t data[TypefaceNum * 2 * 8];	//=========
	static uint8_t data[1024];				//=========重要,用静态变量,或者用全局变量,一个字符作为一个缓冲区
	uint16_t xx = 0;
	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))
				{
					data[xx++] = fc>>8;
					data[xx++] = fc;
//					data[i*2*8 + t] == fc<<8;
//					data[i*2*8 + t + 1] == fc;
//					LCD_WR_DATA(fc);
				}
				else
				{
					data[xx++] = bc>>8;
					data[xx++] = bc;
//					data[i*2*8 + t] == bc<<8;
//					data[i*2*8 + t + 1] == bc;
//					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;
				}
			}
		}
	}
	while(HAL_SPI_GetState(&hspi1)==HAL_SPI_STATE_BUSY_TX);    	//等待SPI发送完成
	LCD_Address_Set(x,y,x+sizex-1,y+sizey-1);  //设置光标位置
	//while(HAL_SPI_GetState(&hspi1)==HAL_SPI_STATE_BUSY_TX);    	//等待SPI发送完成
	HAL_SPI_Transmit_DMA(&hspi1, &data, TypefaceNum * 2 * 8);		//这句有严重问题,会死机,OK
//	while(HAL_SPI_GetState(&hspi1)==HAL_SPI_STATE_BUSY_TX);    	//等待SPI发送完成

}

使用缓冲区的方法还是和全屏刷新一样,先把数据都放在数组,然后一次性SPI口发送出去。

缓冲区的大小是按照32字体大小的字符来计算,32字体是 16*32=512个点,1024个字节,所以使用data是1024个字节的缓冲区,这个缓冲区必须是静态或者全局的(这个问题困扰了我好久,一开始就是显示不正常,或者死机),我的理解是SPI要取数据发送,但缓冲区没有了,被系统回收了。

使用缓冲区后,字符显示都是直接显示,不再是一个一个字符逐个显示的感觉了

相关推荐
hairenjing11236 小时前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word
模拟IC攻城狮8 小时前
华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目——共8套(每套四十题)
嵌入式硬件·华为·硬件架构·芯片
IT B业生8 小时前
51单片机教程(六)- LED流水灯
单片机·嵌入式硬件·51单片机
一枝小雨8 小时前
51单片机学习心得2(基于STC89C52):串口通信(UART)
单片机·嵌入式硬件·51单片机
IT B业生9 小时前
51单片机教程(一)- 开发环境搭建
单片机·嵌入式硬件·51单片机
u01015265810 小时前
STM32F103C8T6学习笔记2--LED流水灯与蜂鸣器
笔记·stm32·学习
海绵波波10711 小时前
Webserver(4.8)UDP、广播、组播
单片机·网络协议·udp
好想有猫猫11 小时前
【51单片机】串口通信原理 + 使用
c语言·单片机·嵌入式硬件·51单片机·1024程序员节
云卓科技12 小时前
无人车之路径规划篇
人工智能·嵌入式硬件·算法·自动驾驶
stm 学习ing13 小时前
C语言 循环高级
c语言·开发语言·单片机·嵌入式硬件·算法·嵌入式实时数据库