⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at45spiflash.c

📁 stm32 中使用SPI通讯写FLASH
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************
*          ATMEL的DATAFLASH操作函数库(FOR AT45DB161D)         *
*                                                               *
*                     作者:gxlujd(彩虹)                      *
*             最后修改时间:2007年2月18日(大年初一)           *
*                                                               *
*    感谢www.ouravr.com、阿莫和坛子里的哥们一直以来的热心帮助   *
*                                                               *
*    如果这些资源能帮到你,请保留以上这些信息,同时也请你把自   *
*    己的一些日常积累拿出来分享,这个世界需要更多的无私开源,   *
*    别让金钱和利益蒙住了内心的真诚,谢谢!                     *
*****************************************************************/

//#include "common.h"
#include "AT45SPIFLASH.h"
unsigned char DF_buffer[528];
#define SPI_FLASH_PageSize 528
#define ddd                111
#define Dummy_Byte1  0xA5
/*******************************************************************************
* Function Name  : SPI_FLASH_Init
* Description    : Initializes the peripherals used by the SPI FLASH driver.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
   
  /* Enable SPI1 and GPIOA clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
  
  /* Configure SPI1 pins: NSS, SCK, MISO and MOSI */
  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);

  /* Configure PA.4 as Output push-pull, used as Flash Chip select */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  /* SPI1 configuration */ 
  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_2;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);
  
  /* Enable SPI1  */
  SPI_Cmd(SPI1, ENABLE);   
}
/*******************************************************************************
* Function Name  : SPI_FLASH_ReadByte
* Description    : Reads a byte from the SPI Flash.
*                  This function must be used only if the Start_Read_Sequence
*                  function has been previously called.
* Input          : None
* Output         : None
* Return         : Byte Read from the SPI Flash.
*******************************************************************************/
u8 SPI_FLASH_ReadByte(u8 Dummy_Byte)
{
  return (SPI_FLASH_SendByte(Dummy_Byte));
}

/*******************************************************************************
* Function Name  : SPI_FLASH_SendByte
* Description    : Sends a byte through the SPI interface and return the byte 
*                  received from the SPI bus.
* Input          : byte : byte to send.
* Output         : None
* Return         : The value of the received byte.
*******************************************************************************/
u8 SPI_FLASH_SendByte(u8 byte)
{
  /* Loop while DR register in not emplty */
  //while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
 // /* Send byte through the SPI1 peripheral */
 // SPI_SendData(SPI1, byte);
   /* Send byte through the SPI1 peripheral */
  SPI_I2S_SendData(SPI1, byte);
  /* Wait to receive a byte */
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI1);
}

void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
	u32 i=0,j=0;
	u32 PageAddr=0;	
	PageAddr=WriteAddr/SPI_FLASH_PageSize;
	if((WriteAddr%SPI_FLASH_PageSize)==0)
	{
		i=NumByteToWrite/SPI_FLASH_PageSize;
		if(i)
		{
			for(j=0;j<i;j++)
			{
				DF_write_page(pBuffer,PageAddr);
				PageAddr++;
				pBuffer+=SPI_FLASH_PageSize;	
			 }
		}
		i=(NumByteToWrite%SPI_FLASH_PageSize);
		if(i)
		{
			DF_mm_to_buf(1,PageAddr);
			DF_write_buf(1,0,i,pBuffer);
			DF_buf_to_mm(1,PageAddr);
		}	
	}
	else 
	{
		DF_mm_to_buf(1,PageAddr);
		i = WriteAddr%SPI_FLASH_PageSize;
		j = i+NumByteToWrite;
		j = j/SPI_FLASH_PageSize;	
		if(j)
		{
			DF_write_buf(1,i,(SPI_FLASH_PageSize-i),pBuffer);
			DF_buf_to_mm(1,PageAddr);
			PageAddr++;
			pBuffer+=(SPI_FLASH_PageSize-i);
			for(;j!=0;j--)
			{
				if(j!=1)
				{
					DF_write_page(pBuffer,PageAddr);
					PageAddr++;
					pBuffer+=SPI_FLASH_PageSize;			
				}
				else 
				{
					DF_mm_to_buf(1,PageAddr);
					DF_write_buf(1,0,(i+NumByteToWrite)%SPI_FLASH_PageSize,pBuffer);
					DF_buf_to_mm(1,PageAddr);
				}	
			}
		}
		else 
		{
			DF_write_buf(1,i,NumByteToWrite,pBuffer);
			DF_buf_to_mm(1,PageAddr);	
		}
	};
}

void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{
	u32 i=0,j=0;
	u32 PageAddr=0;	
	PageAddr=ReadAddr/SPI_FLASH_PageSize;
	if((ReadAddr%SPI_FLASH_PageSize)==0)
	{
		i=NumByteToRead/SPI_FLASH_PageSize;
		if(i)
		{
			for(j=0;j<i;j++)
			{
				DF_read_page(pBuffer,PageAddr);
				PageAddr++;
				pBuffer+=SPI_FLASH_PageSize;	
			 }
		}
		i=(NumByteToRead%SPI_FLASH_PageSize);

		if(i)
		{
			DF_mm_to_buf(2,PageAddr);
			DF_read_buf(2,0,i,pBuffer);
		}	
	}
	else 
	{
		DF_mm_to_buf(2,PageAddr);
		i = ReadAddr%SPI_FLASH_PageSize;
		j = i+NumByteToRead;
		j = j/SPI_FLASH_PageSize;

		if(j)
		{
			
			DF_read_buf(2,i,(SPI_FLASH_PageSize-i),pBuffer);
			PageAddr++;
			pBuffer+=(SPI_FLASH_PageSize-i);
			for(;j!=0;j--)
			{
				if(j!=1)
				{
					DF_read_page(pBuffer,PageAddr);
					PageAddr++;
					pBuffer+=SPI_FLASH_PageSize;			
				}
				else 
				{
					DF_mm_to_buf(2,PageAddr);
					DF_read_buf(2,0,(i+NumByteToRead)%SPI_FLASH_PageSize,pBuffer);
				}	
			}  
		}
		else 
		{
			DF_read_buf(2,i,NumByteToRead,pBuffer);	
		}  
	};
}
void SPI_FLASH_StartReadSequence(u32 ReadAddr)
{
	#if SPI_FLASH_PageSize == 528
    u32 PAddr =0 ,BAddr=0;
    PAddr = (ReadAddr/SPI_FLASH_PageSize);
	BAddr = (ReadAddr%SPI_FLASH_PageSize);
	#endif
	DF_wait_busy();
	/* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();
  
  /* Send "Read from Memory " instruction */
  SPI_FLASH_SendByte(READ_SEQUENCE);
 #if SPI_FLASH_PageSize == 528
/* Send the 24-bit address of the address to read from -----------------------*/  
  /* Send ReadAddr high nibble address byte */
 SPI_FLASH_SendByte(( PAddr & 0x0fc0)  >> 6);
    /* Send ReadAddr medium nibble address byte */
  SPI_FLASH_SendByte(((PAddr &0x003f) << 2)| ((BAddr&0x0030)>>8));
   /* Send ReadAddr low nibble address byte */
  SPI_FLASH_SendByte(BAddr&0x000f);
  #else
   SPI_FLASH_SendByte((ReadAddr&0x003f0000)>>16);
   SPI_FLASH_SendByte((ReadAddr&0x0000ff00)>>8);
   SPI_FLASH_SendByte(ReadAddr&0x000000ff);	
   #endif
 // SPI_FLASH_SendByte(0x00);	
} 

/*******************************************************************************
* Function Name  : SPI_FLASH_SendHalfWord
* Description    : Sends a Half Word through the SPI interface and return the  
*                  Half Word received from the SPI bus.
* Input          : Half Word : Half Word to send.
* Output         : None
* Return         : The value of the received Half Word.
*******************************************************************************/
u16 SPI_FLASH_SendHalfWord(u16 HalfWord)
{
	//SPI_FLASH_CS_LOW();
  /* Loop while DR register in not emplty */
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

  /* Send Half Word through the SPI1 peripheral */
  SPI_I2S_SendData(SPI1, HalfWord);

  /* Wait to receive a Half Word */
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
 // SPI_FLASH_CS_HIGH();
  /* Return the Half Word read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI1);
  
}

/*******************************************************************************
* Function Name  : SPI_FLASH_SectorErase

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -