21ic问答首页 - 求助!!STM32F407VE DMA+FSMC+LCD,照片显示成4个小图
求助!!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发送完成中断使能函数
↑ 不知道为啥我的添加代码文字功能用不了,格式有点乱。
有没有大佬能给解惑
最终图片是显示出来了,但是被均分成了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发送完成中断使能函数
↑ 不知道为啥我的添加代码文字功能用不了,格式有点乱。
有没有大佬能给解惑
赞0
在动态测试之前,首先需要设定测试时间和测试频率
评论
2024-09-06
赞0
构成各种滤波器对EMI进行滤波
评论
2024-09-06
赞0
Cfinal是CESD和人体电容的并联组合
评论
2024-09-06
赞0
模信号是幅度相等且相位相同的信号
评论
2024-09-06
赞0
防雷电路的输出残压值必须比被防护电路自身能够耐受的过电压峰值低,并有一定裕量
评论
2024-09-06
赞0
随着对电路板模块的需求增加
评论
2024-09-06
赞0
信号防雷电路应满足相应接口信号传输速率及带宽的需求,且接口与被保护设备兼容。
评论
2024-09-06
赞0
在测试中,可以改变负载电流,得到最大输出电流和输出电压
评论
2024-09-06
赞0
测试负载测试是在特定的测试条件下进行的
评论
2024-09-06
您需要登录后才可以回复 登录 | 注册