OpenEdv-开源电子网

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

STM32F4 LCD+DMA

[复制链接]

9

主题

44

帖子

2

精华

中级会员

Rank: 3Rank: 3

积分
402
金钱
402
注册时间
2014-8-15
在线时间
0 小时
发表于 2015-7-18 10:36:37 | 显示全部楼层 |阅读模式
5金钱
[mw_shl_code=c,true]请教STM32F4使用DMA传输数据至LCD的问题。[/mw_shl_code]
[mw_shl_code=c,true]#define Frame_SIZE 4800 u16 FlappyBird_Frame[Frame_SIZE];//4800  1/80屏幕 void LCD_DMA_Coinfig(void) { DMA_InitTypeDef  DMA_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能[/mw_shl_code] [mw_shl_code=c,true] DMA_DeInit(DMA2_Stream7); while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE){}//等待DMA1_Stream1可配置 /* 配置 DMA Stream */ DMA_DeInit(DMA2_Stream7); //将DMA设为缺省值 DMA_InitStructure.DMA_Channel = DMA_Channel_5; //通道选择 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) Frame; DMA_InitStructure.DMA_Memory0BaseAddr = (u32)&(LCD->LCD_RAM);//LCD写地址 DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;//存储器到外设器模式 DMA_InitStructure.DMA_BufferSize = Frame_SIZE/2;//数据传输量 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//外设增量模式 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//存储器非增量模式 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据长度:16位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器数据长度:16位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用**模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输 DMA_InitStructure.DMA_PeripheralBurst = DMA_MemoryBurst_Single;//外设突发单次传输 DMA_Init(DMA2_Stream7, &DMA_InitStructure);//初始化DMA Stream // DMA_ITConfig(DMA2_Stream7,DMA_IT_TC,ENABLE); } //开启LCD DMA传输 void LCD_DMA_Enable(u16* buf0) { DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7); //清除上次的传输完成标记 DMA_Cmd(DMA2_Stream7, ENABLE);//开启DMA传输 while(DMA_GetFlagStatus(DMA2_Stream7,DMA_FLAG_TCIF7)==RESET); //等待 DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7); //清除上次的传输完成标记 }[/mw_shl_code]
然后我在主函数里:
LCD_SetCursor(0x00,0x0000); //设置光标位置 
LCD_WriteRAM_Prepare();     //开始写入GRAM  
for(i=0;i<36;i++)
{
res=f_read(ftemp,Frame,Frame_SIZE,(UINT*)&bread);//直接读取数据 
LCD_DMA_Enable(); //启动一次DMA传输
}
效果是这样的(LCD我设置了窗口大小,所以只显示一小半,但是显示内容是错的):


然后我尝试不用DMA:
LCD_SetCursor(0x00,0x0000); //设置光标位置 
LCD_WriteRAM_Prepare();     //开始写入GRAM  
for(i=0;i<36;i++)
{
res=f_read(ftemp,FlappyBird_Frame,Frame_SIZE,(UINT*)&bread);//直接读取数据 
for(j=0;j<Frame_SIZE/2;j++)
   {
    LCD->LCD_RAM=Frame[j];
}
}
正常效果,是一片蓝色天空:


LCD我设置了窗口大小,所以只显示一小半

DMA确实应该用M2M,半字节应该也没有问题。LCD,FSMC时序还是原子程序以前那样,我加快加满都试过了没用。但是没有DMA能正常显示的话就说明确实是DMA的问题。求解!



最佳答案

查看完整内容[请看2#楼]

回复【2楼】正点原子: --------------------------------- 解决了。我也不知道怎么解决的。程序看着都是一样的。上面的配置也完全没有问题。 还有一个注意事项请大家注意。一旦DMA设置里面用到的存储器是使用内存管理方式分配内存的,一定要先分配内存再配置DMA,顺序反了DMA传输数据出错。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

44

帖子

2

精华

中级会员

Rank: 3Rank: 3

积分
402
金钱
402
注册时间
2014-8-15
在线时间
0 小时
 楼主| 发表于 2015-7-18 10:36:38 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
解决了。我也不知道怎么解决的。程序看着都是一样的。上面的配置也完全没有问题。
还有一个注意事项请大家注意。一旦DMA设置里面用到的存储器是使用内存管理方式分配内存的,一定要先分配内存再配置DMA,顺序反了DMA传输数据出错。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2015-7-18 17:58:27 | 显示全部楼层
帮顶 .....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-25 00:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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