野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15234|回复: 3

spi flash DMA TFTLCD 显示偶尔有错?

[复制链接]
发表于 2017-9-4 15:59:07 | 显示全部楼层 |阅读模式
本帖最后由 hubertboy 于 2017-9-4 16:05 编辑

各位大神,现在项目中遇到一个问题,请求大家协助!
项目工作描述如下:
1,通过SPI1 DMA 读取 spi flash 25Q16  到 缓存BUF1
2,通FSMC 接口,采用DMA 方式发送数据至TFTLCD  采用8080方式 8位数据接口,240*320 ,竖显
3,每次传输数据量为240*8 个数据(4行显示数据)


现在问题如下:
1, 采用DMA 方式读取FLASH,有时候数据会丢失第一个字节!
导致LCD 对应显示数据的几行错误。(一副图,会错误几行数据)
2,如果读取flash 方式不采用DMA 方式,显示数据没有错误!




下面为DMA 设置的相关部分代码:


void Flash_DMA_Config1(u16 num)
{
        DMA_InitTypeDef DMA_InitStructure;


        /*开启时钟*/
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);


    DMA_DeInit(DMA1_Channel2);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Rx_Buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = num;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel2, &DMA_InitStructure);


   
    DMA_DeInit(DMA1_Channel3);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Tx_Buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = num;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);


    DMA_Cmd (DMA1_Channel2,ENABLE);
    DMA_Cmd (DMA1_Channel3,ENABLE);


}
此部分是发送FLASH 读 命令及地址的代码


void SPI_FLASH_StartReadSequence(u32 ReadAddr)
{
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();


  /* Send "Read from Memory " instruction */
  SPI_FLASH_SendByte(W25X_ReadData);


  /* Send the 24-bit address of the address to read from -----------------------*/
  /* Send ReadAddr high nibble address byte */
  SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  /* Send ReadAddr medium nibble address byte */
  SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  /* Send ReadAddr low nibble address byte */
  SPI_FLASH_SendByte(ReadAddr & 0xFF);
}



此为启动DMA 接受数据部分代码
void SPI_DMA_BufferReadContinue(void)
{
        
        SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
        SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
        
        while(DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET);
        //while(DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);
        
        DMA_ClearFlag(DMA1_FLAG_TC3);
        DMA_ClearFlag(DMA1_FLAG_TC2);
        
        SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, DISABLE);
        SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, DISABLE);
        
}




以下为显示一副图片的程序
void DispPicFromFlash(unsigned char num)
{
        unsigned long ReadAddr;
        u32 i;
        
        LCD_SetArea(0,0,239,319);
        LCD_WR_REG(0x2C);
        
        ReadAddr = 153600*num;       //计算图片在FLASH 中的偏移地址


        SPI_FLASH_StartReadSequence(ReadAddr);
        
        for(i=0;i<80;i++)
        {
        Flash_DMA_Config1(240*8);
        SPI_DMA_BufferReadContinue();
        
        //FSMC_DMA_Config();
        FSMC_DMA_Config1(240*8);
        }
        
        SPI_FLASH_CS_HIGH();       //结束一次读取
}













回复

使用道具 举报

发表于 2017-9-4 16:30:55 | 显示全部楼层
缓存spi的数据变量定义成4字节对齐试试
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-4 20:10:06 | 显示全部楼层
随风 发表于 2017-9-4 16:30
缓存spi的数据变量定义成4字节对齐试试

目前程序中数据是按8位 单字节处理的,
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-8 09:52:51 | 显示全部楼层
自己回复下!

在中文的手册上看到,SPI 最大速率为18Mhz,将速率降下来就搞定了!开始跑到36Mhz ,不使用DMA 方式一切正常!

如有大神路过,请指点下,如果不是用DMA 方式,SPI 是否可以跑36MHZ?

回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-6 15:21 , Processed in 0.038448 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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