M2M-DMA的问题

shyhard   2009-4-24 11:51 楼主
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_Buffer;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DST_Buffer;

采用M2M模式,在本地RAM测试通过。即
SRC_Buffer[x]={};  
DST_Buffer[x];
//都是RAM里开出来的区域。

问题来了,我扩展了一类似RAM的东东,就是TFT。
描述一下TFT的操作:TFT自带了显存,扩展地址:
#define    LCD_DATA (*((u16 volatile *)(0x60020000)))// ILI9320 数据;

写TFT_ILI9320 不同于一般外部SRAM,不需要地址信号,只管向LCD_DATA 送数据,地址是ILI9320 内部自己增加,如:整屏写一次TFT
Writ_ILI9320 ()
{
  for(int i=0; i<768000, <i++) //768000 = 320*240
  LCD_DATA = DATA;
}

现在改变目的地址
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_Buffer;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)LCD_DATA ;

 DMA_InitStructure.DMA_BufferSize = 320;
这样不能实现写ILI9320 ;
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_Buffer;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)LCD_DATA ;

 DMA_InitStructure.DMA_BufferSize = 1;
这样也不能实现写ILI9320 ;

后一种方法只是测试,应该可以写才对的。前一种方法,肯定不对了,首地是LCD_DATA ,下一个地址就不对了。不管多少数据我都是从LCD_DATA 写入,有办法吗??????????????



回复评论 (9)

有办法的

我不知道理解得对不对,lz的意图是通过DMA连续对LCD_DATA的地址传入数据吗?

如果是这样的话,只要把
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
改成
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
就可以了,这样,不论发生多少次DMA传输,目标的地址都不会改变。

lz修改DMA_InitStructure.DMA_BufferSize是没有意义的,这个参数定义的是DMA传输的次数。
点赞  2009-4-24 12:03

还需要注意数据传输的宽度,包括目标的宽度或源缓冲区数

                                 目标的宽度就是你的LCD_DATA宽度。
点赞  2009-4-24 12:37

刚才看了DMA资料我也改成了,发现没动静

void LCD_DMA_Init(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    u16 CurrDataCounter_Begin = 0, CurrDataCounter_End = 0;
    
    /* Enable DMA clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_DeInit(DMA1_Channel6);
    
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)BMP_BUF;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DET_BUF;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 320;  
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
    //DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
    DMA_Init(DMA1_Channel6, &DMA_InitStructure);

    /* Enable DMA Channel6 Transfer Complete interrupt */
    DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);

    /* Get Current Data Counter value before transfer begins */
    CurrDataCounter_Begin = DMA_GetCurrDataCounter(DMA1_Channel6);

    /* Enable DMA Channel6 transfer */
    DMA_Cmd(DMA1_Channel6, ENABLE);
    
    BSP_IntVectSet(BSP_INT_ID_DMA1_CH6, DMA1_CH6_ISRHandler);  // Assign ISR handler
    // Enable interrupt
}

void DMA1_CH6_ISRHandler(void)
{
  ....
  DMA_ClearFlag(DMA1_FLAG_GL6);
}

看看 我的设置上问题吗?谢谢
点赞  2009-4-24 14:09

你的设置有问题

为什么方向是DMA_DIR_PeripheralSRC?


另外,你最好先用程序直接操作LCD,保证LCD的接口正确后再用DMA。
点赞  2009-4-24 14:14

lcd 是没题,FSMC方式,

lcd 是没题,FSMC方式.
测试的速度,可以达到49帧/S, 耗尽了CUP.如果从外面取数据,速度会下降不少.所以试一下DMA方式,
DMA_DIR_PeripheralSRC,单向传输有问题吗??
点赞  2009-4-24 14:51

你需要从Memory向Peripheral传送数据,而不是倒过来

                                 LCD是Peripheral
点赞  2009-4-24 14:55

M2M好了.

感谢各位大虾.
提醒大家,最好看英文资料.
#define    LCD_DATA (*((u16 volatile *)(0x60020000)))// ILI9320 数据;

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)LCD_DATA ;// 错误
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x60020000;    // OK
点赞  2009-4-24 18:43

你原来那样写当然不对

#define    LCD_DATA (*((u16 volatile *)(0x60020000)))

DMA_PeripheralBaseAddr = (u32)LCD_DATA;
这是取地址为0x60020000的内容,而不是这个地址。
点赞  2009-4-24 20:51

看看

                                  
点赞  2009-4-26 14:58
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复