问答

汇集网友智慧,解决技术难题

21ic问答首页 - 求助!!STM32F407VE DMA+FSMC+LCD,照片显示成4个小图

ST 单片机 嵌入式 技术交流

求助!!STM32F407VE DMA+FSMC+LCD,照片显示成4个小图

lylam182023-09-12
之前一直玩103,最近画了块板子F407Ve的,翻出1个之前的LCD,想通过DMA将数组中的图片,搬到FSMC挂的屏由于对407不是很熟,代码大部分都是通过F407ZE的代码,东拼西凑,改来的
最终图片是显示出来了,但是被均分成了4小份显示出来了,例如:一张图240*320,变成了4张60*80的小图(不好意思,我上传不了图)
然后就是各种线路排出,代码排查。快两个周了,还没找到问题
1. DMA将照片搬到u8、u16、u32数组,数据都没有问题(数据顺序),几乎可以排除DMA代码的问题
2. 如果将数组的数据,按照1个点1个点向LCD写,图片也没问题
3. 只有在通过DMA将数据通过FSMC搬到LCD时,结果就变成4张小图(有可能是数据错位,1分裂成4了)
所以跟人怀疑是FSMC导致的,但是各种试解决不了

这是LCD地址
#define TFTLCD_BASE   ((u32)(0x60000000 | 0x0001FFFE))  //Bank1.sector1 + A16
#define TFTLCD                        ((TFTLCD_TypeDef *) TFTLCD_BASE)


这是FSMC复用部分配置
GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,        GPIO_AF_FSMC);//PD0                FSMC_D2
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,        GPIO_AF_FSMC);//PD1                FSMC_D3
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,        GPIO_AF_FSMC);//PD4                                                        FSMC_NOE
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,        GPIO_AF_FSMC);//PD5                                                        FSMC_NWE
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,        GPIO_AF_FSMC);//PD8                FSMC_D13
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,        GPIO_AF_FSMC);//PD9                FSMC_D14
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC);//PD10        FSMC_D15
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC);//PD14        FSMC_D0
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);//PD15        FSMC_D1

  GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,        GPIO_AF_FSMC);//PE7                FSMC_D4
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,        GPIO_AF_FSMC);//PE8                FSMC_D5
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,        GPIO_AF_FSMC);//PE9                FSMC_D6
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC);//PE10        FSMC_D7
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC);//PE11        FSMC_D8
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC);//PE12        FSMC_D9
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC);//PE13        FSMC_D10
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC);//PE14        FSMC_D11
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC);//PE15        FSMC_D12

  GPIO_PinAFConfig(GPIOD,GPIO_PinSource7, GPIO_AF_FSMC);//PD7                                                        FSMC_NE1
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource11,GPIO_AF_FSMC);//PD11                                                FSMC_A16


//这是FSMC关键部分的代码

  NorsRamInit.FSMC_Bank        = FSMC_Bank1_NORSRAM1;// 存储块标号和区号        :这里我用的是NE1
  NorsRamInit.FSMC_DataAddressMux         = FSMC_DataAddressMux_Disable; // 数据线与地址线是否复用        :不复用数据地址
  NorsRamInit.FSMC_MemoryType = FSMC_MemoryType_SRAM;        // 外接存储器类型:FSMC_MemoryType_SRAM;  //SRAM   
  NorsRamInit.FSMC_MemoryDataWidth= FSMC_MemoryDataWidth_16b;// 存储器数据宽度:16bit   
  NorsRamInit.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;// 配置访问模式:启用或禁用闪存的突发访问模式,仅对同步突发闪存有效。不太理解!!!
  NorsRamInit.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;// 等待信号极性
NorsRamInit.FSMC_AsynchronousWait= FSMC_AsynchronousWait_Disable;
  NorsRamInit.FSMC_WrapMode = FSMC_WrapMode_Disable;                                                           // 是否使用非对齐方式
  NorsRamInit.FSMC_WaitSignalActive= FSMC_WaitSignalActive_BeforeWaitState;        // 等待信号什么时期产生
  NorsRamInit.FSMC_WriteOperation= FSMC_WriteOperation_Enable;                                                // 存储器写使能
  NorsRamInit.FSMC_WaitSignal= FSMC_WaitSignal_Disable;                                                   // 是否使用等待信号
  NorsRamInit.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;                                                         // 读写使用不同的时序
  NorsRamInit.FSMC_WriteBurst          = FSMC_WriteBurst_Disable;                                                         // 是否允许突发写操作
  NorsRamInit.FSMC_ReadWriteTimingStruct = &ReadTiming;// 读写时序
  NorsRamInit.FSMC_WriteTimingStruct  = &WriteTiming;          // 写时序
  FSMC_NORSRAMInit(&NorsRamInit);                                                                                                                                                                                                  // 初始化FSMC配置
  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); // 使能BANK1


// 初始化DAM配置
void DMC_LLL(u32 L_PAdd,u32  PIne,u32 PLeng,          u32 L_MAdd,u32 MInc,u32 MLeng,   u32 L_BufferSize)
{
        DMA_InitTypeDef      DMA_InitStructure;
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
        DMA_DeInit(DMA2_Stream1);
        while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE){}         //等待DMA2_Stream1可配置

  //配置 DMA Stream
  DMA_InitStructure.DMA_Channel  = DMA_Channel_1;   //DCMI_CH1
  DMA_InitStructure.DMA_DIR  = DMA_DIR_PeripheralToMemory;        //外设到内存
  DMA_InitStructure.DMA_BufferSize          = L_BufferSize;         //数据传输量

        DMA_InitStructure.DMA_PeripheralBaseAddr  = L_PAdd; //外设地址:
  DMA_InitStructure.DMA_PeripheralInc = PIne;         //外设非增量模式 DMA_PeripheralInc_Disable
  DMA_InitStructure.DMA_PeripheralDataSize         = PLeng;         //外设数据长度:32bit                DMA_PeripheralDataSize_Word
  DMA_InitStructure.DMA_PeripheralBurst                 = DMA_PeripheralBurst_Single;        //外设突发单次传输
               
  DMA_InitStructure.DMA_Memory0BaseAddr  = L_MAdd;         //内存地址 //(u32)&MAdd
  DMA_InitStructure.DMA_MemoryInc          = MInc;                 //内存增量模式                DMA_MemoryInc
  DMA_InitStructure.DMA_MemoryDataSize          = MLeng;         //内存数据长度
  DMA_InitStructure.DMA_MemoryBurst  = DMA_MemoryBurst_Single;         //内存突发单次传输
               
  DMA_InitStructure.DMA_Mode  = DMA_Mode_Circular;         //使用循环模式(不停地传送,并非一行一行的传送)
  DMA_InitStructure.DMA_Priority  = DMA_Priority_High;                                        //高优先级
  DMA_InitStructure.DMA_FIFOMode  = DMA_FIFOMode_Enable;                                //FIFO模式        
  DMA_InitStructure.DMA_FIFOThreshold  = DMA_FIFOThreshold_Full;                        //使用全FIFO
       
  DMA_Init(DMA2_Stream1, &DMA_InitStructure);         //初始化DMA Stream
//DMA_ITConfig(DMA2_Stream1, DMA_IT_TC, ENABLE); //DMA发送完成中断使能函数



↑ 不知道为啥我的添加代码文字功能用不了,格式有点乱。

有没有大佬能给解惑



回答 +关注 5
948人浏览 17人回答问题 分享 举报
17 个回答
  • 感觉你只能一步一步调试看看问题在哪了。
  • 用的正点原子的板子?
  • 你可以把图片保存在电脑桌面,然后上传呀。可以传图最好是有个图,不然光语述还是不太清楚是啥样的。
  • LCD屏幕都有哪些需要注意的事项?
  • 最新进展:如果将DMA的配置改一下,图片可以显示一张正常的。
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  //更改前:显示4张小图
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;      //更改后:显示1张小图

    也就是说,
    DMA配置Memory是16bit,不管从u8、u16、u32,向LCD搬运,图片都不正常
    DMA配置改成8bit后,不管从u8、u16、u32,向LCD搬运,图片都正常
    这就奇怪了

    有一次把LCD的手册粗略看了一遍
    早上又跑去跟厂家要TFT的电路图,确认LCD硬件上到底是8bit的还是16bit的,答案是:16bit的
    那就不明白了,为什么16bit搬到16bit的LCD中,就变成4小份了????

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 这个配置是例程中的,拿来就用
    是不是我对哪里理解有问题,大佬们给点意见


    另外:由于我电脑(可能是浏览器,flash插件什么的)问题,图片一直上传失败,代码模式也不排版,只能通过文字表达,实在不好意思!!!!!!
  • 做个模拟测试试试
    lylam18 2023-9-14 10:39 回复TA
    请问我应该怎么模拟测试? 
  • 添加图片不能用吗?
    lylam18 2023-9-13 08:06 回复TA
    一直提示图片上传失败,可能跟我浏览器有关 

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