欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11279|回復: 9
打印 上一主題 下一主題
收起左側

FLASH寫入和讀出的數據不一樣,求助

[復制鏈接]
跳轉到指定樓層
樓主
ID:87842 發表于 2015-8-7 14:47 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
用51模擬SPI寫FLASH,數據讀出和寫入不同。附上代碼:

#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
unsigned char ID1,ID2;
unsigned char    BUSY;    //判忙碌
unsigned long Addre24;    //24位的Flash地址


//   ----W25X系統Flash讀寫---SUNYA注----
sbit CS          = P3^7; //選通  
sbit DIO         = P3^6;  //單片機輸出
sbit DO          = P3^5; //FLASH輸出
sbit SCLK        = P3^4; //時鐘

#define W25X_ReadStatus       0x05  //讀狀態寄存器
#define W25X_WriteStatus      0x01  //寫狀態寄存器
#define W25X_ReadDATA8        0x03  //普讀_數據
#define W25X_FastRead         0x0B  //快讀_數據
#define W25X_Write            0x02  //寫_數據_0~255個字節
#define W25X_S_Erase          0x20  //扇區擦除4KB
#define W25X_B_Erase          0xD8  //塊區擦除64KB
#define W25X_C_Erase          0xC7  //整片格式化
#define W25X_PowerDown        0xB9  //待機
#define W25X_PowerON_ID       0xAB  //開機或是讀ID
#define W25X_READ_ID    0x90  //讀ID
#define W25X_JEDEC_ID         0x9F  //十六位的JEDEC_ID
#define W25X_WriteEnable      0x06  //寫充許
#define W25X_WriteDisable     0x04  //寫禁止
#define W25X_BUSY             0x01  //FLASH忙
#define W25X_NotBUSY          0x00  //FLASH閑 這是自定義的

//*********************************************** OK
void Send_OneByte(unsigned char DATA8) //從SPI發8位數
{                 //上升沿寫入
   unsigned char x;
    SCLK=0;
   for (x=0;x<8;x++)
    {
//  DATA8=DATA8<<1;
  SCLK=0;
  _nop_();  
  if(DATA8&0x80)
   DIO=1;
else
  DIO=0;
  SCLK=1;
  DATA8=DATA8<<1;
  _nop_();
  }
}
//***********************************************  OK
unsigned char Read_OneByte(void)     //從SPI收8位數
   {               //下降沿輸出
   unsigned char DATA8;
   unsigned char x;
//   DATA8=0;
//   DO=0;
   SCLK=1;
   for (x=0;x<8;x++)
     {
  SCLK=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  SCLK=0;  
  DATA8=(DATA8<<1)|DO;  
  }
   return (DATA8);
}
//*************** 寫允許 ****************************  OK
void WriteEnable  (void)
{
   CS=0;
   Send_OneByte(W25X_WriteEnable);  
   CS=1;
}
//*************** 寫禁止 **************************** OK
void WriteDisable (void)
{
   CS=0;
   Send_OneByte(W25X_WriteDisable);  
   CS=1;
}
//***************判BUSY********************************
unsigned char W25X_BUSY_OrNot (void) //在讀和寫之前得先判斷FLASH是否BUSY
   {             //BUSY的原因是擦除,或是連續讀寫
   unsigned char k;          //如果沒有以上方式,不必判定可以寫讀  
//   PCA0CPH2 = 0x00;
   SCLK=1;
   _nop_();
   CS=0;
   Send_OneByte(W25X_ReadStatus);  //讀狀態寄存器
   k=Read_OneByte();  //讀一個字節
   k=k&0x01;
   CS=1;_nop_();
   SCLK=1;
   if(k)return (W25X_BUSY);
   else return (W25X_NotBUSY);
   } //end of check BUSY
//***********************************************
void W25X_Flash_Byte_Write(unsigned long Addre24,unsigned char dat)
   {      
uchar addr1,addr2,addr3;
addr3=Addre24>>16;
addr2=Addre24>>8;
addr1=Addre24;     
   while(W25X_BUSY_OrNot ()  );  //判BUSY 等到Flash閑才能操作
   WriteEnable();   //寫允許
      //把地址拆開來
   
   CS=0;
   Send_OneByte(W25X_Write);  //命令
   Send_OneByte(addr3);
   Send_OneByte(addr2);
   Send_OneByte(addr1);
   Send_OneByte(dat);
   CS=1;   
   WriteDisable ();
   }  //寫FLASH結束
//***********************************************
unsigned char W25X_Flash_Byte_Read (unsigned long Addre24)  //從Flash里讀出小于256字節數
{
unsigned char temp;   
   uchar addr1,addr2,addr3;
addr3=Addre24>>16;
addr2=Addre24>>8;
addr1=Addre24;
//   while(W25X_BUSY_OrNot ());  //判BUSY
   WriteEnable();
   
   CS=0;
   Send_OneByte(W25X_ReadDATA8);//命令讀
   Send_OneByte(addr3);
   Send_OneByte(addr2);
   Send_OneByte(addr1);
temp=Read_OneByte();
   CS=1;
   WriteDisable ();  
   return temp;
}
//**************片擦除 (MAX_80S)****************** OK
void W25X_ChipErase(void)
  {
  WriteEnable();   //寫允許
  SCLK=1;
  CS=0;
  Send_OneByte(W25X_C_Erase);//整片擦除命令
  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(W25X_S_Erase);//整扇擦除命令
   Send_OneByte(Addre3);
   Send_OneByte(Addre2);
   Send_OneByte(Addre1);
   CS=1;
  }
//*************** 64K頁/塊擦除************************* OK
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(W25X_B_Erase);//整扇擦除命令
   Send_OneByte(Addre3);
   Send_OneByte(Addre2);
   Send_OneByte(Addre1);
   CS=1;
}

//******************************************************** OK
void Delay_ms(unsigned int ms) //ms級延時
{
  unsigned char i;
  while(ms--)
   for(i=0;i<110;i++);
}
void  W25X_Flash_ID_Read ()
{
   while(W25X_BUSY_OrNot ());  //判BUSY
   
   CS=0;
   Send_OneByte(W25X_READ_ID);
   Send_OneByte(0x00);
   Send_OneByte(0x00);
   Send_OneByte(0x00);
   ID1=Read_OneByte();  
   ID2=Read_OneByte();
   CS=1;   
}  
unsigned char W25X_Status ()
{            
   unsigned char k;           
   SCLK=1;
   _nop_();
   CS=0;
   Send_OneByte(W25X_ReadStatus);  //讀狀態寄存器
   k=Read_OneByte();  //讀一個字節
   CS=1;
   return k;
}
void W25X_Flash_Status_Write()
{      
   while(W25X_BUSY_OrNot ()  );  //判BUSY 等到Flash閑才能操作
   WriteEnable();   //寫允許
   SCLK=1;     
   
   CS=0;
   Send_OneByte(W25X_WriteStatus);  //命令
   Send_OneByte(0x80);
   CS=1;
}
void main()  
  {
  TMOD=0X20;
  TH1=0XFD;
        TL1=0XFD;
        TR1=1;
        REN=1;
        SM0=0;
        SM1=1;
//     W25X_ChipErase();           //片擦除
   W25X_SectorErase(0);   //4K擦除         
////   W25X_BlockErase (Addre24);   //64K塊擦除
     W25X_Flash_Byte_Write(0,0xaa);  //存儲數據
//  while(W25X_BUSY_OrNot ());
while(1)      
{
//  W25X_Flash_Byte_Write(0xaaaaaa,0xaa);
  Delay_ms(100);
//  CS=0;
//  Send_OneByte(0xaa);
//  while(!RI);
//  RI=0;
  SBUF=W25X_Flash_Byte_Read (0);
  while(!TI);
  TI=0;
}
      
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:87849 發表于 2015-8-7 16:12 | 只看該作者
主要是什么不一樣,說的詳細點
回復

使用道具 舉報

板凳
ID:87842 發表于 2015-8-10 10:10 | 只看該作者
我做了一部分測試,
輸入        輸出
0xa0        0x81
0xb0        0xa1
0xc0        0xc0
0xd0        0xc1
0x20        0x01
0x0a        0x03
0x0b        0x07
0x0c        0x09
0x0d        0x0b
0x0e        0x0d
還有就是輸入0xf0~0xf9 ,0xfb~0xff,0x0f~0x09,0x0b~0x0f,,,輸出都對
現象就是這樣
回復

使用道具 舉報

地板
ID:144225 發表于 2016-10-24 14:51 | 只看該作者
樓主,你的問題解決了沒,我也遇到了和你一樣的問題
回復

使用道具 舉報

5#
ID:61002 發表于 2016-10-27 09:30 | 只看該作者
我沒細看你的程序,自己查查。stc的片內eeprom寫之前,必須要擦除以后再寫,不然就是亂的,
回復

使用道具 舉報

6#
ID:137653 發表于 2016-10-27 12:42 | 只看該作者
看看地址有沒有對應上
回復

使用道具 舉報

7#
ID:138155 發表于 2016-10-27 14:47 | 只看該作者
STC的 我遇到的好像是先清零 在寫1再清然后寫入新的數據 不然多出來亂碼 不是每次都亂碼 偶爾會的那種
回復

使用道具 舉報

8#
ID:145017 發表于 2016-10-29 10:43 | 只看該作者
你的問題解決了沒,我也遇到了和你一樣的問題
回復

使用道具 舉報

9#
ID:145062 發表于 2016-10-29 14:21 | 只看該作者
解決步驟:
1.你使用的mCU是51系列的吧,看這些管腳和別的是否用沖突,
2. W25Xxx系列的FLASH是片擦除,扇區擦除,
3.寫完之后要稍等幾個ms然后回讀比較
4.參考FLASH的手冊檢查你的驅動程序流程是否正確,
5.驅動程序中的延時是否合理,要和FLASH的手冊想比對
回復

使用道具 舉報

10#
ID:184706 發表于 2019-2-13 11:29 | 只看該作者
謝謝您的程序
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表