久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4365|回復: 14
收起左側

求指點:單片機向EEPROM內寫入一個數,然后再把他讀出來驗證寫入成功。但結果是255

  [復制鏈接]
回帖獎勵 25 黑幣 回復本帖可獲得 5 黑幣獎勵! 每人限 1 次
ID:702446 發表于 2020-3-15 14:05 | 顯示全部樓層 |閱讀模式
求大神指點:我想向EEPROM內寫入一個數,然后再把他讀出來驗證寫入成功,以此來學習IIC通訊協議的用法。但是讀出來的結果是255,不管怎么調試都沒用。哪位高手有邏輯分析儀能幫我看看是哪里出錯了嗎?

單片機源程序如下:
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define At24c02ADDR 0xa0                             //At24c02EEPROM地址宏定義
#define I2cWrite 0
#define I2cRead 1
sbit SCL=P2^1;
sbit SDA=P2^0;
sbit dula=P2^6;
sbit wela=P2^7;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,                        //編碼表
                    0x7d,0x07,0x7f,0x6f,0x77,0x7c,
                                        0x39,0x5e,0x79,0x71,0x00     };
bit AcKFlag;
uchar bai,shi,ge;
void delay(uint z)                   //定義 延時函數
{
uint x,y;
for(x=0;x<100;x++)
         for(y=0;y<z;y++);
}

void delay5us()                  //定義  延時函數
{
_nop_();
}

void I2Cstart()                 //定義  起始信號函數
{
SDA=1;
SCL=1;
delay5us();
SDA=0;
delay5us();
}

void I2Cstop()                 //定義  停止信號函數
{
SCL=0;
SDA=0;
SCL=1;
delay5us();
SDA=1;
delay5us();
}

bit ReadAck()                //定義  主機讀從機應答信號函數
{
SCL=0;
SCL=1;                           
delay5us();
if(SDA)
{                                         //非應答
          SCL=0;                         //拉低SCL(據波形圖)
        return(1);
}
else
{
  SCL=0;
  return(0);
}


}

void SendAck(bit i)          //定義  主機發送應答
{
SCL=0;
if(i)
         SDA=1;
else
         SDA=0;
SCL=1;                                  //SCL拉高,讀取數據
delay5us();                  //延時保持數據穩定
SCL=0;                                  //SCL拉低占用總線繼續通信
SDA=1;                                  //釋放sda         ,否則主機會一直占用sda
}

void I2cSendByte(uchar DAT)        //定義 寫入數據操作邏輯函數
{
        uchar i;
        for(i=0;i<8;i++)
        {
                 SCL=0;
                delay5us();
                if(DAT&0x80)
                        SDA=1;
                else
                        SDA=0;
                SCL=1;
                delay5us();
                DAT<<=1;
        }
        SCL=0;                                    //拉低時鐘總線,繼續通信
        SDA=1;                                   //釋放數據總線,允許其他設備傳遞數據
}

void At24c02write(uchar ADDR,DAT)        //定義  寫入函數
{
  I2Cstart();                                  //起始信號
  I2cSendByte(At24c02ADDR+I2cWrite);  //發送從機地址+寫信號
          if(ReadAck())
           AcKFlag=1;           //主機讀應答信號:結果為無應答
          else
           AcKFlag=0;           //主機讀應答信號:結果為有應答
  I2cSendByte(ADDR);           //調用寫入數據操作邏輯函數:發送想要寫入的內存地址
          if(ReadAck())
           AcKFlag=1;           
          else
           AcKFlag=0;           
  I2cSendByte(DAT);           //調用寫入數據操作邏輯函數:發送要寫入的數據
             if(ReadAck())
           AcKFlag=1;           
          else
           AcKFlag=0;
  I2Cstop();                      //停止信號
}

uchar I2cReadByte()           //讀取從機內存數據邏輯子函數
{
uchar i,DAT;
for(i=0;i<8;i++)
         {
          DAT<<=1;
          SCL=0;                   //讀數據時SDA由從機控制,主機只要控制scl時序,接收sda上的數據即可
          SCL=1;
          if(SDA)
                  DAT|=0x01;
          delay5us();
        }
return(DAT);
}

uchar At24c02Read(uchar ADDR)  //定義  讀出函數
{
  uchar DAT;
  I2Cstart();                                  //起始信號
  I2cSendByte(At24c02ADDR+I2cWrite);  //發送從機(EEPROM)地址+寫信號(此處發寫信號是為了發送想要讀取的內存單元的地址)
          if(ReadAck())
           AcKFlag=1;           //主機讀應答信號:結果為無應答
          else
           AcKFlag=0;           //主機讀應答信號:結果為有應答
  I2cSendByte(ADDR);           //發送想要讀的內存地址
  ReadAck();                             //主機讀應答信號(不管是否應答)
  I2Cstart();                   //重復起始信號
  I2cSendByte(At24c02ADDR+I2cRead);  //發送從機地址+讀信號
  if(ReadAck())                   //判斷應答信號
           AcKFlag=1;           
          else
           AcKFlag=0;
  DAT=I2cReadByte();   //調用 讀取從機內存數據邏輯子函數 讀一個字節
  SendAck(1);                   //主機發送應答信號:非應答(非應答函數內包括,占用總線繼續通信與釋放數據總線允許其他設備調用的信號,故調用的子函數內部不必寫
  I2Cstop();                   //發送停止信號
  return(DAT);                   //返回函數值
}

void display(uchar num)
{

bai=num/100;
shi=num%100/10;
ge=num%10;

while(1)
{
                wela=1;
                P0=0xdf;
                wela=0;
        dula=1;
                P0=table[bai];
                dula=0;
                        P0=0xff;
                delay(3);

        
                dula=1;
                P0=table[shi];
                dula=0;
                        P0=0xff;
                wela=1;
                P0=0xbf;
                wela=0;
                delay(3);

        
                dula=1;
                P0=table[ge];
                dula=0;
                        P0=0xff;
                wela=1;
                P0=0x7f;
                wela=0;
                delay(3);
}
}
void main()
{
At24c02write(0x02,6);
delay5us();
delay5us();                           //延時一會,待從機將先前接收的數據處理完畢,否則可能會讀取失敗
display(At24c02Read(0x02));
while(1);

}

回復

使用道具 舉報

ID:235200 發表于 2020-3-15 17:39 | 顯示全部樓層
讀出是255,證明是數據未寫進去,重點檢查寫入程序
回復

使用道具 舉報

ID:699855 發表于 2020-3-16 08:31 | 顯示全部樓層
用示波器看i2c時序實現對不對
回復

使用道具 舉報

ID:709464 發表于 2020-3-16 17:23 | 顯示全部樓層
可能是讀寫時序沒處理好吧,建議換匯編語言來處理這部分程序,可能更精準些。
回復

使用道具 舉報

ID:691449 發表于 2020-3-19 12:52 | 顯示全部樓層
可能是應答出了問題
回復

使用道具 舉報

ID:645890 發表于 2020-3-19 14:01 | 顯示全部樓層
數據超過了?
回復

使用道具 舉報

ID:466599 發表于 2020-3-20 09:49 | 顯示全部樓層
這個是時序不對,利用示波器/邏輯分析儀檢查波形,根據手冊說明調整時序即可
回復

使用道具 舉報

ID:743654 發表于 2020-9-17 13:58 | 顯示全部樓層
有可能是時序有問題,時序必須嚴格對照數據手冊
回復

使用道具 舉報

ID:637608 發表于 2021-8-13 14:40 | 顯示全部樓層
時序問題,可采用示波器復現修正
回復

使用道具 舉報

ID:386001 發表于 2021-8-14 09:30 | 顯示全部樓層
這個讀寫函數,我自己寫過,你按著時序寫了,然后用示波器看一下,感覺不是很難的
回復

使用道具 舉報

ID:805317 發表于 2021-9-2 09:37 來自手機 | 顯示全部樓層
你把時間多延遲一會,就是寫入數據后,延遲時間稍微長一點,再讀取數據
回復

使用道具 舉報

ID:624769 發表于 2021-9-2 14:54 | 顯示全部樓層
首先IIC必須用上拉電阻,其次,Eeprom的寫保護,要確保關閉。最后,確認一下設備地址,是否正確?
回復

使用道具 舉報

ID:81196 發表于 2021-9-13 11:48 | 顯示全部樓層
肯定是時序的問題了,
回復

使用道具 舉報

ID:207030 發表于 2021-9-13 14:27 | 顯示全部樓層
1、檢查IO口置高置低是否正常,萬用表量一下。
2、檢查IO口的讀是否正常,是否能讀到0   1  電平。
3、單片機如果不是準雙向,需要在讀之前設置為輸入,讀之后立刻設置為輸出。
4、還是不行  那就是時序不對  或者延時不對。
回復

使用道具 舉報

ID:624769 發表于 2021-9-13 14:36 | 顯示全部樓層
sgd985437 發表于 2021-9-13 14:27
1、檢查IO口置高置低是否正常,萬用表量一下。
2、檢查IO口的讀是否正常,是否能讀到0   1  電平。
3、單 ...

此帖 樓主 于2020年 3 月 發的帖子,至今1年半,只有63黑幣。這種僵尸貼,就沒有必要翻出來回復了吧?而且也不是結論性的答復,也不會對其他壇友有任何參考價值。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费毛片网 | 久草视频在线播放 | 日韩一区二区三区在线播放 | www久久| 国产一区二区三区精品久久久 | 亚洲精品一区二区三区中文字幕 | 中文字幕蜜臀 | 免费看爱爱视频 | 99精品在线 | 久久se精品一区精品二区 | 天天干天天操天天看 | 欧美日韩精选 | 午夜丰满寂寞少妇精品 | 精品欧美一区二区三区久久久 | 欧美一级免费 | 狠狠av| 日韩视频中文字幕 | 久久精品在线免费视频 | 一区二区在线视频 | 亚洲一区二区三区乱码aⅴ 四虎在线视频 | 久久精品91久久久久久再现 | 亚洲国产精品久久久久秋霞不卡 | 91精品国产91久久久久久最新 | 99久久精品国产麻豆演员表 | 国产麻豆乱码精品一区二区三区 | 在线婷婷| 超碰人人艹| 国产一区二区麻豆 | 日本成人在线免费视频 | 国产黄色网 | 国产精品美女久久久久aⅴ国产馆 | 国产精品亚洲欧美日韩一区在线 | 亚洲大片在线观看 | 精品乱子伦一区二区三区 | 久久91精品 | 麻豆一区二区三区精品视频 | 在线一区 | 91精品麻豆日日躁夜夜躁 | 久久免费观看一级毛片 | 亚洲精品一二三 | 天堂资源最新在线 |