找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3626|回復(fù): 0
收起左側(cè)

單片機(jī)W25X16讀寫程序

[復(fù)制鏈接]
ID:148457 發(fā)表于 2016-11-17 14:00 | 顯示全部樓層 |閱讀模式
51單片機(jī)讀寫25X16程序,簡單昨懂
全部源碼下載:
51讀寫W25X16程序.rar (45.03 KB, 下載次數(shù): 54)

預(yù)覽:

  1. #include <intrins.h>  //包含位移和_nop_();
  2. #include "STC12C5A60S2.H"

  3. //***************************************************************

  4. void WriteDisable (void); //寫禁止
  5. void WriteEnable  (void); //寫允許
  6. unsigned char W25X_BUSY_OrNot (void); //判忙碌
  7. void W25X_ChipErase(void);  //片擦除
  8. void W25X_BlockErase(unsigned long Addre24);
  9. void W25X_SectorErase(unsigned long Addre24);        //擦除資料圖示的4KB空間
  10.                                                                                                                                                  //讀數(shù)據(jù)可以無限次,這里是由緩沖決定的大小
  11. void W25X_Flash_Byte_Read (unsigned long Addre24,unsigned char Quantity);//多字節(jié)讀FLASH(1~256)  -W25X32-000000-3FFF00(4M)-
  12. void W25X_Flash_Byte_Write(unsigned long Addre24,unsigned char Quantity); //往FLASH里寫一個或多個字節(jié)(小于256字節(jié))

  13. unsigned char Read_OneByte(void);          //從SPI收8位數(shù)
  14. void Send_OneByte(unsigned char DATA8);
  15. void InitSerial(void);  //串行口初始化.通信速率9600bps 在22.1184MHz晶振頻率        
  16. void Delay100ms(unsigned int _100ms); //100ms級延時

  17. //進(jìn)度: 發(fā)一個指令OK 寫允許OK 讀狀態(tài)OK 讀寫一個字節(jié)OK        

  18. unsigned char xdata Send_DATA[256];         //要發(fā)送的數(shù)據(jù)
  19. unsigned char xdata Recv_DATA[256];         //已接收的數(shù)據(jù), 如2個數(shù),則為Recv_DATA[0] Recv_DATA[1]
  20. unsigned char * Send_Pionter;
  21. unsigned char * Recv_Pionter;

  22. void main()         
  23.   {
  24.   unsigned char    BUSY;           //判忙碌
  25.   unsigned long Addre24;           //24位的Flash地址
  26.   unsigned char  x=0;
  27.   unsigned char  A;
  28.   unsigned char  B;
  29.   unsigned char  C;
  30.   unsigned long  D;

  31. //************************
  32.   A=0; B=0; C=0; D=0;
  33.   Delay100ms(2);
  34.   if(x)
  35.          {               
  36.          WriteDisable ();            //寫禁止

  37.      W25X_ChipErase();                  //片擦除
  38.      W25X_SectorErase(Addre24);  //4K擦除                                                         
  39.      W25X_BlockErase (Addre24);  //64K塊擦除

  40.      BUSY=W25X_BUSY_OrNot();        //判忙碌
  41.      W25X_Flash_Byte_Read (Addre24,21); //讀FLASH
  42.      W25X_Flash_Byte_Write(Addre24,21);  //寫入
  43.      }
  44. //*************************
  45.   P1M0=0xB0;
  46.   InitSerial();  //串行口初始化.通信速率9600bps 在22.1184MHz晶振頻率

  47.   Send_Pionter = &Send_DATA[0];  //發(fā)送指針取地址
  48.   Recv_Pionter = &Recv_DATA[0];  //接收指針取地址

  49.   for (D=0;D<256;D++)
  50.      {
  51.         Send_DATA[D]=D;
  52.         Recv_DATA[D]=0;
  53.          }

  54.   W25X_SectorErase(Addre24); Delay100ms (4); //4K擦除  
  55.                   
  56. //**************************

  57.   W25X_Flash_Byte_Write(0x000000,255);  //寫N個數(shù)
  58.   W25X_Flash_Byte_Read (0x000000,255);  //讀X個數(shù)
  59.   

  60.   while(1)
  61.     {

  62.    SBUF  =A;
  63.    while(TI==0);
  64.    TI=0;
  65.    SBUF  =Recv_DATA[A] ;
  66.    while(TI==0);
  67.    TI=0;
  68.    Delay100ms(1);
  69.    A++;

  70.         }                           
  71.   }        // End of Main

  72. //*******************END of Main****************************



  73. //   ----W25X系統(tǒng)Flash讀寫---SUNYA注----
  74. //sbit CS          = P1^4;        //選通  
  75. //sbit DIO         = P1^5;  //單片機(jī)輸出
  76. //sbit DO          = P1^6;        //FLASH輸出
  77. //sbit SCLK        = P1^7;        //時鐘
  78. //讀寫SPI口模擬模式3,時鐘平時為高電平

  79. //#define W25X_ReadStatus       0x05                //讀狀態(tài)寄存器
  80. //#define W25X_WriteStatus      0x01                //寫狀態(tài)寄存器
  81. //#define W25X_ReadDATA8        0x03                //普讀_數(shù)據(jù)
  82. //#define W25X_FastRead         0x0B                //快讀_數(shù)據(jù)
  83. //#define W25X_DualOutput       0x3B                //快讀_雙輸出
  84. //#define W25X_Write            0x02                //寫_數(shù)據(jù)_0~255個字節(jié)
  85. //#define W25X_S_Erase          0x20                //扇區(qū)擦除4KB
  86. //#define W25X_B_Erase          0xD8                //塊區(qū)擦除64KB
  87. //#define W25X_C_Erase          0xC7                //整片格式化
  88. //#define W25X_PowerDown        0xB9                //待機(jī)
  89. //#define W25X_PowerON_ID       0xAB                //開機(jī)或是讀ID
  90. //#define W25X_JEDEC_ID         0x9F                //十六位的JEDEC_ID
  91. //#define W25X_WriteEnable      0x06                //寫充許
  92. //#define W25X_WriteDisable     0x04                //寫禁止

  93. //#define W25X_BUSY             0x01                //FLASH忙
  94. //#define W25X_NotBUSY          0x00                //FLASH閑        這是自定義的

  95. //***************判BUSY********************************
  96. unsigned char W25X_BUSY_OrNot (void) //在讀和寫之前得先判斷FLASH是否BUSY
  97.    {                                         //BUSY的原因是擦除,或是連續(xù)讀寫
  98.    unsigned char k;          //如果沒有以上方式,不必判定可以寫讀  

  99.    SCLK=1;
  100.    _nop_();
  101.    CS=0;
  102.    Send_OneByte(W25X_ReadStatus);  //讀狀態(tài)寄存器
  103.    k=Read_OneByte();  //讀一個字節(jié)
  104.    k=k&0x01;
  105.    CS=1;_nop_();
  106.    SCLK=1;
  107.    if(k)return (W25X_BUSY);
  108.    else return (W25X_NotBUSY);
  109.    }        //end of check BUSY
  110. //***********************************************
  111. void W25X_Flash_Byte_Write(unsigned long Addre24,unsigned char Quantity)    //往FLASH里寫一個或多個字節(jié)(小于255)
  112.    {                                                 //連續(xù)寫的時候,地址最后八位必須從00開始寫                 *如果256個字節(jié)都讀滿或?qū)憹M,三字節(jié)地址最后一個字節(jié)必須為0*
  113.    unsigned char Addre3;         //否則當(dāng)?shù)刂吩竭^分面時,會從本頁的00從新開始,造成錯寫
  114.    unsigned char Addre2;         //^^現(xiàn)在本函數(shù)沒啟用連寫連讀
  115.    unsigned char Addre1;
  116.    unsigned char J;   //計字節(jié)數(shù)
  117.    unsigned char x;

  118.    while(W25X_BUSY_OrNot ());  //判BUSY        等到Flash閑才能操作

  119.    WriteEnable();   //寫允許
  120.    SCLK=1;
  121.    Addre1=Addre24;
  122.    Addre24=Addre24>>8;
  123.    Addre2=Addre24;
  124.    Addre24=Addre24>>8;
  125.    Addre3=Addre24;                    //把地址拆開來
  126.    
  127.    CS=0;
  128.    Send_OneByte(W25X_Write);  //命令
  129.    Send_OneByte(Addre3);
  130.    Send_OneByte(Addre2);
  131.    Send_OneByte(Addre1);

  132.    for (J=0;J<Quantity;J++)
  133.      {
  134.      Send_OneByte(Send_DATA[J]); //寫字節(jié)
  135.            }

  136.    CS=1;
  137.    _nop_();_nop_();
  138.    SCLK=1;
  139.    for(x=0;x<200;x++) //延時一點點
  140.      {
  141.      _nop_();_nop_();
  142.      }
  143.    Addre24=0;  //地址清0

  144.    }         //寫FLASH結(jié)束

  145. //***********************************************

  146. void W25X_Flash_Byte_Read (unsigned long Addre24,unsigned char Quantity)  //從Flash里讀出小于256字節(jié)數(shù)
  147.    {
  148.    unsigned char xdata DATA8[256];  //要返回的字節(jié)
  149.    unsigned char * DATA;  //定義一個指針

  150.    unsigned char J;         //計字節(jié)數(shù)
  151.    unsigned char Addre3;
  152.    unsigned char Addre2;
  153.    unsigned char Addre1;
  154.    
  155.    while(W25X_BUSY_OrNot ());  //判BUSY

  156.    DATA=&DATA8[0]; //指針指向DATA8[256]

  157.    Addre1=Addre24;
  158.    Addre24=Addre24>>8;
  159.    Addre2=Addre24;
  160.    Addre24=Addre24>>8;
  161.    Addre3=Addre24;                 //把地址拆開來
  162.    
  163.    CS=0;
  164.    Send_OneByte(W25X_ReadDATA8);//命令讀
  165.    Send_OneByte(Addre3);
  166.    Send_OneByte(Addre2);
  167.    Send_OneByte(Addre1);

  168.    for (J=0;J<Quantity;J++)
  169.      {
  170.      Recv_DATA[J]=Read_OneByte();         //讀一個字節(jié)
  171.          }

  172.    CS=1;
  173.    _nop_();_nop_();
  174.    SCLK=1;
  175.    _nop_();_nop_();
  176.    Addre24=0;  //地址清0
  177.    }          //讀FLASH結(jié)束

  178. //*********************************************** OK

  179. void Send_OneByte(unsigned char DATA8) //從SPI發(fā)8位數(shù)
  180.    {                                                                  //上升沿寫入
  181.    unsigned char x;
  182.      
  183.    for (x=0;x<8;x++)
  184.      {
  185.          SCLK=0;
  186.          if(DATA8&0x80)DIO=1;
  187.          else DIO=0;
  188.          SCLK=1;
  189.          DATA8=DATA8<<1;
  190.          }
  191.        //發(fā)完后SCLK為1
  192.    }  //end of Send_OneByte

  193. //***********************************************  OK
  194. unsigned char Read_OneByte(void)     //從SPI收8位數(shù)
  195.    {                                                         //下降沿輸出
  196.    unsigned char DATA8;
  197.    unsigned char x;

  198.    SCLK=1;
  199.    DATA8=0x00;
  200.    for (x=0;x<8;x++)
  201.      {
  202.          _nop_();
  203.          SCLK=0;
  204.          DATA8=DATA8<<1;
  205.          if(DO)DATA8=DATA8|0x01;
  206.          SCLK=1;         
  207.          }
  208.    return (DATA8);
  209.     //完成后SCLK=1
  210.    }//end of Read_OneByte

  211. //**************片擦除 (MAX_80S)****************** OK
  212. void W25X_ChipErase(void)
  213.   {
  214.   //BUSY ?
  215.   WriteEnable();   //寫允許
  216.   SCLK=1;
  217.   CS=0;
  218.   Send_OneByte(W25X_C_Erase);//整片擦除命令
  219.   CS=1;          //從CS=1時開始執(zhí)行擦除
  220.   SCLK=1;  
  221.   }

  222. //*************** 4K扇擦除************************ OK
  223. void W25X_SectorErase(unsigned long Addre24)        //擦除資料圖示的4KB空間
  224.   {
  225.    //判BUSY或許放這里
  226.    unsigned char Addre3;
  227.    unsigned char Addre2;
  228.    unsigned char Addre1;

  229.    WriteEnable();   //寫允許
  230.    Addre1=Addre24;
  231.    Addre24=Addre24>>8;
  232.    Addre2=Addre24;
  233.    Addre24=Addre24>>8;
  234.    Addre3=Addre24;                 //把地址拆開來

  235.    SCLK=1;
  236.    CS=0;
  237.    Send_OneByte(W25X_S_Erase);//整扇擦除命令
  238.    Send_OneByte(Addre3);
  239.    Send_OneByte(Addre2);
  240.    Send_OneByte(Addre1);
  241.    CS=1;
  242.    _nop_();
  243.    SCLK=1;
  244.    _nop_();_nop_();
  245.    Addre24=0;  //地址清0
  246.   }
  247. //*************** 64K頁/塊擦除************************* OK
  248. void W25X_BlockErase(unsigned long Addre24)        //擦除資料圖示的64KB空間
  249.   {
  250.    //判BUSY或許放這里
  251.    unsigned char Addre3;
  252.    unsigned char Addre2;
  253.    unsigned char Addre1;

  254.    WriteEnable();   //寫允許
  255.    Addre1=Addre24;
  256.    Addre24=Addre24>>8;
  257.    Addre2=Addre24;
  258.    Addre24=Addre24>>8;
  259.    Addre3=Addre24;                 //把地址拆開來

  260.    SCLK=1;
  261.    CS=0;
  262.    Send_OneByte(W25X_B_Erase);//整扇擦除命令
  263.    Send_OneByte(Addre3);
  264.    Send_OneByte(Addre2);
  265.    Send_OneByte(Addre1);
  266.    CS=1;
  267.    _nop_();_nop_();
  268.    SCLK=1;
  269.    _nop_();_nop_();
  270.    Addre24=0;  //地址清0
  271.   }
  272. //*************** 寫允許 ****************************  OK
  273. void WriteEnable  (void)
  274.    {
  275.    SCLK=1;
  276.    CS=0;
  277.    Send_OneByte(W25X_WriteEnable);  
  278.    CS=1;
  279.    SCLK=1;
  280.    }
  281. //*************** 寫禁止 ****************************        OK
  282. void WriteDisable (void)
  283.    {
  284.    SCLK=1;
  285.    CS=0;
  286.    Send_OneByte(W25X_WriteDisable);  
  287.    CS=1;
  288.    SCLK=1;
  289.    }

  290. //******************************************************** OK
  291. void Delay100ms(unsigned int _100ms) //100ms級延時
  292. {
  293.    unsigned char n,i,ms,loop;
  294.    for(loop=12;loop>0;loop--)  //STC12C5412AD為快速單片機(jī),此100ms延時要快6倍
  295.      {  ms=_100ms;            //晶體為11.0592MHz
  296.         for(;ms>0;ms--)
  297.           for(n=145;n>0;n--)
  298.             for(i=251;i>0;i--)_nop_();
  299.      }
  300. }


  301. //***************************************//串行口初始化                OK
  302. void InitSerial(void)  //串行口初始化.通信速率9600bps 在22.1184MHz晶振頻率
  303. {
  304.         SCON = 0x50;
  305.         BRT  = 250;
  306.         AUXR = 0x11;                        //使用獨立波特率發(fā)生器
  307.         AUXR1= 0x80;
  308.         ES=1;
  309.         EA=1;
  310. /*   
  311.                 TR1=0;
  312.     ET1=0;            //定時器1禁止中斷
  313.     TMOD=TMOD&0xCF;
  314.     TMOD=TMOD|0x20;   //通信方式2
  315.     TH1=0xFF;         //波特率:bps
  316.     TL1=0xFF;         //1位起始位,8位數(shù)據(jù)位,2位停止位,無校驗
  317.     SCON=0xD8;
  318.     PCON=0x80;
  319.     TR1=1;                   //開啟定時
  320.     ES=1;
  321. */
  322.     //IE=IE|0x90;    //開中斷,允許串口中斷
  323. }
  324. //***************************************************************
復(fù)制代碼

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

相關(guān)帖子

回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表