硬汉嵌入式论坛

 找回密码
 立即注册
查看: 7612|回复: 5
收起左侧

[有问必答] STM32F407利用FSMC接口采用DMA机制填充TFT

[复制链接]

1

主题

33

回帖

36

积分

新手上路

积分
36
发表于 2014-11-19 15:46:48 | 显示全部楼层 |阅读模式
    最近在做STM32F407驱动3.5寸TFT,采用FSMC总线驱动TFT,利用CPU逐点填色正常但是刷屏速度较慢(显示TF卡中的图片)。于是采用DMA传输机制进行填色,1是提速,2是将CPU解放出来执行其他任务。

问题:实际测试发现,TFT上未有预期显示,DMA启动后未能进入任何对应中断(TC或TE),查询标志位也无任何置位。通过DMA_GetCmdStatus(FSMC_DMA_STREAM)函数发现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_0
#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模式刷屏
    注意:使用存储器到存储器模式时,不允许循环模式和直接模式。只有DMA2 控制器能够执行存储器到存储器的传输。
    采用M2M模式时,外设作为数据源(像素数组),存储器作为目标源(这里为FSMC的(uint32_t)Bank1_LCD_D),外设地址应执行增1,而存储器不增
** 输入: 无
** 输出: 无
** 全局变量: 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)0;                     //外设地址  启用DMA时设置
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Bank1_LCD_D;              //DMA访问的数据地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;                         //传输方向
    DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE;                        //传输数据量大小  启用DMA时设置
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;             //外设地址不增加
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;                    //内存地址自增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_High;                         //DMA传送优先级为高

    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;                       //指定使用FIFO模式还是直接模式
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;           //指定了FIFO阈值
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                 //内存突发传输每次转移一个数据
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;         //外设突发传输每次转移一个数据

    DMA_Init(FSMC_DMA_STREAM, &DMA_InitStructure);
   
    NVIC_FSMC_DMA_Configuration();
    DMA_ITConfig(FSMC_DMA_STREAM, DMA_IT_TC | DMA_IT_TE, ENABLE);               //开DMA中断
    DMA_ClearFlag(FSMC_DMA_STREAM, FSMC_DMA_IT_TCIF | FSMC_DMA_IT_TEIF);
}

/************************************************************************************
** 说明: LCD刷屏DMA配置  将像素数组中的RGB颜色填充到FSMC总线上
** 输入: uint16_t *buff  像素数组指针
         uint16_t num    填充点数
** 输出: 无
** 全局变量: 无
** 调用模块: LCD_FSMC_DMA_CK();
************************************************************************************/
void LCD_FSMC_DMA_BMP(uint16_t *buff,uint16_t num)
{   
    DMA_InitTypeDef DMA_InitStructure;
      
    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_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) buff;//重新配置缓冲区地址和大小
    DMA_InitStructure.DMA_BufferSize = (uint32_t) num;            
    DMA_Init(FSMC_DMA_STREAM, &DMA_InitStructure);
   
    DMA_Cmd(FSMC_DMA_STREAM, ENABLE);
}
11[/tr]
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107443
QQ
发表于 2014-11-20 17:04:20 | 显示全部楼层
没有搞过这种方式,帮顶
回复

使用道具 举报

1

主题

33

回帖

36

积分

新手上路

积分
36
 楼主| 发表于 2014-11-21 11:13:18 | 显示全部楼层
在103上调试成功,移植到407上就不行了。407有双缓冲,这样可以将TF卡中的BMP图片分几次读取,实现无间断BMP显示,可以大幅提升外部存储中的图片显示速度
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107443
QQ
发表于 2014-11-21 12:09:11 | 显示全部楼层

回 maple_lu 的帖子

maple_lu:在103上调试成功,移植到407上就不行了。407有双缓冲,这样可以将TF卡中的BMP图片分几次读取,实现无间断BMP显示,可以大幅提升外部存储中的图片显示速度 (2014-11-21 11:13) 
这种方法比较适合裸机搞,使用emWin的话,就比较麻烦了。
回复

使用道具 举报

1

主题

33

回帖

36

积分

新手上路

积分
36
 楼主| 发表于 2014-11-21 13:22:37 | 显示全部楼层
是的,用emWin就不用DMA了,这个是在特殊应用上的
回复

使用道具 举报

116

主题

800

回帖

1148

积分

至尊会员

积分
1148
QQ
发表于 2014-11-26 09:14:04 | 显示全部楼层
楼主没用CCM段存储吧,不然开DMA不行的
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-1 08:22 , Processed in 0.163245 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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