OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4655|回复: 4

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

[复制链接]

8

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2014-8-22
在线时间
14 小时
发表于 2015-1-13 11:12:40 | 显示全部楼层 |阅读模式
5金钱

#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();
}

SPI.rar

2.5 MB, 下载次数: 201

最佳答案

查看完整内容[请看2#楼]

 SST25VF064为MicroChip FLASH 芯片,8M字节,每页最多写256个字节,可4K、32K、64K或片擦除,项目要求将电流、电压波形数据存入指定的地址。 波形存储数据大小为4K,起始地址为每4k的首地址。根据SST25VF064读写条件,写数据时需将片选拉低,完成后将其拉高。写数据时需先写使能,每页最多写256字节,DMA发送时,每次发送256字节后需要变更写入数据的地址,读数据可以连续读取多个字节。 程序中每次写入256个字节时变变 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2014-8-22
在线时间
14 小时
 楼主| 发表于 2015-1-13 11:12:41 | 显示全部楼层
 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;
正常。

SPI1.rar

2.39 MB, 下载次数: 276

回复

使用道具 举报

8

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2014-8-22
在线时间
14 小时
 楼主| 发表于 2015-1-13 11:15:24 | 显示全部楼层
各位大神,帮忙分析一下,SST25VF064每页只能写256个字节,DMA写1次后,第2次写数据写不进去是什么原因?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165558
金钱
165558
注册时间
2010-12-1
在线时间
2118 小时
发表于 2015-1-13 23:55:50 | 显示全部楼层
帮顶....
回复

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2016-8-30
在线时间
12 小时
发表于 2017-2-9 21:21:35 | 显示全部楼层
同样遇到这个问题,DMA第一次发送没有问题,后面的DMA就没有数据了,但是写SPI->DR寄存器可以正常发送
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-8-24 12:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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