野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16196|回复: 5

关于STM32F407 FSMC采用DMA机制填充TFT

[复制链接]
发表于 2014-11-19 11:09:53 | 显示全部楼层 |阅读模式
最近在做STM32F407驱动3.5寸TFT,采用FSMC总线驱动TFT,逐点填色正常但是刷屏速度较慢(显示TF卡中的图片)。
于是准备采用在103系列上调试成功的DMA传输机制进行填色,1是提速,2是将CPU解放出来执行其他任务。
由于407与103在固件和内部架构上有一定的差异,移植后对DMA配置进行了相应的调整,代码如下:

/*FSMC DMA设置项*/
#define FSMC_DMA                   DMA2
#define FSMC_DMA_CLK               RCC_AHB1Periph_DMA2

#define FSMC_DMA_STREAM            DMA2_Stream7
#define FSMC_DMA_CHANNEL           DMA_Channel_1
#define FSMC_DMA_FLAG_FEIF         DMA_FLAG_FEIF7
#define FSMC_DMA_FLAG_DMEIF        DMA_FLAG_DMEIF7
#define FSMC_DMA_FLAG_TEIF         DMA_FLAG_TEIF7
#define FSMC_DMA_FLAG_HTIF         DMA_FLAG_HTIF7
#define FSMC_DMA_FLAG_TCIF         DMA_FLAG_TCIF7
#define FSMC_DMA_IRQn              DMA2_Stream7_IRQn
#define FSMC_DMA_IRQHANDLER        DMA2_Stream7_IRQHandler

///************************************************************************************
//** 说明:FSMC采用DMA模式刷屏
//** 输入: 无
//** 输出: 无
//** 全局变量: FSMC_DMA_TCB
//** 调用模块: 无
//************************************************************************************/
static void LCD_FSMC_DMA(void)
{       
    DMA_InitTypeDef DMA_InitStructure;
       
    /* Enable the DMA2 Clock */
    RCC_AHB1PeriphClockCmd(FSMC_DMA_CLK, ENABLE);

    /* DMA2 Stream7 disable */
    DMA_Cmd(FSMC_DMA_STREAM, DISABLE);
    DMA_ClearFlag(FSMC_DMA_STREAM, FSMC_DMA_FLAG_FEIF | FSMC_DMA_FLAG_DMEIF | FSMC_DMA_FLAG_TEIF |
                  FSMC_DMA_FLAG_HTIF | FSMC_DMA_FLAG_TCIF);

    DMA_DeInit(FSMC_DMA_STREAM);

    DMA_InitStructure.DMA_Channel = FSMC_DMA_CHANNEL;                           //数据流
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)Bank1_LCD_D;           //外设地址  FSMC总线写地址
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0;                        //DMA访问的数据地址 启用DMA时赋值
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                     //外设作为数据传输的目的地
    DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE;                        //传输数据量大小 启用DMA时赋值
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //外设地址不增加
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                     //内存地址自增1
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度为16bit
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         //DMA从内存中搬运数据宽度为byte
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                               //只传送一次
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                     //(DMA传送优先级为高)
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                      //指定使用FIFO模式还是直接模式
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;               //指定了FIFO阈值
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                 //内存突发传输每次转移一个数据
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;         //外设突发传输每次转移一个数据

    DMA_Init(FSMC_DMA_STREAM, &DMA_InitStructure);
}

/************************************************************************************
** 说明: LCD刷屏DMA配置  将像素数组中的RGB颜色填充到FSMC总线上
** 输入: uint16_t *buff  像素数组指针
         uint16_t num    填充点数
** 输出: 无
** 全局变量: 无
** 调用模块: 无;
************************************************************************************/
void LCD_FSMC_DMA_BMP(uint16_t *buff,uint16_t num)
{       
    DMA_InitTypeDef DMA_InitStructure;

    DMA_ClearFlag(FSMC_DMA_STREAM, FSMC_DMA_FLAG_FEIF | FSMC_DMA_FLAG_DMEIF | FSMC_DMA_FLAG_TEIF |
                  FSMC_DMA_FLAG_HTIF | FSMC_DMA_FLAG_TCIF);//清标志           

    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) buff;/配置缓冲区地址和大小
    DMA_InitStructure.DMA_BufferSize = (uint32_t) num;            
    DMA_Init(FSMC_DMA_STREAM, &DMA_InitStructure);

    DMA_Cmd(FSMC_DMA_STREAM, ENABLE);
}


问题:实际测试发现,TFT上未有预期显示,DMA启动后未能进入任何对应中断(TC或TE),感觉DMA没有成功启动或者设置上有错误。希望调试成功的大侠能给予指正?
回复

使用道具 举报

 楼主| 发表于 2014-11-19 13:31:05 | 显示全部楼层
通过仿真发现是DMA未能启动,程序一直处于以下循环中
    while(DMA_GetCmdStatus(FSMC_DMA_STREAM)==0)//查询DMA是否启动
    {
        DMA_Cmd(FSMC_DMA_STREAM, ENABLE);
    }
未能启动的原因仍不明,继续查找  
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-19 14:14:58 | 显示全部楼层
错误原因:FSMC作为外部存储器控制器,不是外设,DMA机制应采用M2M,根据数据手册上的描述,外设作为数据源,存储器作为目标。M2M模式仅能采用DMA2,且不能采用直接模式,看来还是没有好好研读手册。
回复 支持 反对

使用道具 举报

发表于 2014-12-8 20:23:01 | 显示全部楼层
嗯,这样应该很快!
回复 支持 反对

使用道具 举报

发表于 2015-12-9 13:21:37 | 显示全部楼层
楼主,能将实现的代码贴出来吗,小弟搞了3天DMA  FSMC还没成功,  谢谢了!
回复 支持 反对

使用道具 举报

发表于 2022-9-2 10:21:34 | 显示全部楼层
您好,楼主,有资料吗
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-2 09:27 , Processed in 0.031887 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表