Wu学c20年 2024-09-30 01:06 采纳率: 33.3%
浏览 40
已结题

G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?

img

红色框内加了就卡死了,一直在等待DMA数据传输完成,绿色框内不加就无法正常驱动芯片,但是绿色框表示的是等待SPI接收数据完成。
不是很理解 我是主机模式工作驱动的LCD,应该是不需要等待接收的,但是不加这while((SPI1->SR & (1<< 0)) == 0);就无法驱动; 看了中景园的官方例程HAL库,改了之后也无法正常驱动。如下图:

img


红色框内也是同样的情况一直在等待,无法正常运行,不知道问题出在哪里。

img


这是直接用硬件SPI驱动LCD是能正常使用的,但是也不知道为啥要加while((SPI1->SR&SPI_SR_RXNE)==RESET);//等待接收完一个byte ;去掉了就无法显示了。
请教大 佬 指点为什么出现这情况,然后DMA传输该怎么改动。

  • 写回答

21条回答 默认 最新

  • GISer Liu 2024-09-30 03:50
    关注

    该回答引用自GPT-4o, 由博主 GISer Liu 编写:

    问题分析

    用户在使用G0系列单片机的HAL库驱动景园gc9307液晶驱动芯片时,遇到了硬件SPI DMA传输的问题。具体表现为:

    1. 红色框内的代码:添加了while((SPI1->SR & (1 << 0)) == 0);后,程序卡死,一直在等待DMA数据传输完成。
    2. 绿色框内的代码:不添加while((SPI1->SR & (1 << 0)) == 0);时,无法正常驱动芯片,但该代码的作用是等待SPI接收数据完成。
    3. 主机模式:用户明确表示自己是主机模式工作驱动的LCD,理论上不需要等待接收。
    4. 官方例程:参考了中景园的官方例程HAL库,但修改后仍无法正常驱动。

    解决方案

    1. 分析红色框内的代码

    红色框内的代码while((SPI1->SR & (1 << 0)) == 0);实际上是在等待SPI的接收寄存器(SR)的第0位(RXNE位)被置位,即等待接收完成。在DMA传输的情况下,DMA会自动处理数据的接收,因此不需要手动等待接收完成。

    修改建议

    • 删除红色框内的代码,因为DMA会自动处理接收,不需要手动等待。

    2. 分析绿色框内的代码

    绿色框内的代码while((SPI1->SR & (1 << 0)) == 0);的作用是等待SPI接收数据完成。在主机模式下,发送数据后确实需要等待接收完成,以确保数据传输的完整性。

    修改建议

    • 保留绿色框内的代码,但在DMA传输的情况下,可以考虑使用中断或回调函数来处理接收完成的事件,而不是使用轮询方式。

    3. DMA传输的配置

    在DMA传输的情况下,需要正确配置DMA通道,并确保DMA传输的触发源和SPI的传输事件匹配。

    DMA配置代码示例

    // 配置DMA通道
    __HAL_RCC_DMA1_CLK_ENABLE();
    
    hdma_spi1_tx.Instance = DMA1_Channel3;
    hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi1_tx.Init.Mode = DMA_NORMAL;
    hdma_spi1_tx.Init.Priority = DMA_PRIORITY_HIGH;
    HAL_DMA_Init(&hdma_spi1_tx);
    
    __HAL_LINKDMA(&hspi1, hdmatx, hdma_spi1_tx);
    
    // 启动DMA传输
    HAL_DMA_Start(&hdma_spi1_tx, (uint32_t)txBuffer, (uint32_t)&hspi1.Instance->DR, sizeof(txBuffer));
    
    // 启动SPI传输
    HAL_SPI_Transmit_DMA(&hspi1, txBuffer, sizeof(txBuffer));
    

    4. 使用中断或回调函数

    为了避免轮询等待,可以使用中断或回调函数来处理DMA传输完成的事件。

    回调函数示例

    void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) {
        if (hspi->Instance == SPI1) {
            // DMA传输完成后的处理
            // 例如:更新LCD显示
        }
    }
    

    总结

    1. 删除红色框内的代码:因为DMA会自动处理接收,不需要手动等待。
    2. 保留绿色框内的代码:但在DMA传输的情况下,建议使用中断或回调函数来处理接收完成的事件。
    3. 正确配置DMA通道:确保DMA传输的触发源和SPI的传输事件匹配。
    4. 使用中断或回调函数:避免轮询等待,提高程序的效率。

    通过以上修改,应该可以解决DMA传输导致的问题,并正常驱动景园gc9307液晶驱动芯片。

    如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(20条)
编辑
预览

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月6日
  • 已采纳回答 10月6日
  • 创建了问题 9月30日

悬赏问题

  • ¥15 基于pwm 实现buck变换
  • ¥15 关于#c##的问题:treenode反序列化后获取不到上一节点和下一节点,Fullpath和Handle报错
  • ¥15 一部手机能否同时用不同的app进入不同的直播间?
  • ¥15 没输出运行不了什么问题
  • ¥20 输入import torch显示Intel MKL FATAL ERROR,系统驱动1%,: Cannot load mkl_intel_thread.dll.
  • ¥15 点云密度大则包围盒小
  • ¥15 nginx使用nfs进行服务器的数据共享
  • ¥15 C#i编程中so-ir-192编码的字符集转码UTF8问题
  • ¥15 51嵌入式入门按键小项目
  • ¥30 海外项目,如何降低Google Map接口费用?