STM32读写FPGA存储器EPCS器件(EPCS1、EPCS4)

EPCS器件,此处主要是EPCS1、EPCS4,EPCS1、EPCS4其实是一种特殊的Flash,Altera称之为稳定性比较高的SPI FLASH。

如果我们使用一些万能编程器测试EPCS的话,会被认为是M25PXX系列的,比如说EPCS1被认为M25P10A的器件。

此处使用了STM32,两路SPI,SPI1和SPI2来分别进行读和进行写。

初始化函数如下

void ReadSPIInit()		//SPI1
{
	
		GPIO_InitTypeDef GPIO_InitStructure;
		SPI_InitTypeDef  SPI_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1, ENABLE);
		
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			//NCS
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
	  //GPIO_PinRemapConfig(GPIO_Remap_SPI1,ENABLE); 
	  /* Configure SPI1 pins: SCK, MISO and MOSI */
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA, &GPIO_InitStructure);

	  /* SPI1 configuration */
	  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_16;
		SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
		SPI_Init(SPI1,&SPI_InitStructure);

	  /* Enable SPI1  */
	  SPI_Cmd(SPI1, ENABLE);
	

}
void WriteSPIInit()	//SPI2
{
		GPIO_InitTypeDef GPIO_InitStructure;
		SPI_InitTypeDef  SPI_InitStructure;

	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

		RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);	
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			//NCS			PB12接1,PB13接6,PB14接2,PB15接5,GND接4,VCC接3 7 8
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	
	  //GPIO_PinRemapConfig(GPIO_Remap_SPI1,ENABLE); 
	  /* Configure SPI1 pins: SCK, MISO and MOSI */
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;			//adsi接mosi,data接miso
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_Init(GPIOB, &GPIO_InitStructure);

	  /* SPI1 configuration */
	  SPI_Cmd(SPI2, 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_32;
		SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
		SPI_Init(SPI2,&SPI_InitStructure);

	  /* Enable SPI1  */
	  SPI_Cmd(SPI2, ENABLE);
}
之后是底层操作函数,使用库函数的SPI读写进行的封装的:

unsigned char SPI1_ReadWriteByte(unsigned char TxData)
{		
	unsigned char retry=0;				 
	while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET)
	{
		retry++;
		if(retry>200)
            return 0;
	}			  

	SPI_I2S_SendData(SPI1,TxData);
    
	retry=0;
    
	while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET)
	{
		retry++;
		if(retry>200)
            return 0;
	}	  						    
	return SPI_I2S_ReceiveData(SPI1);		    
}
unsigned char SPI2_ReadWriteByte(unsigned char TxData)
{		
	unsigned char retry=0;				 
	while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE) == RESET) 
	{
		retry++;
		if(retry>200)
            return 0;
	}			  

	SPI_I2S_SendData(SPI2,TxData);
    
	retry=0;
    
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET)
	{
		retry++;
		if(retry>200)
            return 0;
	}	  						    
	return SPI_I2S_ReceiveData(SPI2);				    
}

第一部是读id,epcs1的id是0x10,epcs2的是0x12

u8 ReadID1()
{
	u8 id;
	CL_CS1;
	SPI1_ReadWriteByte(0xab);		//读id指令
	
	SPI1_ReadWriteByte(0xff);		//三个虚拟字节
	SPI1_ReadWriteByte(0xff);		
	SPI1_ReadWriteByte(0xff);
	id=SPI1_ReadWriteByte(0xff);		//读出id
	SE_CS1;
	if(id==0x12)
		return 1;
	else
		return 0;

}
之后是检查忙函数,读status函数,去除写保护以及写使能函数

u8 Whilebusy()//检查是否忙
{
	CL_CS2;
	SPI2_ReadWriteByte(0x5);		//读状态指令
	while(SPI2_ReadWriteByte(0xff)&0x01)		//wip=1的时候正在工作,=0的时候完成工作
	SE_CS2;
}
u8 ReadStatus()//检查是否忙
{
	u8 sta;
	CL_CS2;
	SPI2_ReadWriteByte(0x5);		//读状态指令
	sta=SPI2_ReadWriteByte(0xff);		//wip=1的时候正在工作,=0的时候完成工作
	SE_CS2;
	return sta;
}
void DisableProt2()//写操作和擦出操作前执行WEL置1,同时清除写保护
{
	CL_CS2;
	SPI2_ReadWriteByte(0x1);		//写状态指令
	SPI2_ReadWriteByte(0x02);		//WEL置1,其他置0;
	SE_CS2;	
	delay_ms(30);
}
void EnalbeProt1()	//开启写保护,防止误写
{
	CL_CS1;
	SPI1_ReadWriteByte(0x1);		//写状态指令
	SPI1_ReadWriteByte(0x1c);		//WEL置1,其他置0;
	SE_CS1;	
}
void WriteE()
{
	CL_CS2;
	SPI2_ReadWriteByte(0x6);		//写状态指令
	SE_CS2;	
	delay_ms(30);
}

之后是读函数和写函数,注意写函数一次写的不能超过256


void Readbytes2(u32 add,u8 * data,u16 len)
{
	u16 i;
	CL_CS2;
	SPI2_ReadWriteByte(0x3);		//读字节指令
	SPI2_ReadWriteByte(add>>16);		//地址
	SPI2_ReadWriteByte(add>>8);		//地址	
	SPI2_ReadWriteByte(add);		//地址
	for(i=0;i<len;i++)
	{
		data[i]=SPI2_ReadWriteByte(0xff);
	}
	SE_CS2;		
}
void Writebytes2(u32 add,u8 * data,u16 len)
{
	u16 i;
	CL_CS2;
	SPI2_ReadWriteByte(0x2);		//写字节指令
	SPI2_ReadWriteByte(add>>16);		//地址
	SPI2_ReadWriteByte(add>>8);		//地址	
	SPI2_ReadWriteByte(add);		//地址
	for(i=0;i<len;i++)
	{
		SPI2_ReadWriteByte(data[i]);
	}
	SE_CS2;	
}

















  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值