初中生
最后登录1970-1-1
在线时间 小时
注册时间2016-9-21
|
本帖最后由 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(); //结束一次读取
}
|
|