你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32U3评测】TouchGFX之六——体验基于SPI_GPDMA的丝滑UI界面

[复制链接]
lugl 发布时间:2025-5-27 18:01

【前言】

前面的TouchGFX的LCD数据发送是使用阻塞式的发送,虽然画面比较流畅了,但是今天我成功的切换到了gpdma进行数据传送,经调试好后,画面切换以及拖动,相比以前有了非常大的提升,可谓经典丝滑,现将我的优化记录如下。

在touchGFX中主要的接口是在TouchGFXHAL.cpp中的flushFrameBuffer函数。他负责将touchGFX生成的图像,通过spi发送给LCD屏。

刷新后生成的数据块为对象rect,rect对象在定义中是如下描述的:

    /**
     * Initializes a new instance of the Rect class.
     *
     * @param  rectX      The x coordinate.
     * @param  rectY      The y coordinate.
     * @param  rectWidth  The width.
     * @param  rectHeight The height.
     */

里面包含了起始坐标,图像的长与宽。我们拿到这块数据的内存地址,然后通过spi发送给LCD屏。

【优化前的代码】

        TouchGFXGeneratedHAL::flushFrameBuffer(rect);
    volatile uint16_t* buffer = getClientFrameBuffer()+(rect.y*LCD_WIDTH)+rect.x;
    lcd_set_address(rect.x, rect.y, rect.x+rect.width-1, rect.y+rect.height-1);
    lcd_write_ram();
    hspi1.Init.DataSize = SPI_DATASIZE_16BIT; //转换为16位工作模式
    HAL_SPI_Init(&hspi1);
    LCD_CS(0);
    LCD_WR(1);
     for(uint32_t i=0; i<rect.height; i++)
     {
         HAL_SPI_Transmit(&hspi1,(uint8_t *)buffer,rect.width,100);
             buffer += LCD_WIDTH;
     }
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;  //切换回8位
    HAL_SPI_Init(&hspi1);

在这里我是使用HAL_SPI_Transmit来发送的。

【优化后代码】

在切换为spi_dma之前,需要在stm32cubeMX中配置GPDMA,配置如下图所示:

image.png

配置好后,还需要在spi中打开中断。

image.png

然后修改发送代码如下:

  TouchGFXGeneratedHAL::flushFrameBuffer(rect);
    volatile uint16_t* buffer = getClientFrameBuffer()+(rect.y*LCD_WIDTH)+rect.x;
    uint32_t lenght ;
    lcd_set_address(rect.x, rect.y, rect.x+rect.width-1, rect.y+rect.height-1);
    lcd_write_ram();
    hspi1.Init.DataSize = SPI_DATASIZE_16BIT;  //修改为16位带宽
    HAL_SPI_Init(&hspi1);
    LCD_CS(0);
    LCD_WR(1);
    for(uint32_t i=0; i<rect.height; i++)
    {
            HAL_SPI_Transmit_DMA(&hspi1, (uint8_t *)buffer, rect.width);
            while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY)
                    {
                            //osDelay(1); // 使用RTOS延迟代替空循环
                    }
            buffer += LCD_WIDTH;
    }
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;  //切换回8位
    HAL_SPI_Init(&hspi1);

最后还需要添加两个中断回调函数:

image.png

【测试效果】

下载后,改善的效果是非常明显的,为了可视化的观察,我特意在发送前与发送后,通获取系统的tick数,执行完后,再获取,相减后通过串口打印出来。

image.png

阻塞式使用的tick数:

image.png

使用dma+16bit传递的tick:

image.png

可以看到通过优化后,提升的效果是非常之明显的。

image.png
收藏 评论0 发布时间:2025-5-27 18:01

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版