本帖最后由 liutogo 于 2016-11-20 12:10 编辑
最近在做的项目中有一个480x320的彩屏,刷屏比较慢,需要提速,于是乎想到了DMA。
屏与STM32使用16Bit总线连接,使用FSMC传输方式。
对于写数据LCD也就是写(0x60000000 | 0x08080000)空间
在STM32F2的DMA2支持Memory to Memory的DMA传输方式
写DMA驱动初始化如下:
- uint8_t Image_DMA_init(void)
- uint8_t Image_DMA_init(void)
- {
- DMA_InitTypeDef DMA_InitStructure = {0};
- //注意,由于在本函数中该结构体仅被部分初始化,必须在定义该局部变量时对其进行0初始化,否则将出现不可预料的错误。
- u32 TimeOver = 0xffffffff;
- /* 此处需要使用Memory to Memory的DMA传输,仅DMA2支持此种传输*/
- /* 此处使用DMA2Stream1 */
- /* Ref:ST RM0033 Rev7 P183 Memory-to-memory mode */
- /* Enable DMA clock */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
- DMA_DeInit(DMA2_Stream1);
- while ((DMA_GetCmdStatus(DMA2_Stream1) != DISABLE) && TimeOver)
- {
- TimeOver--;
- }
- if(!TimeOver)
- {
- return !0;
- }
- /* IN Memory-to-memory mode, DMA channels work without being triggered by a request from a peripheral
- So,DMA parameter DMA_Channel do not need to be assigned */
- // DMA_InitStructure.DMA_Channel = DMA_Channel_3;
- /* Memory-to-memory mode Sourece Address: DMA_SxPAR Destination Address:DMA_SxM0AR */
- /* 初始化时不需要指定源地址,传输前指定 */
- //DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI1->DR));//0x4001300C;
- /* 目的地址为LCD控制器对应的FSMC接口 */
- DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&LCD2->LCD_RAM;
- DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;
- /* 初始化时不需要指定传输数据数,传输前指定NDTR */
- //DMA_InitStructure.DMA_BufferSize = BGPIC_WIDTH * BGPIC_HEIGH << 1;
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
- DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
- /* When memory-to-memory mode is used, the Circular and direct modes are not allowed. */
- DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
- DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
- DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
- DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
- DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
- DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
- DMA_Init(DMA2_Stream1, &DMA_InitStructure);
- /* DMA Stream enable */
- DMA_Cmd(DMA2_Stream1, DISABLE);
- return 0;
- }
复制代码
DMA传输方式为从Memory的图像缓冲区地址空间(16位宽,递增),向(0x60000000 | 0x08080000)地址空间(16位宽,不递增)传输数据。
可是遇到的问题是:
每次传输(NDTR = 1下)本来应该只触发一次16Bit传输的FSMC时序(16Bit位宽的 565 RGB数据,对应一个像素点),实际被分成两次传输,触发了两次FSMC的写时序,结果在屏上绘制了两个点。
大家有没有类似的做过使用DMA通过FSMC刷屏的实验,麻烦帮我分析以下这样的问题,谢谢大家!
此帖出自
小平头技术问答
一周热门 更多>