写flash 刚开始我用spi硬件方式读写是没有问题的,但是当我用spi dma 方式写,然后用硬件方式读,发现有错误!
比如我定义两个数组
u8 rvc[10];
const u8 send[10] = {0x01,0x02,0x03.0x04,0x05,0x06,0x07,0x08,0x09,0x0a};
用dma写,然后用硬件读,然后打印发现
rvc[0] =0xff
rvc[1] =0x01
rvc[2] =0x02
rvc[3] =0x03
rvc[4] =0x04
rvc[5] =0x05
rvc[6] =0x06
rvc[7] =0x07
rvc[8] =0x08
rvc[9] =0x0a
就是往右移了一位,不知道是为什么,我之前怀凝是DMA字节对齐问题,但是查不出结果,想问一下,有哪位朋友是不是也遇到类似问题了,怎么解决的?
DMA相关写的部分程序:
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI_MASTER_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)0;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 0xffff;
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_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
DMA_ITConfig(DMA1_Channel3,DMA_IT_TC,ENABLE);
// NumByteToWrite<256
void Flash_WritePage(uint8_t* pBuffer, u32 WriteAddr, uint16_t NumByteToWrite)
{
sFLASH_WriteEnable();
sFLASH_WaitForWriteEnd();
sFLASH_CS_LOW();
sFLASH_SendByte(sFLASH_CMD_WRITE);
sFLASH_SendByte((WriteAddr&0xFF0000)>>16);
sFLASH_SendByte((WriteAddr&0xFF00)>>8);
sFLASH_SendByte(WriteAddr&0xFF);
// if(NumByteToWrite>256)
// {
// NumByteToWrite=256;
// }
// while(NumByteToWrite--)
// {
// sFLASH_SendByte(*pBuffer);
// pBuffer++;
// }
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = NumByteToWrite;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel3,ENABLE);
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
共享下DMA那部分就好了!
我的不会呀,就是错位,我发我的代码给你看看!#include "mcu_spi.h"
#include "stdio.h"
#define sFLASH_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_2)
#define sFLASH_CS_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_2)
#define sFLASH_CMD_WRSR 0x01
#define sFLASH_CMD_WRITE 0x02
#define sFLASH_CMD_READ 0x03
#define sFLASH_CMD_DISWR 0x04
#define sFLASH_CMD_RDSR 0X05
#define sFLASH_CMD_ENWR 0x06
#define sFLASH_DUMMY_BYTE 0xFF
#define sFLASH_CMD_BE 0xc7
#define sFLASH_CMD_SE 0xd8
#define sFLASH_CMD_RDID 0x9f
#define sFLASH_IDADDR 0x14
#define sFLASH_SPI_PAGESIZE 0x100 //one page 256 byte
#define sFLASH_W25X16_ID 0x3015
u8 Rvcbuf2[10];
u8 Sendbuf2[10]= {
0x01,0x02,0x03,0x04,
0x05,0x06,0x07,0x08,
0x09,0x0a
};
#define SPI_MASTER_DR_Base 0x4001300C
DMA_InitTypeDef DMA_InitStructure;
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO|
RCC_APB2Periph_SPI1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA , &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//spi enable pin
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI_MASTER_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Rvcbuf2;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 0xffff;
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_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Sendbuf2;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
SPI_Cmd(SPI1, DISABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);
DMA_ITConfig(DMA1_Channel3,DMA_IT_TC,ENABLE);
DMA_Cmd(DMA1_Channel2, DISABLE);
DMA_Cmd(DMA1_Channel3, DISABLE);
}
u8 sFLASH_SendByte(u8 dat)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1,dat);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI1);
}
void sFLASH_WriteEnable(void)
{
sFLASH_CS_LOW();
sFLASH_SendByte(sFLASH_CMD_ENWR);
sFLASH_CS_HIGH();
}
void sFLASH_WaitForWriteEnd(void)
{
uint8_t flashstatus = 0;
sFLASH_CS_LOW();
sFLASH_SendByte(sFLASH_CMD_RDSR);
do
{
flashstatus = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
}
while ((flashstatus & 0x01) == SET);
sFLASH_CS_HIGH();
}
void Flash_WritePage(uint8_t* pBuffer, u32 WriteAddr, uint16_t NumByteToWrite)
{
sFLASH_WriteEnable();
sFLASH_WaitForWriteEnd();
sFLASH_CS_LOW();
sFLASH_SendByte(sFLASH_CMD_WRITE);
sFLASH_SendByte((WriteAddr&0xFF0000)>>16);
sFLASH_SendByte((WriteAddr&0xFF00)>>8);
sFLASH_SendByte(WriteAddr&0xFF);
//hard mode write
// if(NumByteToWrite>256)
// {
// NumByteToWrite=256;
// }
// while(NumByteToWrite--)
// {
// sFLASH_SendByte(*pBuffer);
// pBuffer++;
// }
//DMA mode write
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = NumByteToWrite;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel3,ENABLE);
}
u8 sFLASH_ReadByte(void)
{
return (sFLASH_SendByte(sFLASH_DUMMY_BYTE));
}
//hard mode read
void sFLASH_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead)
{
sFLASH_CS_LOW();
sFLASH_SendByte(sFLASH_CMD_READ);
sFLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
sFLASH_SendByte((ReadAddr& 0xFF00) >> 8);
sFLASH_SendByte(ReadAddr & 0xFF);
while (NumByteToRead--)
{
*pBuffer++ = sFLASH_ReadByte();
}
}
void sFLASH_BulkErase(void)
{
sFLASH_WriteEnable();
sFLASH_WaitForWriteEnd();
sFLASH_CS_LOW();
sFLASH_SendByte(sFLASH_CMD_BE);
sFLASH_CS_HIGH();
sFLASH_WaitForWriteEnd();
}
void DMA1_Channel2_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA1_IT_TC2) != RESET)
{
DMA_ClearFlag(DMA1_IT_GL2);
DMA_Cmd(DMA1_Channel2, DISABLE); }
}
void DMA1_Channel3_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA1_IT_TC3) != RESET)
{
DMA_ClearFlag(DMA1_IT_GL3);
DMA_Cmd(DMA1_Channel3, DISABLE);
}
}
void SPI_Flash_Check(void)
{
Flash_WritePage((u8*)&Sendbuf2,0,10);
delay_ms(10);
sFLASH_CS_HIGH();
sFLASH_WaitForWriteEnd();
sFLASH_ReadBuffer((u8*)&Rvcbuf2,0,10);
delay_ms(100);
LED_RED_FLASH();
printf("Rvcbuf2[0]=: %x ",Rvcbuf2[0]);
printf("Rvcbuf2[1]=: %x ",Rvcbuf2[1]);
printf("Rvcbuf2[2]=: %x ",Rvcbuf2[2]);
printf("Rvcbuf2[3]=: %x ",Rvcbuf2[3]);
printf("Rvcbuf2[4]=: %x ",Rvcbuf2[4]);
printf("Rvcbuf2[5]=: %x ",Rvcbuf2[5]);
printf("Rvcbuf2[6]=: %x ",Rvcbuf2[6]);
printf("Rvcbuf2[7]=: %x ",Rvcbuf2[7]);
printf("Rvcbuf2[8]=: %x ",Rvcbuf2[8]);
printf("Rvcbuf2[9]=: %x ",Rvcbuf2[9]);
}
打印信息:
rvc[0] =0xff
rvc[1] =0x01
rvc[2] =0x02
rvc[3] =0x03
rvc[4] =0x04
rvc[5] =0x05
rvc[6] =0x06
rvc[7] =0x07
rvc[8] =0x08
rvc[9] =0x0a
切换回硬件,不用DMA就正常了!
void SPI_Flash_Write_DMA_Config(uint8_t *pBuffer,uint16_t NumByteToWrite)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = NumByteToWrite;
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);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
}
void SPI_Flash_Write_DMA(uint8_t *pBuffer,uint16_t NumByteToWrite)
{
SPI_Flash_Write_DMA_Config(pBuffer,NumByteToWrite);
DMA_Cmd(DMA1_Channel3, ENABLE);
while(DMA_GetITStatus(DMA1_IT_TC3) == RESET);
DMA_ClearITPendingBit(DMA1_IT_TC3);
}
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
/* Enable the write access to the FLASH */
SPI_FLASH_WriteEnable();
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Write to Memory " instruction */
SPI_FLASH_SendByte(W25X_PageProgram);
/* Send WriteAddr high nibble address byte to write to */
SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
/* Send WriteAddr medium nibble address byte to write to */
SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
/* Send WriteAddr low nibble address byte to write to */
SPI_FLASH_SendByte(WriteAddr & 0xFF);
if(NumByteToWrite > SPI_FLASH_PerWritePageSize)
{
NumByteToWrite = SPI_FLASH_PerWritePageSize;
//printf(" Err: SPI_FLASH_PageWrite too large!");
}
#ifdef USE_DMA_WRITE_FLASH
SPI_Flash_Write_DMA(pBuffer,NumByteToWrite); //这里不行,卡在这里,所以写我还没有实现
#else
//如果不用DMA则使用下面的代码
/* while there is data to be written on the FLASH */
while (NumByteToWrite--)
{
/* Send the current byte */
SPI_FLASH_SendByte(*pBuffer);
/* Point on the next byte to be written */
pBuffer++;
}
#endif
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
/* Wait the end of Flash writing */
SPI_FLASH_WaitForWriteEnd();
}
你都没有开DMA中断,应该是这while(DMA_GetITStatus(DMA1_IT_TC3) == RESET);有问题吧
你用while(!DMA_GetFlagStatus(DMA1_FLAG_TC3));把它换掉试试!
我这边读可以了,但是写不会死掉,就是第一个还是写不进去的!
一周热门 更多>