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

【求助】F207用DMA方式驱动FSMC接口的LCD屏的问题

[复制链接]
liutogo 提问时间:2016-11-20 12:02 /
本帖最后由 liutogo 于 2016-11-20 12:03 编辑

最近在做的项目中有一个480x320的彩屏,刷屏比较慢,需要提速,于是乎想到了DMA。
屏与STM32使用16Bit总线连接,使用FSMC传输方式。

对于写数据LCD也就是写(0x60000000 | 0x08080000)空间

在STM32F2的DMA2支持Memory to Memory的DMA传输方式

写DMA驱动初始化如下:
  1. uint8_t Image_DMA_init(void)
  2. {
  3.   DMA_InitTypeDef  DMA_InitStructure = {0};               
  4.         //注意,由于在本函数中该结构体仅被部分初始化,必须在定义该局部变量时对其进行0初始化,否则将出现不可预料的错误。
  5.         
  6.         u32        TimeOver = 0xffffffff;

  7.   /* 此处需要使用Memory to Memory的DMA传输,仅DMA2支持此种传输*/
  8.   /* 此处使用DMA2Stream1 */
  9.   /* Ref:ST RM0033 Rev7 P183 Memory-to-memory mode */
  10.   /* Enable DMA clock */
  11.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);               
  12.   
  13.   DMA_DeInit(DMA2_Stream1);        
  14.   while ((DMA_GetCmdStatus(DMA2_Stream1) != DISABLE) && TimeOver)
  15.         {
  16.                 TimeOver--;        
  17.         }

  18.         if(!TimeOver){
  19.                 return !0;
  20.         }
  21.         /*        IN Memory-to-memory mode, DMA channels work without being triggered by a request from a peripheral
  22.                 So,DMA parameter DMA_Channel do not need to be assigned */
  23.         //  DMA_InitStructure.DMA_Channel = DMA_Channel_3;               

  24.         /* Memory-to-memory mode Sourece Address: DMA_SxPAR Destination Address:DMA_SxM0AR */
  25.         /* 初始化时不需要指定源地址,传输前指定 */
  26.   //DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI1->DR));//0x4001300C;

  27.   /* 目的地址为LCD控制器对应的FSMC接口 */
  28.   DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&LCD2->LCD_RAM;
  29.   DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;

  30.         /* 初始化时不需要指定传输数据数,传输前指定NDTR */
  31.   //DMA_InitStructure.DMA_BufferSize = BGPIC_WIDTH * BGPIC_HEIGH << 1;               
  32.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
  33.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  34.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  35.   DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
  36.   /* When memory-to-memory mode is used, the Circular and direct modes are not allowed. */
  37.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  38.   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  39.   DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  40.   DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  41.   DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  42.   DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  43.   DMA_Init(DMA2_Stream1, &DMA_InitStructure);
  44.   /* DMA Stream enable */
  45.   DMA_Cmd(DMA2_Stream1, DISABLE);
  46.   

  47.   return 0;
  48. }
复制代码
DMA传输方式为从Memory的图像缓冲区地址空间(16位宽,递增),向(0x60000000 | 0x08080000)地址空间(16位宽,不递增)传输数据。
可是遇到的问题是:
每次传输(NDTR = 1下)本来应该只触发一次16Bit传输的FSMC时序(16Bit位宽的 565 RGB数据,对应一个像素点),实际被分成两次传输,触发了两次FSMC的写时序,结果在屏上绘制了两个点。



大家有没有类似的做过使用DMA通过FSMC刷屏的实验,麻烦帮我分析以下这样的问题,谢谢大家!
收藏 1 评论2 发布时间:2016-11-20 12:02

举报

2个回答
Robot@HCS 回答时间:2016-12-15 16:25:23
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
GPIO_InitTypeDef GPIO_InitStructure;


    //config SRAM DATA lines configuration D0------->>D15
//please reference STC datasheet FSMC PINs Page37
//D0---->>D3  D13------->>D15
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
                                  GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);

//D4----->>D12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
        GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
        GPIO_Pin_15;
GPIO_Init(GPIOE, &GPIO_InitStructure);

    //config SRAM ADRESS lines configuration A0------->>A18
//please reference STC datasheet FSMC PINs Page37
//A0------>>A9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
                             GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
                             GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOF, &GPIO_InitStructure);

//A10---->>A15
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
                             GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init(GPIOG, &GPIO_InitStructure);

//A16------->>A18
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 ;
GPIO_Init(GPIOD, &GPIO_InitStructure);

    //config SRAM NOE NWE lines configuration
//please reference STC datasheet FSMC PINs Page37
//NOE-->PD4     
//NWE ----->PD5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
GPIO_Init(GPIOD, &GPIO_InitStructure);

    //config SRAM NE3 lines configuration
//please reference STC datasheet FSMC PINs Page37
//NE4-->PG12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOG, &GPIO_InitStructure);

    //config SRAM NBL0, NBL1 lines configuration
//please reference STC datasheet FSMC PINs Page37
//NBL0(LB)-->PE0 NBL1(UB)-->PE1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOE, &GPIO_InitStructure);



//FSMC Structure Config
p.FSMC_AddressSetupTime = 0;//The time is used for duration address set up time
p.FSMC_AddressHoldTime = 0;//The time is used for duration address hold time
p.FSMC_DataSetupTime = 2;//The time is used for duration data set up time
p.FSMC_BusTurnAroundDuration = 0;//The time is used for the duration Bus turn
p.FSMC_CLKDivision = 0;//The division of HCLK
p.FSMC_DataLatency = 0;//The time is memory clock cycle before get first data
p.FSMC_AccessMode = FSMC_AccessMode_A;//


FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;//choose FSMC bank
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;//Address and Data line is not muxed
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;//The type of externed memory
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//The memory data widthy
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;//disable burst access ,because this is only used for synchronous memory
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;//only used in burst mode
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; //only used in burst mode
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;//only used in burst mode
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;//enable write
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;//only used in burst mode
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;//disable extended mode
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;//disable burst write mode
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

//enable FSMC bank1_NORSRAM
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
Robot@HCS 回答时间:2016-12-15 16:26:08
DMA_InitTypeDef  DMA_InitStructure;

DMA_DeInit(DMA1_Channel4);
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)SRC_Const_Buffer;//The address of peripheral
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Bank1_SRAM3_ADDR;//The DAM RAM address
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//Peripheral is the source of data
DMA_InitStructure.DMA_BufferSize =32;//32 times
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//The address of peripheral will be added
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//The address of DMA will be added
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//32 bits
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//32 bits
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA Work in normal mode,not Circle
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA high Priority
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;// enable Memory to Memory transfer

DMA_Init(DMA1_Channel4, &DMA_InitStructure);

//Enable DMA1 channel 4 transfer complete interrupt
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
//clear the flag
DMA_ClearFlag(DMA1_FLAG_TC4);

//Enable DAM1 channel4 transfer
DMA_Cmd(DMA1_Channel4, ENABLE);

所属标签

相似问题

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