野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 28343|回复: 10

【求解答】关于FSMC+DMA+LCD可能性验证中出的问题

[复制链接]
发表于 2014-2-2 21:02:32 | 显示全部楼层 |阅读模式
本帖最后由 天空の鱼 于 2014-2-3 00:59 编辑

在这里已经卡壳好几天了,网上的资料也比较少
求火哥指导一下第三步问题到底出在哪???


第一步:我用FSMC模拟了8080端口,在没有使用DMA的前提下成功初始化并刷新了LCD  说明FSMC与LCD的配置没问题
int main()
{
   u32 i;
   GPIO_Config();
   FSMC_LCD_Config();
   LCD_Init();
   LCD_Write_Cmd(0x2C);
   for(i=0; i<(320*240); i++)     
  {
      LCD_Write_Data(2500);  
   }
   while(1);
}



第二步:使用DMA的M2M模式成功将一个内存的值复制到了另外一个内存    说明DMA配置正确
int main()
{
    u16 i=0x1546,n=0;
    u16 *Memory=&i;
    u16 *Peripheral=&n;
    GPIO_Config();
    DMA_Config();
    DMA_Start(Memory,Peripheral);
    if(n==0x1546)
    led(1);
    while(1);
}

第三部:我将外设的地址变为0x60000000(LCD指令地址),使用DMA向LCD发送0x2c的指令,其他所以的都不变,但是不行
进一步用LED小灯验证发现LED小灯不亮,程序卡死在写指令这一行
int main()
{
   u32 i;
   u16 cmd=(u16)0x2c;
   GPIO_Config();
   DMA_Config();
   FSMC_LCD_Config();
   LCD_Init();
   DMA_Start(&cmd,(u16*)0x60000000);//<----------用DMA代替LCD_Write_Cmd(0x2C);来验证DMA与FSMC融合的可能性
   led(1);              //<--------------------这里LED小灯没亮说明程序没能过DMA_Start()函数
   for(i=0; i<(320*240); i++)     
   {
      LCD_Write_Data(2500);  
   }
   while(1);
}


下面是配置代码:



#include "stm32f10x.h"
GPIO_InitTypeDef gpio;
DMA_InitTypeDef dma;
enum time{s,ms,us};




void GPIO_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
gpio.GPIO_Pin=GPIO_Pin_3;
gpio.GPIO_Speed=GPIO_Speed_50MHz;
gpio.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOC,&gpio);
led(0);
}




void SysTick_Init()
{
SysTick->VAL=0;
}




void Delay(enum time t,u16 n)
{
u16 i;
switch(t)
{
  case s: SysTick->LOAD=9000000; break;
  case ms:SysTick->LOAD=9000; break;
  case us:SysTick->LOAD=9; break;
  }
SysTick->CTRL|=SysTick_CTRL_ENABLE;
for(i=0;i<n;i++)
while((SysTick->CTRL&0x00010000)==0);
SysTick->CTRL&=~SysTick_CTRL_ENABLE;
SysTick->VAL=0;
}




void DMA_Config()
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
dma.DMA_DIR=DMA_DIR_PeripheralDST;
dma.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
dma.DMA_MemoryInc=DMA_MemoryInc_Disable;
dma.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
dma.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
dma.DMA_Mode=DMA_Mode_Normal;
dma.DMA_Priority=DMA_Priority_VeryHigh;
dma.DMA_M2M=DMA_M2M_Enable;
}



void DMA_Start(u16* Memory,u16* Peripheral)
{
   dma.DMA_PeripheralBaseAddr=(u32)Peripheral;
   dma.DMA_MemoryBaseAddr=(u32)Memory;
   dma.DMA_BufferSize=1;
   DMA_Init(DMA1_Channel1,&dma);
   DMA_Cmd(DMA1_Channel1,ENABLE);
}



void FSMC_LCD_Config()
{
FSMC_NORSRAMInitTypeDef fsmc;
FSMC_NORSRAMTimingInitTypeDef timing;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|
                        RCC_APB2Periph_GPIOE|
                        RCC_APB2Periph_GPIOB,
                        ENABLE);

gpio.GPIO_Pin=GPIO_Pin_13;            //LCD背光
gpio.GPIO_Speed=GPIO_Speed_50MHz;
gpio.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOD,&gpio);

gpio.GPIO_Pin=GPIO_Pin_1;             //LCD复位
gpio.GPIO_Speed=GPIO_Speed_50MHz;
gpio.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOE,&gpio);

gpio.GPIO_Pin=
               GPIO_Pin_0|              //FSMC_D2-----------------
               GPIO_Pin_1|              //FSMC_D3-----------------
             //GPIO_Pin_3|              //FSMC_CLK-  -  -  -  -  -(同步模式时钟)
               GPIO_Pin_4|              //FSMC_NOE-  -  -  -  -  -(读信号)
               GPIO_Pin_5|              //FSMC_NWE-  -  -  -  -  -(写信号)
             //GPIO_Pin_6|              //FSMC_NWAIT -  -  -  -  -(等待信号)
               GPIO_Pin_7|              //FSMC_NE1-  -  -  -  -  -(块选择标志)
               GPIO_Pin_8|              //FSMC_D13----------------
               GPIO_Pin_9|              //FSMC_D14----------------
               GPIO_Pin_10|             //FSMC_D15----------------
               GPIO_Pin_11|             //FSMC_A16 - * - * - * - *(连接了 数据/指令 选择线)
             //GPIO_Pin_12|             //FSMC_A17 - * - * - * - *
             //GPIO_Pin_13|             //FSMC_A18 - * - * - * - *(连接了背光灯)
               GPIO_Pin_14|             //FSMC_D0-----------------
               GPIO_Pin_15;             //FSMC_D1-----------------
  gpio.GPIO_Speed=GPIO_Speed_50MHz;
  gpio.GPIO_Mode=GPIO_Mode_AF_PP;
  GPIO_Init(GPIOD,&gpio);

gpio.GPIO_Pin=
             //GPIO_Pin_0|              //FSMC_NBL0 -  -  -  -  - (PSRAM模式下高字节使能)
             //GPIO_Pin_1|              //FSMC_NBL1 -  -  -  -  - (PSRAM模式下低字节使能,连接了LCD复位脚)
             //GPIO_Pin_2|              //FSMC_A23 - * - * - * - *
             //GPIO_Pin_3|              //FSMC_A19 - * - * - * - *
             //GPIO_Pin_4|              //FSMC_A20 - * - * - * - *
             //GPIO_Pin_5|              //FSMC_A21 - * - * - * - *
             //GPIO_Pin_6|              //FSMC_A22 - * - * - * - *
               GPIO_Pin_7|              //FSMC_D4-----------------
               GPIO_Pin_8|              //FSMC_D5-----------------
               GPIO_Pin_9|              //FSMC_D6-----------------
               GPIO_Pin_10|             //FSMC_D7-----------------
               GPIO_Pin_11|             //FSMC_D8-----------------
               GPIO_Pin_12|             //FSMC_D9-----------------
               GPIO_Pin_13|             //FSMC_D10----------------
               GPIO_Pin_14|             //FSMC_D11----------------
        GPIO_Pin_15;             //FSMC_D12----------------
gpio.GPIO_Speed=GPIO_Speed_50MHz;
gpio.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOE,&gpio);

gpio.GPIO_Pin=GPIO_Pin_7;              //FSMC_NADV  -  -  -  -  -(数据/地址信号复用标志)
gpio.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOB,&gpio);
timing.FSMC_AddressSetupTime=2;
timing.FSMC_AddressHoldTime=0;
timing.FSMC_DataSetupTime=5;
timing.FSMC_BusTurnAroundDuration=0;
timing.FSMC_CLKDivision=0;
timing.FSMC_DataLatency=0;
timing.FSMC_AccessMode=FSMC_AccessMode_B;

fsmc.FSMC_Bank=FSMC_Bank1_NORSRAM1;
fsmc.FSMC_DataAddressMux=FSMC_DataAddressMux_Disable;
fsmc.FSMC_MemoryType=FSMC_MemoryType_NOR;
fsmc.FSMC_MemoryDataWidth=FSMC_MemoryDataWidth_16b;
fsmc.FSMC_BurstAccessMode=FSMC_BurstAccessMode_Disable;
fsmc.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
fsmc.FSMC_WriteOperation=FSMC_WriteOperation_Enable;
fsmc.FSMC_WaitSignal=FSMC_WaitSignal_Disable;
fsmc.FSMC_ExtendedMode=FSMC_ExtendedMode_Enable;
fsmc.FSMC_WriteBurst=FSMC_WriteBurst_Disable;
fsmc.FSMC_ReadWriteTimingStruct=&timing;
fsmc.FSMC_WriteTimingStruct=&timing;
FSMC_NORSRAMInit(&fsmc);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1,ENABLE);
}



void LCD_Init()
{
  RES(1);
  Delay(ms,30);         
  RES(0);     
  Delay(ms,30);

LCD_Write_Cmd(0xCF);
LCD_Write_Data(0x00);
LCD_Write_Data(0x81);
LCD_Write_Data(0x30);

LCD_Write_Cmd(0xED);
LCD_Write_Data(0x64);
LCD_Write_Data(0x03);
LCD_Write_Data(0x12);
LCD_Write_Data(0x81);

LCD_Write_Cmd(0xE8);
LCD_Write_Data(0x85);
LCD_Write_Data(0x10);
LCD_Write_Data(0x78);

LCD_Write_Cmd(0xCB);
LCD_Write_Data(0x39);
LCD_Write_Data(0x2C);
LCD_Write_Data(0x00);
LCD_Write_Data(0x34);
LCD_Write_Data(0x02);

LCD_Write_Cmd(0xF7);
LCD_Write_Data(0x20);

LCD_Write_Cmd(0xEA);
LCD_Write_Data(0x00);
LCD_Write_Data(0x00);

LCD_Write_Cmd(0xB1);
LCD_Write_Data(0x00);
LCD_Write_Data(0x1B);

LCD_Write_Cmd(0xB6);
LCD_Write_Data(0x0A);
LCD_Write_Data(0xA2);

LCD_Write_Cmd(0xC0);
LCD_Write_Data(0x35);

LCD_Write_Cmd(0xC1);
LCD_Write_Data(0x11);

LCD_Write_Cmd(0xC5);
LCD_Write_Data(0x45);
LCD_Write_Data(0x45);

LCD_Write_Cmd(0xC7);
LCD_Write_Data(0xA2);

LCD_Write_Cmd(0xF2);
LCD_Write_Data(0x00);

LCD_Write_Cmd(0x26);
LCD_Write_Data(0x01);

LCD_Write_Cmd(0xE0);
LCD_Write_Data(0x0F);
LCD_Write_Data(0x26);
LCD_Write_Data(0x24);
LCD_Write_Data(0x0B);
LCD_Write_Data(0x0E);
LCD_Write_Data(0x09);
LCD_Write_Data(0x54);
LCD_Write_Data(0xA8);
LCD_Write_Data(0x46);
LCD_Write_Data(0x0C);
LCD_Write_Data(0x17);
LCD_Write_Data(0x09);
LCD_Write_Data(0x0F);
LCD_Write_Data(0x07);
LCD_Write_Data(0x00);

LCD_Write_Cmd(0XE1);
LCD_Write_Data(0x00);
LCD_Write_Data(0x19);
LCD_Write_Data(0x1B);
LCD_Write_Data(0x04);
LCD_Write_Data(0x10);
LCD_Write_Data(0x07);
LCD_Write_Data(0x2A);
LCD_Write_Data(0x47);
LCD_Write_Data(0x39);
LCD_Write_Data(0x03);
LCD_Write_Data(0x06);
LCD_Write_Data(0x06);
LCD_Write_Data(0x30);
LCD_Write_Data(0x38);
LCD_Write_Data(0x0F);

LCD_Write_Cmd(0x36);
LCD_Write_Data(0x68);

LCD_Write_Cmd(0X2A);
LCD_Write_Data(0x00);
LCD_Write_Data(0x00);
LCD_Write_Data(0x01);
LCD_Write_Data(0x3F);

LCD_Write_Cmd(0X2B);
LCD_Write_Data(0x00);
LCD_Write_Data(0x00);
LCD_Write_Data(0x00);
LCD_Write_Data(0xEF);
LCD_Write_Cmd(0x3a);
LCD_Write_Data(0x55);
LCD_Write_Cmd(0x11);
Delay(ms,2);
LCD_Write_Cmd(0x29);
}

回复

使用道具 举报

发表于 2014-2-2 21:12:35 | 显示全部楼层
用dma的M2M功能感觉很鸡肋啊,你为什么不直接往内存地址写数据?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-2 21:19:28 | 显示全部楼层
随风 发表于 2014-2-2 21:12
用dma的M2M功能感觉很鸡肋啊,你为什么不直接往内存地址写数据?

我最终的目的是要通过DMA向LCD大批量地传输数据,比如图片什么的,而且这样CPU能腾出手做其他事情
回复 支持 反对

使用道具 举报

发表于 2014-2-2 21:22:43 | 显示全部楼层
天空の鱼 发表于 2014-2-2 21:19
我最终的目的是要通过DMA向LCD大批量地传输数据,比如图片什么的,而且这样CPU能腾出手做其他事情

我没有试过DMA的M2M功能,不过感觉你的配置不太正确:
dma.DMA_DIR=DMA_DIR_PeripheralDST;
M2M的话目的地址应该是内存啊
回复 支持 反对

使用道具 举报

发表于 2014-2-2 21:25:54 | 显示全部楼层
天空の鱼 发表于 2014-2-2 21:19
我最终的目的是要通过DMA向LCD大批量地传输数据,比如图片什么的,而且这样CPU能腾出手做其他事情

这个参数也写错了:  

DMA_Start(&cmd,(u16*)60000000);//<----------用DMA代替LCD_Write_Cmd(0x2C);来验证DMA与FSMC融合的可能性

应该是0x60000000 吧,你用了10进制
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-2 21:26:07 | 显示全部楼层
随风 发表于 2014-2-2 21:22
我没有试过DMA的M2M功能,不过感觉你的配置不太正确:
dma.DMA_DIR=DMA_DIR_PeripheralDST;
M2M的话目的 ...

这个应该没问题,因为第二步中M2M的配置正确性已经得到了验证。如果没有传输成功LED是不会亮的
回复 支持 反对

使用道具 举报

发表于 2014-2-2 21:27:04 | 显示全部楼层
天空の鱼 发表于 2014-2-2 21:26
这个应该没问题,因为第二步中M2M的配置正确性已经得到了验证。如果没有传输成功LED是不会亮的

这个参数写错了:  

DMA_Start(&cmd,(u16*)60000000);//<----------用DMA代替LCD_Write_Cmd(0x2C);来验证DMA与FSMC融合的可能性

应该是0x60000000 吧,你用了10进制
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-2 21:27:18 | 显示全部楼层
随风 发表于 2014-2-2 21:25
这个参数也写错了:  

DMA_Start(&cmd,(u16*)60000000);//

我改下试试。。。不好意思犯这种低级错误。。。比雷公还雷人哦~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-2 21:28:46 | 显示全部楼层
随风 发表于 2014-2-2 21:27
这个参数写错了:  

DMA_Start(&cmd,(u16*)60000000);//

改了,还是没反应。对了,我用的V3的板子。。。
回复 支持 反对

使用道具 举报

发表于 2014-2-2 21:36:50 | 显示全部楼层
天空の鱼 发表于 2014-2-2 21:28
改了,还是没反应。对了,我用的V3的板子。。。

可能因为是字长宽度不对应吧,dma的配置是16位的,fsmc那个配置是8位的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-2 21:39:27 | 显示全部楼层
随风 发表于 2014-2-2 21:36
可能因为是字长宽度不对应吧,dma的配置是16位的,fsmc那个配置是8位的

fsmc.FSMC_MemoryDataWidth=FSMC_MemoryDataWidth_16b;
FSMC也是16位的。。。
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 15:47 , Processed in 0.048004 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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