📄 mem25vf.c
字号:
/**********************************************************************************************
* 当前版本:2.1.2
* 作 者:陈兆红
* 完成日期:2005年10月15日
**********************************************************************************************/
#include "mem25vf.h"
//===========================================================================
//SPI初始化,设置输入输出、SPI时钟等
//===========================================================================
void SPI_Init(void)
{
/* Set MOSI and SCK output, all others input */
PORTB=0xff;
DDRB=0xBF;
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = 0x52;
SPSR = 0x00;
CE11;
CE21;
return;
}
//===========================================================================
//SPI 发送程序
//===========================================================================
void SPI_Send(uchar cData)
{
uint i;
i=0x0fff;
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while( (!(SPSR & 0x80)) && (i--)) ;
SPSR = 0x00;
return;
}
//===========================================================================
//SPI接收程序,通过发送任意虚字节产生SPI时钟
//===========================================================================
uchar SPI_Receive(void)
{
uchar i;
SPI_Send(0xFF); //send a dummy byte to generate spi's clock
DelayUs(2);
i = SPDR; // play data from shift register
return i;
}
//===========================================================================
//读取flash状态
//===========================================================================
uchar Read_Status(uchar chipcs)
{
uchar temp;
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
//read command
SPI_Send(MEM_READ_STATUS);
//get data
temp=SPI_Receive();
CE11;
CE21;
return temp;
}
//===========================================================================
//写状态
//===========================================================================
void Write_Status(uchar status,uchar chipcs)
{
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
SPI_Send(MEM_ENABLE_STATUS_WRITE);
CE11;
CE21;
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
SPI_Send(MEM_WRITE_STATUS);
SPI_Send(status);
CE11;
CE21;
return ;
}
//===========================================================================
//写允许
//===========================================================================
void Write_Enable(uchar chipcs)
{
//WP11;
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
SPI_Send( MEM_WRITE_ENABLE );
CE11;
CE21;
}
//===========================================================================
//写禁止
//===========================================================================
void Write_Disable(uchar chipcs)
{
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
SPI_Send( MEM_WRITE_DISABLE );
CE11;
CE21;
}
//读一个字节
uchar Mem_Read(ulong address,uchar chipcs)
{
uchar temp;
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
//read command
SPI_Send(MEM_READ);
//address to read
temp=(uchar)((address&0xff0000)>>16);
SPI_Send(temp);
temp=(uchar)((address&0xff00)>>8);
SPI_Send(temp);
temp=(uchar)(address&0xff);
SPI_Send(temp);
//get data
temp=SPI_Receive();
CE11;
CE21;
DelayUs(1);
return temp;
}
//===========================================================================
//===========================================================================
void Mem_Read1(ulong address,uchar chipcs,uchar n,uchar *tp)
{
uchar i,temp;
if( chipcs == 1 )
{ CE10; CE21;}
else
{ CE20; CE11; }
//read command
SPI_Send(MEM_READ);
//address to read
temp=(uchar)((address&0xff0000)>>16);
SPI_Send(temp);
temp=(uchar)((address&0xff00)>>8);
SPI_Send(temp);
temp=(uchar)(address&0xff);
SPI_Send(temp);
//get data
for(i=0;i<n;i++) tp[i]=SPI_Receive();
CE11;
CE21;
DelayUs(1);
return ;
}
//===========================================================================
//===========================================================================
void read_flash(ulong addr,uchar chip_cs,uchar n,uchar *p)
{
Mem_Read1(addr,chip_cs,n,p);
}
//===========================================================================
//===========================================================================
uchar wait_idle(uchar chipcs)
{
uchar i,temp;
for ( i=0; i<0xff; i++ ){
temp=Read_Status(chipcs);
if( !(temp & 0x01) ) return 1;
DelayMs(1);
}
return 0;
}
//===========================================================================
//扇区擦除
//===========================================================================
uchar Sector_Erase1(ulong address,uchar chipcs)
{
uchar temp;
//uchar i;
if(wait_idle(chipcs)==0)
return 0;
Write_Status(0x00,chipcs);
Write_Enable(chipcs);
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
//read command
SPI_Send(MEM_SECTOR_ERASE);
//address to read
temp=(uchar)((address&0xff0000)>>16);
SPI_Send(temp);
temp=(uchar)((address&0xff00)>>8);
SPI_Send(temp);
temp=(uchar)(address&0xff);
SPI_Send(temp);
CE11;
CE21;
if(wait_idle(chipcs)==0)
return 0;
Write_Disable(chipcs);
DelayMs(12); //DelayMs(12);
return 1;
}
//===========================================================================
//
//===========================================================================
void Sector_Erase(ulong address,uchar chipcs)
{
uchar i=0;
while(1)
{
if(Sector_Erase1(address,chipcs)==1)
return;
else
i++;
if(i>10)
return ;
DelayMs(10);
}
}
//===========================================================================
//===========================================================================
//整片擦除
uchar Chip_Erase1(uchar chipcs){
if(wait_idle(chipcs)==0) return 0;
Write_Status(0x00,chipcs);
Write_Enable(chipcs);
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
//read command
SPI_Send(MEM_CHIP_ERASE);
CE11;
CE21;
if(wait_idle(chipcs)==0) return 0;
Write_Disable(chipcs);
DelayMs(83);
return 1;
}
//===========================================================================
//===========================================================================
void Chip_Erase(uchar chipcs)
{
uchar i=0;
while(1)
{
if(Chip_Erase1(chipcs)==1) return ;
else i++;
if(i>10) return ;
DelayMs(20);
}
}
//===========================================================================
//连续字节写入
//===========================================================================
uchar AAI_Write1(uchar num,ulong address,uchar *sData,uchar chipcs)
{
uchar temp;
uchar i;
if(wait_idle(chipcs)==0) return 0;
Write_Status(0x00,chipcs);
if(wait_idle(chipcs)==0) return 0;
Write_Enable(chipcs);
if(wait_idle(chipcs)==0) return 0;
if ( chipcs == 1 )
{
CE10;
CE21;
}
else
{
CE20;
CE11;
}
//read command
SPI_Send(MEM_AAI_WRITE);
//address to read
temp=(uchar)((address&0xff0000)>>16);
SPI_Send(temp);
temp=(uchar)((address&0xff00)>>8);
SPI_Send(temp);
temp=(uchar)(address&0xff);
SPI_Send(temp);
for ( i=0; i<num; i++ )
{
SPI_Send(sData[i]);
CE21;
DelayUs(20); //byte program time,max 20uS
CE20;
if( i<(num-1) )
SPI_Send(MEM_AAI_WRITE); //AAI mode
}
Write_Disable(chipcs);
CE11;
CE21;
DelayMs(2);
return 1;
}
//===========================================================================
// 连续往 Flash 中写入数据,
//===========================================================================
void AAI_Write(uchar num,ulong address,uchar *sData,uchar chipcs)
{
uchar i=0;
while(1)
{
if(AAI_Write1(num,address,sData,chipcs)==1)
return ;
else
i++;
if(i>10)
return ;
DelayMs(5);
}
}
//===========================================================================
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -