分立元件 发表于 2020-11-14 23:28:58

【分享】51单片机读写25Q80测试程序



#include <reg52.h>
#include <intrins.h>
unsigned long Addre24;    //24位的Flash地址

sbit CS          = P1^0; //选通
sbit SCLK      = P1^1; //时钟
sbit DIO         = P1^2;//输入
sbit DO          = P1^3; //输出

void Send_OneByte(unsigned char DATA8) //从SPI发8位数
{                                        //上升沿写入
   unsigned char x;
   
   for (x=0;x<8;x++)
    {
if(DATA8&0x80)
   DIO=1;
else
DIO=0;
DATA8=DATA8<<1;
SCLK=0;
SCLK=1;
}
}

unsigned char Read_OneByte(void)   //从SPI收8位数
   {                                 //下降沿输出
   unsigned char DATA8;
   unsigned char x;
   SCLK=1;
   for (x=0;x<8;x++)
   {
SCLK=1;
SCLK=0;
DATA8=(DATA8<<1)|DO;
}
   return (DATA8);
}
//*************** 写允许 ****************************OK
void WriteEnable(void)
{
   CS=0;
   Send_OneByte(0x06);
   CS=1;
}
//*************** 写禁止 **************************** OK
void WriteDisable (void)
{
   CS=0;
   Send_OneByte(0x04);
   CS=1;
}
//***************判BUSY********************************
unsigned char W25X_BUSY_OrNot (void) //在读和写之前得先判断FLASH是否BUSY
   {                                 //BUSY的原因是擦除,或是连续读写
   unsigned char k;                  // 如果没有以上方式,不必判定可以写读
                                    //   PCA0CPH2 = 0x00;
   SCLK=1;
   _nop_();
   CS=0;
   Send_OneByte(0x05);//读状态寄存器
   k=Read_OneByte();//读一个字节
   k=k&0x01;
   CS=1;_nop_();
   SCLK=1;
   if(k)return (0x01);
   else return (0x00);
   }               
void W25X_Flash_Byte_Write(unsigned long Addre24,unsigned char dat)
   {      
   
   while(W25X_BUSY_OrNot ());//判BUSY 等到Flash闲才能操作

   WriteEnable();                //写允许
                                 //把地址拆开来
   CS=0;
   Send_OneByte(0x02);         //命令
   Send_OneByte(Addre24>>16);
   Send_OneByte(Addre24>>8);
   Send_OneByte(Addre24);
   Send_OneByte(dat);
   CS=1;
   WriteDisable ();
   }//写FLASH结束


unsigned char W25X_Flash_Byte_Read (unsigned long Addre24)//从Flash里读出小于256字节数
{
unsigned char temp;

   while(W25X_BUSY_OrNot ());//判BUSY

   WriteEnable();

   CS=0;
   Send_OneByte(0x03);//命令读
   Send_OneByte(Addre24>>16);
   Send_OneByte(Addre24>>8);
   Send_OneByte(Addre24);
   temp=Read_OneByte();
   CS=1;
   WriteDisable ();
   return temp;
}
//**************片擦除 (MAX_80S)****************** OK
void W25X_ChipErase(void)
{
WriteEnable();   //写允许
SCLK=1;
CS=0;
Send_OneByte(0xc7);//整片擦除命令
CS=1;            //从CS=1时开始执行擦除
}

//*************** 4K扇擦除************************ OK
void W25X_SectorErase(unsigned long Addre24) //擦除资料图示的4KB空间
{
   unsigned char Addre3;
   unsigned char Addre2;
   unsigned char Addre1;

   WriteEnable();   //写允许
   Addre1=Addre24;
   Addre24=Addre24>>8;
   Addre2=Addre24;
   Addre24=Addre24>>8;
   Addre3=Addre24;   //把地址拆开来

   SCLK=1;
   CS=0;
   Send_OneByte(0x20);//整扇擦除命令
   Send_OneByte(Addre3);
   Send_OneByte(Addre2);
   Send_OneByte(Addre1);
   CS=1;
}
                     //64K页/块擦除
void W25X_BlockErase(unsigned long Addre24) //擦除资料图示的64KB空间
{
   unsigned char Addre3;
   unsigned char Addre2;
   unsigned char Addre1;

   WriteEnable();   //写允许
   Addre1=Addre24;
   Addre24=Addre24>>8;
   Addre2=Addre24;
   Addre24=Addre24>>8;
   Addre3=Addre24;   //把地址拆开来

   SCLK=1;
   CS=0;
   Send_OneByte(0xd8);//整扇擦除命令
   Send_OneByte(Addre3);
   Send_OneByte(Addre2);
   Send_OneByte(Addre1);
   CS=1;

}

void main()
{
    //W25X_ChipErase();            //片擦除
    W25X_SectorErase(0);                  //4K擦除      
    //W25X_BlockErase (Addre24);      //64K块擦除
        W25X_Flash_Byte_Write(0,0x01);//写入存存储据
    while(W25X_BUSY_OrNot ());
while(1)      
{

P0=W25X_Flash_Byte_Read (0);           //读出存储数据

}
   
}
页: [1]
查看完整版本: 【分享】51单片机读写25Q80测试程序