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;
}