liudingding 发表于 2022-9-13 11:22:01

斑竹,帮忙解决一下DMA不能搬运数据到液晶屏

本帖最后由 liudingding 于 2022-9-13 11:40 编辑

我属愚笨型人员,主控F407是用寄存器开发的,显示屏用TK499,例程都是库开发的,不懂库函数,写起程序很困难,照瓢画瓢从例程上抄了个DMA搬运数据显示的程序,不工作,求斑竹看看哪里错了,直接来个正确的程序,你要是说修改方法的话,我将是云里雾里的听不懂,这个帖子就看不懂:www.amobbs.com/forum.php?mod=viewthread&tid=5764784&highlight=DMA,


程序如下:
LCD_Fill_Pic(0, 0,320, 480, (u32*)gImage_MM_T035);//用DMA模式 显示一幅图片       


/******************************************
函数名:Lcd图像填充
功能:向Lcd指定位置填充图像
入口参数:
                                        (x,y): 图片左上角起始坐标
                                        (pic_H,pic_V): 图片的宽高
                                       pic指向存储图片数组的指针
******************************************/
void LCD_Fill_Pic(u16 x, u16 y,u16 pic_H, u16 pic_V, u32*pic)
{
        //DMA 方式
        BlockWrite(x,x+pic_H-1,y,y+pic_V-1);   //开窗函数
        TK80_DMA_Init((u32)pic, pic_H*pic_V*2);//DMA初始化
        while((DMA2->ISR & 0x20)==0);
        DMA2->IFCR |=1<<5;       
}
void TK80_DMA_Init(u32 srcAdd ,u32 len)       //TK80的DMA配置函数,srcAdd是源地址,len是数据长度,一次能搬运42亿点
{   
        RCC->AHB2ENR |= RCC_AHB2Periph_TK80;   
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
       
      DMA2_Channel2->CCR = 0x3090;                        //0x3090==8位, 0x3590==16位,      0x3A90==32位,
        DMA2_Channel2->CPAR = (u32)&(TK80->DINR);
        TK80->CFGR1 = 0x05050102;
        TK80->CFGR2 = 0x0501;

        DMA2_Channel2->CMAR= srcAdd;//存储器地址(发送地址)
        DMA2_Channel2->CNDTR = len;   //数据传输长度
        DMA2_Channel2->CCR|= 1;       //通道开启
        TK80->CR |= 1;
}
void WriteComm(unsigned int CMD) //写命令
{
        TK80->CMDIR = CMD;
        while(TK80->SR & 0x10000);
}

void WriteData(u32 dat) //写数据
{
        TK80->DINR = dat;
        while(TK80->SR & 0x10000);       
}
/**********************************************
函数名:开窗函数

入口参数:XStart x方向的起点
          Xend   x方向的终点
                                        YStart y方向的起点
          Yend   y方向的终点

这个函数的意义是:开一个矩形框,方便接下来往这个框填充数据
***********************************************/
void BlockWrite(unsigned int Xstart,unsigned int Xend,unsigned int Ystart,unsigned int

Yend)
{

        WriteComm(0x2a);
        WriteData(Xstart>>8);
        WriteData(Xstart);
        WriteData(Xend>>8);
        WriteData(Xend);

        WriteComm(0x2b);   
        WriteData(Ystart>>8);
        WriteData(Ystart);
        WriteData(Yend>>8);
        WriteData(Yend);
        WriteComm(0x2c);
}

armok. 发表于 2022-9-13 11:23:56

已经帮你转告版主

tiky 发表于 2022-9-13 12:27:49

      你是用在7寸屏上吗?7寸屏这种属于线性显示器,你用这个DMA属于直接内存到内存copy,可以用在特例下面,就是搬运的数据刚好等于屏的分辨率,也就是全屏显了。或者还有一个特例情况,就是整行显示,这个用在LVGL界面上比较多,就只更新需要更新的行数,其它不动的行不更新显示,达到快速显示的效果。
      只参考DMA例程中的M to M例程就行,如下函数,只需要更改目标地址M_addr_des及源地址M_addr_scr 两个参数就行。
      原理是,线性显示器是从内存中顺序读取数据,发送到LTDC接口给显示器显示的,所以所有操作只有内存操作就行。
void DMA_m32tom32_test(void)
{
        DMA_InitTypeDef DMA_InitStructure;

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

        DMA_InitStructure.DMA_PeripheralBaseAddr = M_addr_des;
DMA_InitStructure.DMA_MemoryBaseAddr = M_addr_scr;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 128;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
       
        DMA_Cmd(DMA1_Channel6, ENABLE);
        AI_Responder_refresh();//refresh the AI Responder
}

liudingding 发表于 2022-9-13 14:05:59

本帖最后由 liudingding 于 2022-9-13 14:42 编辑

tiky 发表于 2022-9-13 12:27
你是用在7寸屏上吗?7寸屏这种属于线性显示器,你用这个DMA属于直接内存到内存copy,可以用在特例 ...
(引用自3楼)

谢谢斑竹答复,还有个问题不明白:
DMA_InitStructure.DMA_PeripheralBaseAddr = M_addr_des;
如果我要让源起始地址为:__align(4) const unsigned char gImage_MM_T035首地址,
或者u32cc首地址,应该怎么写?
可能是基础问题,基础不行,只会 ifelse



解决了,从寄存器来,一直用&取地址,用库不会了,基础不牢,不要笑话,

tiky 发表于 2022-9-13 15:57:40

你定义变量时,gImage_MM_T035这个变量就已经是4字节对齐了,直接把这个地址递交给DMA就行
页: [1]
查看完整版本: 斑竹,帮忙解决一下DMA不能搬运数据到液晶屏