矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 1976|回复: 0

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

[复制链接]
     
发表于 2020-11-14 23:28:58 | 显示全部楼层 |阅读模式
timg.jpg

#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);           //读出存储数据

}
     
}
您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-28 09:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表