OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6543|回复: 12

SPI到LCD的DMA如何调试呢

[复制链接]

43

主题

147

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2016-4-29
在线时间
137 小时
发表于 2018-1-18 11:05:01 | 显示全部楼层 |阅读模式
1金钱
之前调的一款屏,参考了原子哥F103的SPI Flash到LCD的DMA,移植到F407上了,DMA显示成功!

最近换了一款屏,还是8080接口,显示都已经调好了,现在试了下Flash到LCD的DMA,并没有显示出来。

DMA相关的代码,和上一款屏是一模一样的,我一行都没改。
原子哥的代码中,在DMA之前,屏相关的寄存器就写了下面这一个,wramcmd的值我也确认过是对的。
void LCD_WriteRAM_Prepare(void)
{
         LCD->LCD_REG=lcddev.wramcmd;
}


是否还有啥需要配或者改的呢?

void slcd_dma_init(void)
{  
        RCC->AHB1ENR|=1<<22;                //DMA2时钟使能  
        while(DMA2_Stream2->CR&0X01);//等待DMA2_Stream2可配置
        DMA2->LIFCR|=0X0F7D0F7D;                //清空Stream2的通道0-3上所有中断标志
        DMA2_Stream2->FCR=0X0000021;//设置为默认值        
        
        DMA2_Stream2->PAR=(u32)&SPI1->DR;                        //外设地址为:SPI1->DR
        DMA2_Stream2->M0AR=(u32)&LCD->LCD_RAM;        //目标地址为LCD_RAM
        DMA2_Stream2->M1AR=0;                //不用设置
        DMA2_Stream2->NDTR=0;                //暂时设置长度为0
        DMA2_Stream2->CR=0;                        //先全部复位CR寄存器值  
        DMA2_Stream2->CR|=0<<6;                //外设到存储器模式
        DMA2_Stream2->CR|=0<<8;                //普通模式
        DMA2_Stream2->CR|=0<<9;                //外设非增量模式
        DMA2_Stream2->CR|=0<<10;        //存储器非增量模式
        DMA2_Stream2->CR|=1<<11;        //外设数据长度:16位
        DMA2_Stream2->CR|=1<<13;        //存储器数据长度:16位
        DMA2_Stream2->CR|=2<<16;        //高优先级
        DMA2_Stream2->CR|=0<<18;        //单缓冲模式
        DMA2_Stream2->CR|=0<<21;        //外设突发单次传输
        DMA2_Stream2->CR|=0<<23;        //存储器突发单次传输
        DMA2_Stream2->CR|=3<<25;        //选择通道0
        
        DMA2_Stream2->FCR&=~(1<<2);        //不使用FIFO模式
        DMA2_Stream2->FCR&=~(3<<0);        //无FIFO 设置  
}


void slcd_spi2_mode(u8 mode)
{
        u16 tempreg=0;
        if(mode==0)        //8位普通模式,重新配置SPI
        {
        //这里只针对SPI口初始化
                RCC->APB2RSTR|=1<<12;        //复位SPI1
                RCC->APB2RSTR&=~(1<<12);//停止复位SPI1
                tempreg|=0<<10;                        //全双工模式        
                tempreg|=1<<9;                        //软件nss管理
                tempreg|=1<<8;                        
                tempreg|=1<<2;                        //SPI主机  
                tempreg|=0<<11;                        //8位数据格式        
                tempreg|=1<<1;                        //空闲模式下SCK为1 CPOL=1
                tempreg|=1<<0;                        //数据采样从第2个时间边沿开始,CPHA=1   
                tempreg|=0<<3;                        //2分频,设置为42Mhz频率
                tempreg|=0<<7;                        //MSB First  
                tempreg|=1<<6;                        //SPI启动
                SPI1->CR1=tempreg;                 //设置CR1  
                SPI1->I2SCFGR&=~(1<<11);//选择SPI模式
        }else                                                //16位DMA模式
        {
                SPI1->CR1|=1<<10;                 //仅接收模式   
                SPI1->CR1|=1<<11;                //16bit数据格式        
                SPI1->CR2|=1<<0;                //使用DMA接收
        }  
}


void slcd_dma_enable()
{         
        u32 lcdsize=spbdev.spbwidth*spbdev.spbheight;
        u32 dmatransfered=0;
        while(lcdsize)
        {
                DMA2_Stream2->CR&=~(1<<0);                        //关闭DMA传输
                while(DMA2_Stream2->CR&0X01);                //等待DMA2_Stream2可配置
                DMA2->LIFCR|=1<<21;                                        //清除上次的传输完成标记
                if(lcdsize>SLCD_DMA_MAX_TRANS)
                {
                        lcdsize-=SLCD_DMA_MAX_TRANS;
                        DMA2_Stream2->NDTR=SLCD_DMA_MAX_TRANS;        //设置传输长度
                }else
                {
                        DMA2_Stream2->NDTR=lcdsize;        //设置传输长度
                        lcdsize=0;
                }        
//                DMA2_Stream2->PAR=(u32)(sramlcdbuf+x*spbdev.spbheight+dmatransfered);        
                dmatransfered+=SLCD_DMA_MAX_TRANS;               
                DMA2_Stream2->CR|=1<<0;                                //开启DMA传输                 
                while((DMA2->LISR&(1<<21))==0);                //等待传输完成
        }
        DMA2_Stream2->CR&=~(1<<0);                                //关闭DMA传输
}

void slcd_frame_show(u16 x)
{
    OS_CPU_SR cpu_sr=0;
        u32 addr=SPILCD_BASE+1+(x*spbdev.spbheight)*2;
        LCD_Scan_Dir(U2D_L2R);                //设置扫描方向
        if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510||lcddev.id==0X6804)
        {
                LCD_Set_Window(spbdev.stabarheight,0,spbdev.spbheight,spbdev.spbwidth);
                LCD_SetCursor(spbdev.stabarheight,0);//设置光标位置
        }else
        {
                LCD_Set_Window(0,spbdev.stabarheight,spbdev.spbwidth,spbdev.spbheight);
                if(lcddev.id!=0X1963)LCD_SetCursor(0,spbdev.stabarheight);//设置光标位置                 
        }
        LCD_WriteRAM_Prepare();     //开始写入GRAM         
        W25QXX_CS=0;                                       //使能器件   
    SPI1_ReadWriteByte(W25X_FastReadData);        //发送快速读取命令   
    SPI1_ReadWriteByte((u8)((addr)>>16));        //发送24bit地址   
    SPI1_ReadWriteByte((u8)((addr)>>8));   
    SPI1_ReadWriteByte((u8)addr);  
    SPI1_ReadWriteByte(0XFF);        //8 dummy clock  
        slcd_spi2_mode(1);                         //设置为16位宽,DMA接收
        OS_ENTER_CRITICAL();                //进入临界区(无法被中断打断)            
        slcd_dma_enable();                        //启动一次SPI到LCD的dma传输
        OS_EXIT_CRITICAL();                        //退出临界区(可以被中断打断)
        slcd_spi2_mode(0);                        //恢复8位模式
        //加入读数据,判断是不是白屏.
        W25QXX_CS=1;                                    //禁止W25QXX
        LCD_Scan_Dir(DFT_SCAN_DIR);        //恢复默认方向        
        LCD_Set_Window(0,0,lcddev.width,lcddev.height);//恢复默认窗口大小         
}



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-1-19 02:20:34 | 显示全部楼层
既然调试成功了应该不难了,仿真找找吧
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2018-2-20
在线时间
33 小时
发表于 2018-2-27 13:53:03 | 显示全部楼层
楼主解决了吗
回复

使用道具 举报

43

主题

147

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2016-4-29
在线时间
137 小时
 楼主| 发表于 2018-6-21 14:23:48 | 显示全部楼层

没有啊 这款LCD 死活没法DMA
你也用的这款吗?
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2017-12-19
在线时间
5 小时
发表于 2018-6-22 23:14:24 | 显示全部楼层
请问F103的SPI Flash到LCD的DMA是综合实验的例程吗
回复

使用道具 举报

43

主题

147

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2016-4-29
在线时间
137 小时
 楼主| 发表于 2018-6-24 10:40:11 | 显示全部楼层
aint 发表于 2018-6-22 23:14
请问F103的SPI Flash到LCD的DMA是综合实验的例程吗

是的啊
回复

使用道具 举报

13

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2016-1-15
在线时间
36 小时
发表于 2018-10-14 00:17:08 | 显示全部楼层
这种把flash内部图像dma到lcd个和屏幕的 驱动 IC有没有关系 ?刷出来的是白屏。不用dma倒是可以把flash内部图像刷出来
回复

使用道具 举报

1

主题

63

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1820
金钱
1820
注册时间
2015-11-30
在线时间
255 小时
发表于 2018-12-21 17:39:53 | 显示全部楼层
abc3240660 发表于 2018-6-21 14:23
没有啊 这款LCD 死活没法DMA
你也用的这款吗?

我也碰到类似问题    不用DMA数据一个一个传输过去能够显示   
用DMA就是显示不了   是和速度有关系么?
回复

使用道具 举报

1

主题

63

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1820
金钱
1820
注册时间
2015-11-30
在线时间
255 小时
发表于 2018-12-21 17:40:14 | 显示全部楼层
maplblue 发表于 2018-10-14 00:17
这种把flash内部图像dma到lcd个和屏幕的 驱动 IC有没有关系 ?刷出来的是白屏。不用dma倒是可以把flash内部 ...

我也碰到类似问题    不用DMA数据一个一个传输过去能够显示   
用DMA就是显示不了   是和速度有关系么?
回复

使用道具 举报

13

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2016-1-15
在线时间
36 小时
发表于 2018-12-22 16:55:03 | 显示全部楼层
asianeast 发表于 2018-12-21 17:40
我也碰到类似问题    不用DMA数据一个一个传输过去能够显示   
用DMA就是显示不了   是和速度有关系么?

熟读一下  显示芯片的手册  0x36   MX  MY  重点关注下 写一个像素横纵座标是否会自动加一
回复

使用道具 举报

1

主题

63

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1820
金钱
1820
注册时间
2015-11-30
在线时间
255 小时
发表于 2018-12-23 17:20:17 | 显示全部楼层
maplblue 发表于 2018-12-22 16:55
熟读一下  显示芯片的手册  0x36   MX  MY  重点关注下 写一个像素横纵座标是否会自动加一

现在的问题不是显示端的问题,如果通过软件SPI数据一个一个传输到LCD驱动芯片,显示正常。如果用SPI DMA就无法显示,是因为DMA数据传输太快还是其他原因? 有相关操作经验吗?
回复

使用道具 举报

0

主题

32

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
379
金钱
379
注册时间
2017-1-4
在线时间
129 小时
发表于 2019-6-14 18:34:40 来自手机 | 显示全部楼层
问题解决了吗?我遇到了DMA显示不全的问题,搜了一下论坛也有这个问题,但都没找到原因
回复

使用道具 举报

43

主题

147

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2016-4-29
在线时间
137 小时
 楼主| 发表于 2019-6-17 08:59:11 | 显示全部楼层
kuyoung 发表于 2019-6-14 18:34
问题解决了吗?我遇到了DMA显示不全的问题,搜了一下论坛也有这个问题,但都没找到原因

后来也没能解决,不知道玄机在哪
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-16 21:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表