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

【求助】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管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版