SPI+DMA+SST25VF064 DMA数据只能发送1次,不用DMA发送数据读取数据正常

2019-10-15 04:05发布


#define CNT   256
#define SST25VF064_CS_High() GPIO_SetBits(GPIOC,  GPIO_Pin_0) 
#define SST25VF064_CS_Low() GPIO_ResetBits(GPIOC,  GPIO_Pin_0)
#define ReadMemory 0x03
#define FastReadDualIO 0xBB
#define FastReadDualO 0x3B
#define HighSpeedRead 0x0B
#define SectorErase4K 0x20
#define BlockErase32K 0x52
#define BlockErase64K 0xD8
#define ChipErase 0x60
#define PageProgram 0x02
#define DualInputPageProgram 0xA2
#define RDSR 0x05
#define EWSR 0x50
#define WRSR 0x01
#define WREN 0x06
#define WRDI 0x04
#define RDID 0x90
#define JedecID 0x9F
#define EHLD 0xAA
#define ReadSid 0x88
#define ProgramSid 0xA5
#define LockOutSid 0x85

u8 buff1[513];

 int main(void)
{  
u8 p[513] = {0};
u16 i,num = 0,count = 0,offset = 0;
SPI1_Init();
Chip_Erase();
for(i=0;i<256;i++)
buff1= i;
  for(i=0;i<256;i++)
  buff1[i+256]= i;
   for(i=0;i<1;i++)
   buff1[i+512]= i+5;
while(1)
{
SST25VF064ReadData(0,513,(u8 *)p);
// PageProgram256Byte(0,513,(u8 *)buff1);
DMA_Send((u8 *)buff1,256,0);
DMA_Send((u8 *)buff1,256,256);
SST25VF064ReadData(0,513,(u8 *)p);

SST25VF064ReadData(0,513,(u8 *)p);
    
}



void SPI1_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_SPI1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

//MOSI MISO SCLK
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

SST25VF064_CS_High();
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_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);

DMA_DeInit(DMA1_Channel3);
    DMA_Cmd(DMA1_Channel3, DISABLE);       
    DMA_ClearFlag(DMA1_FLAG_TC3 | DMA1_FLAG_GL3);   
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buff1; 
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;    
    DMA_InitStructure.DMA_BufferSize = CNT;  
    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_Channel3, &DMA_InitStructure);
// DMA_ITConfig(DMA1_Channel3,DMA_IT_TC, ENABLE);

// /* Configure one bit for preemption priority */
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;  
// NVIC_Init(&NVIC_InitStructure);

SPI_Cmd(SPI1, ENABLE);
}



u8 SPI1_ReadWrite(u8 dat)
{
   /* Loop while DR register in not emplty */
   while (SPI_I2S_GetFlagStatus(SPI1,SPI_SR_TXE) == RESET);
   /* Send byte through the SPI1 peripheral */
   SPI_I2S_SendData(SPI1,dat);
/* Wait to receive a byte */
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_SR_RXNE) == RESET);
   /* Return the byte read from the SPI bus */
   return SPI_I2S_ReceiveData(SPI1);
}

void SST25VF064WriteEnable(void)
{
SST25VF064_CS_Low();
SPI1_ReadWrite(WREN);
SST25VF064_CS_High();
}


void SST25VF064WriteDisable(void)
{
SST25VF064_CS_Low();
SPI1_ReadWrite(WRDI);
SST25VF064_CS_High();
}




u8 SST25VF064ReadStatus(void)
{
u8 dat;
SST25VF064_CS_Low();
SPI1_ReadWrite(RDSR);
dat = SPI1_ReadWrite(0xFF);
SST25VF064_CS_High();
return dat;
}

void BusyTest(void)
{
while((SST25VF064ReadStatus() & 0x01) == 0x01)
SST25VF064ReadStatus();
}

void WriteStatusRegister(void)
{
SST25VF064_CS_Low();
SPI1_ReadWrite(EWSR);
SST25VF064_CS_High();

SST25VF064_CS_Low();
SPI1_ReadWrite(WRSR);
SPI1_ReadWrite(0x00);
SST25VF064_CS_High();
BusyTest();
}

void Chip_Erase(void)
{
SST25VF064WriteEnable();
SST25VF064_CS_Low();
SPI1_ReadWrite(ChipErase);
SST25VF064_CS_High();
SST25VF064WriteDisable();
BusyTest();
}



void SST25VF064ReadData(u32 addr,u16 num,u8 *p)
{
u16 i = 0;
SST25VF064_CS_Low();
SPI1_ReadWrite(ReadMemory);//??????
SPI1_ReadWrite((u8)(addr >> 16));
SPI1_ReadWrite((u8)(addr >> 8));
SPI1_ReadWrite((u8)addr);
SPI1_ReadWrite(0xFF);
for(i=0;i<num;i++)
p = SPI1_ReadWrite(0xFF);
SST25VF064_CS_High();
}



void DMA_Send(u8 *s,u16 num,u32 addr)
{
WriteStatusRegister();
SST25VF064WriteEnable(); //??????
SST25VF064_CS_Low(); //???????§

SPI1_ReadWrite(0x02); //????????×??à256×???
SPI1_ReadWrite((u8)(addr >> 16)); //???·??×???
SPI1_ReadWrite((u8)(addr >> 8));
SPI1_ReadWrite((u8)addr);

DMA1_Channel3->CCR &= (uint16_t)(~DMA_CCR1_EN); //?§??DMA????Channel3?¨??
DMA1_Channel3->CMAR = (uint32_t)s; //????
DMA1_Channel3->CNDTR = num; //·????¤??
DMA1_Channel3->CCR |= DMA_CCR1_EN; //????DMA  

while(!DMA_GetFlagStatus(DMA1_FLAG_TC3)); //????·????ê??
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY));//????SPI????
DMA_ClearFlag(DMA1_FLAG_TC3 | DMA1_FLAG_GL3);
DMA_Cmd(DMA1_Channel3, DISABLE); //?§??DMA

SST25VF064_CS_High();
SST25VF064WriteDisable(); //???§??
BusyTest(); //???ì??
}




void PageProgram256Byte(u32 addr,u16 num,u8 *p)
{
u16 i = 0;
WriteStatusRegister();
SST25VF064WriteEnable();
SST25VF064_CS_Low();
SPI1_ReadWrite(PageProgram);
SPI1_ReadWrite((u8)(addr >> 16));
SPI1_ReadWrite((u8)(addr >> 8));
SPI1_ReadWrite((u8)addr);
for(i=0;i<num;i++)
SPI1_ReadWrite(p);
SST25VF064_CS_High();
SST25VF064WriteDisable();
BusyTest();
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
yinghuajf_0215
1楼-- · 2019-10-15 06:01
 SST25VF064为MicroChip FLASH 芯片,8M字节,每页最多写256个字节,可4K、32K、64K或片擦除,项目要求将电流、电压波形数据存入指定的地址。
波形存储数据大小为4K,起始地址为每4k的首地址。根据SST25VF064读写条件,写数据时需将片选拉低,完成后将其拉高。写数据时需先写使能,每页最多写256字节,DMA发送时,每次发送256字节后需要变更写入数据的地址,读数据可以连续读取多个字节。

程序中每次写入256个字节时变变更1次地址,写完1次,需将DMA失能,SST25VF064片选拉高,并失能写操作,为保证DMA发送时最后一个字节发送完成,需在DMA发送完成后,等待SPI发送空。
每次写数据,需交DMA失能,才能更改发送数据的个数,再使能DMA。
将测试原码贴上供大家参考,请各位大神指正
另用原子串口程序使用printf打印读取的数据时,发现第1个字节丢失
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);

while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}
   
    return ch;

改为 int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);

while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
   
    return ch;
} 正常。
yinghuajf_0215
2楼-- · 2019-10-15 08:47
各位大神,帮忙分析一下,SST25VF064每页只能写256个字节,DMA写1次后,第2次写数据写不进去是什么原因?
正点原子
3楼-- · 2019-10-15 09:55
帮顶....
刀锋风灵
4楼-- · 2019-10-15 13:05
同样遇到这个问题,DMA第一次发送没有问题,后面的DMA就没有数据了,但是写SPI->DR寄存器可以正常发送

一周热门 更多>