STM32CubeIDE SPI LCD曲线显示

随言:

spi_lcd屏幕其实不适合用于曲线显示。

数据传输太慢了而且传输数据过程还需传一些设置命令。

但是需求来了,软硬件压榨一下也能做出来。

 

硬件:

STM32F407 + 1.54寸ST7789屏幕

STM32CubeIDE SPI LCD曲线显示_第1张图片

 

STM32CubeIDE:

SPI配置速度最快。使用硬件SPI发送。

STM32CubeIDE SPI LCD曲线显示_第2张图片

 

ST7789手册:

翻一下ST7789这个屏幕显示驱动芯片的技术手册,看一下寄存器,有哪些能提升速度的。

看到0xC6这个寄存器可以设置屏幕刷新速度。那就设置成0x01,即111Hz.(不知道为什么设置119Hz黑屏)

STM32CubeIDE SPI LCD曲线显示_第3张图片

 

编程:

现在就是软件优化了。

首先能确定一点的是,如果是全屏显示曲线,一般来说用画线函数LCD_DrawLine()画出曲线,

然后使用清屏函数LCD_Clear(),清除曲线,一直这样循环。

但是实际操作,由于数据传输太慢,会导致 屏幕的曲线一闪清屏一闪,基本不能看。

所以我们清除不能使用全屏清除这用需要发送大量数据的函数;转而使用反向画线即可清除曲线。

比如:背景是是黑色的,曲线是红色的,延时一下。然后清除曲线,此时重新把刚才画的曲线再在

屏幕上画一次,但是这是的曲线显示颜色换成和背景一样的黑色,画完后就和背景融为一体,即达到清屏目的。

这样由于发送数据少,清屏速度快,这样做完,至少完整显示曲线是人能看的。

 

代码:

// X轴上两相邻的两个坐标之间的x差值,X轴步进
#define		X_AXIS_STEP			5



int main(void)
{
  /* USER CODE BEGIN 1 */
	  uint16_t x1 = 0, x2 = 0;
	  uint16_t y1 = 0, y2 = 0;
	  uint32_t i = 0, index = 0;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  printf("Sudaroot\r\n");
  Lcd_Init();
  LCD_Clear(BLACK);
  HAL_Delay(1000);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  // 显示曲线
	  for(i = 0, x1 = 0; x1 < (240 - X_AXIS_STEP); i ++, x1 += X_AXIS_STEP)
	  {
		  x1 = i * X_AXIS_STEP;
		  x2 = x1 + X_AXIS_STEP;
		  y1 = data[index + i];
		  y2 = data[index + i + 1];
		  LCD_DrawLine(x1, y1, x2, y2, RED);
	  }

	  // 延时
	  HAL_Delay(10);

	  // 清空曲线
	  for(i = 0, x1 = 0; x1 < (240 - X_AXIS_STEP); i ++, x1 += X_AXIS_STEP)
	  {
		  x1 = i * X_AXIS_STEP;
		  x2 = x1 + X_AXIS_STEP;
		  y1 = data[index + i];
		  y2 = data[index + i + 1];
		  LCD_DrawLine(x1, y1, x2, y2, BLACK);
	  }

	  if((++index) >= (DATA_SIEZ - (240 / X_AXIS_STEP)))
		  index = 0;

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

 

效果:

SPI_LCD曲线

 

 

 

进阶:

我的屏幕分辩率是240 x 240.

由于我显示的曲线至少需要240点以上才能看出曲线的完整趋势。

根据上面的代码设置X轴的步进为1 的话,还是会微微闪屏。

故还需要优化代码。

 

优化方向:

1、直接设置寄存器发送数据,不使用HAL的SPI发送接口。

2、减少发送过程的频繁调用函数开辟栈次数。

3、片选和数据等GPIO尽量也设置一次到位,不要频繁拉高拉低。

4、设置命令尽量少,数据尽量连续发送。

5、不要在刷新曲线的时候计算曲线等数据,应当在芯片空间的时候计算好下一次显示的曲线等数据。

5、由于X轴的步进为1的话,实际上就是画竖直线。那我也不用画线函数了,效率太低。

      改成用  指定区域填充颜色LCD_Fill()这个接口。最后把这个接口流程优化就可以了。

 

效果和上面的一样,只是刷X轴步进为1的时候一点都不会闪屏,曲线非常流畅。

最后的代码我还做了全局缩放、局部缩放和范围缩放。

演示局部缩放:https://www.bilibili.com/video/bv1kV411U7oJ

SPI

 

源码链接:

https://download.csdn.net/download/sudaroot/12745418

 

 

 

全篇完。

 

本人是一个嵌入式未入门小白,博客仅仅代表我个人主观见解方便记录成长笔记。 若有与大神大大见解有冲突,我坚信大神大大见解是对的,我的是错的。 若无法下载源码,可私聊私发。 感谢~!

你可能感兴趣的:(STM32)