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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

I2C通訊主機隨便發個AT24C02的設備地址都能讀取數據是怎么回事?

[復制鏈接]
跳轉到指定樓層
樓主
STC89C52和AT24C02進行I2C通訊時,STC89C52主機向從機AT24C02隨便發個設備地址,都能讀寫數據,是怎么回事喔?
具體情況:我的AT24C02的設備地址線A0 A1 A2都接地了的,數據手冊上說的AT24C02的設備地址格式:(前四位固定)1010 A2 A1 A0 R/W,由于AT24C02的A0 A1 A2引腳我都在硬件上接地了的,正常情況我在進行讀寫數據時,發送的設備地址應該為(0xa0+R/W), 但是現在我在程序上隨意改變設備地址的值(也就是A2 A1 A0的值),都能讀寫數據成功。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:388197 發表于 2019-7-25 21:58 | 只看該作者
看看你程序里應答部分是怎么寫的
回復

使用道具 舉報

板凳
ID:123289 發表于 2019-7-26 09:18 | 只看該作者
當你序讀取每一位的時候,總會認定的一個值,非0即1!
只不過讀到的0/1是不是“目標設備”發出來的,就不好說了。
回復

使用道具 舉報

地板
ID:467739 發表于 2019-7-30 14:05 | 只看該作者
cjm82 發表于 2019-7-25 21:58
看看你程序里應答部分是怎么寫的

/**
  * @brief  主機檢測從機應答
  * @param  none
  * @retval return(1)應答,return(0)非應答
  */
bit Test_ACK()
{
        SCL=1;                         //拉高SCL線
        Delay_5us();
        if(SDA==1)                         //如果為1,則非應答
        {
                SCL=0;                 //拉低SCL線,使SDA線可以發送停止信號
                _nop_();
                I2C_Stop();           //發送停止信號
                return (0);           //非應答
        }
        else
        {
                SCL=0;                   //拉低SCL線
                _nop_();
                return (1);                //應答
        }               
}
應答程序部分就是這樣寫的,隨便發個設備地址(A0A1A2三個引腳都接地了的),發現SDA都會被拉低。
回復

使用道具 舉報

5#
ID:467739 發表于 2019-7-30 18:59 | 只看該作者
yzwzfyz 發表于 2019-7-26 09:18
當你序讀取每一位的時候,總會認定的一個值,非0即1!
只不過讀到的0/1是不是“目標設備”發出來的,就不 ...

不能確定是不是目標設備發出的0/1, 我總線上就用了一個AT24C02芯片,這樣是不是可以懷疑是芯片有問題
回復

使用道具 舉報

6#
ID:401564 發表于 2019-7-31 08:41 | 只看該作者
芯片有問題的情況并不多
你得寫一個驗證的程序,兩個按鍵:寫入并顯示,讀取并顯示,地址可以是固定的某個地址
先向一個地址寫入一個數據并顯示
然后,斷電,開機,不要寫入,直接讀取,數據是對的話,你的IIC代碼就是對的
驗證好程序之后,其它的再說
回復

使用道具 舉報

7#
ID:467739 發表于 2019-8-3 10:07 | 只看該作者
Y_G_G 發表于 2019-7-31 08:41
芯片有問題的情況并不多
你得寫一個驗證的程序,兩個按鍵:寫入并顯示,讀取并顯示,地址可以是固定的某個 ...

你好,我用程序驗證時,在I2C總線上只用一個AT24C02芯片,用的模擬I2C通訊;先寫入一個數據到一個固定的地址,然后讀取并顯示在數碼管上,下載運行時發現讀取的結果正常,斷電再上電,結果依然正常,然后去掉寫入數據程序部分,只留下讀取數據程序部分,再下載到開發板,發現讀取的數據還是和之前寫入的一樣,斷電再上電,讀取結果依然正常,<<同時我又嘗試將發送的器件地址改變,僅改變A0/A1/A2三位的數值,使它和硬件上連接的地址不相同,我開發板上的AT24C02芯片的A0A1A2都接地了的,重復上面的驗證過程,發現結果還是一樣,寫入的數據和讀取的數據相同, 但是 “將器件地址的高四位,也就是AT24C02固定的那四位1010,
1010 A0 A1 A2 R/W  也改變的話,就會讀取和寫入失敗!   >>
回復

使用道具 舉報

8#
ID:467739 發表于 2019-8-3 10:09 | 只看該作者
Y_G_G 發表于 2019-7-31 08:41
芯片有問題的情況并不多
你得寫一個驗證的程序,兩個按鍵:寫入并顯示,讀取并顯示,地址可以是固定的某個 ...

對了,我用的芯片型號是,ATMEL 711 24C02 PU27 D
回復

使用道具 舉報

9#
ID:401564 發表于 2019-8-3 16:22 | 只看該作者
張松松 發表于 2019-8-3 10:09
對了,我用的芯片型號是,ATMEL 711 24C02 PU27 D

你能寫入和讀取,就說明讀寫的函數是正確的了
A0 A1 A2 這幾個位在多個24C02并聯使用時才會用到的,在24C02中,你只能改動R/W位,其它位是不能動的,1010是固定不變的,A0 A1 A2 這個是和24C02三個引腳的邏輯對應的,你接地了,就是000了,不能改,改了就找不到地址了
如果你是A0接了高電平,那么這三個應該就是:100
回復

使用道具 舉報

10#
ID:401564 發表于 2019-8-3 16:24 | 只看該作者
硬件電路上傳看一下了
回復

使用道具 舉報

11#
ID:388197 發表于 2019-8-4 02:32 | 只看該作者
張松松 發表于 2019-7-30 14:05
/**
  * @brief  主機檢測從機應答
  * @param  none

#define SCK_High GPIO_SetBits(GPIOA,GPIO_Pin_1)
#define SCK_Low  GPIO_ResetBits(GPIOA,GPIO_Pin_1)

#define SDA_High GPIO_SetBits(GPIOA,GPIO_Pin_3)
#define SDA_Low  GPIO_ResetBits(GPIOA,GPIO_Pin_3)

#define SCK_read      GPIOA->IDR  & GPIO_Pin_1  
#define SDA_read      GPIOA->IDR  & GPIO_Pin_3  
typedef enum
{
  FALSE = 0,
  TRUE = !FALSE
} bool;

void I2C_delay()  
{     
   u8 i=100;     
   while(i)   
   {   
     i--;   
   }   
}  

bool I2C_Start()  
{  
    SDA_High;  
    SCK_High;  
    I2C_delay();  
    if(!SDA_read)
    {
        return FALSE;   //SDA線為低電平則總線忙,退出  
    }
    SDA_Low;  
    I2C_delay();  
    if(SDA_read)
    {
        return FALSE;   //SDA線為高電平則總線出錯,退出  
    }
    SDA_Low;  
    I2C_delay();  
    return TRUE;  
}

void I2C_Stop()  
{  
    SCK_Low;  
    I2C_delay();  
    SDA_Low;  
    I2C_delay();  
    SCK_High;  
    I2C_delay();  
    SDA_High;  
    I2C_delay();  
}  

void I2C_Ack()  
{     
    SCK_Low;  
    I2C_delay();  
    SDA_Low;  
    I2C_delay();  
    SCK_High;  
    I2C_delay();  
    SCK_Low;  
    I2C_delay();  
}  

void I2C_NoAck()  
{     
    SCK_Low;  
    I2C_delay();  
    SDA_High;  
    I2C_delay();  
    SCK_High;  
    I2C_delay();  
    SCK_Low;  
    I2C_delay();  
}

bool I2C_WaitAck()   //返回TRUE有ACK,FALSE無ACK  
{  
    SCK_Low;  
    I2C_delay();  
    SDA_High;            
    I2C_delay();  
    SCK_High;  
    I2C_delay();  
    if(SDA_read)  
    {  
      SCK_Low;  
      return FALSE;  
    }  
    SCK_Low;  
    return TRUE;  
}

void I2C_SendByte(u8 SendByte) //數據從高位到低位//  
{  
    u8 i=8;  
    while(i--)  
    {  
      SCK_Low;  
      I2C_delay();  
      if(SendByte&0x80)
      {
        SDA_High;
      }
      else
      {
        SDA_Low;
      }
      SendByte<<=1;  
      I2C_delay();  
      SCK_High;  
      I2C_delay();  
    }  
    SCK_Low;  
}

u8 I2C_ReadByte(void)  //數據從高位到低位//  
{   
    u8 i=8;  
    u8 data=0;  
  
    SDA_High;               
    while(i--)  
    {  
      data<<=1;        
      SCK_Low;  
      I2C_delay();  
      SCK_High;  
      I2C_delay();   
      if(SDA_read)  
      {  
        data|=0x01;  
      }  
    }  
    SCK_Low;  
    return data;  
}
//===================24C02 讀寫程序===========================
bool AT24C02_WriteByte(u8 SendByte, u8 Address)  
{         
  if(!I2C_Start())
  {
    return FALSE;                                                           
  }
  I2C_SendByte(0xa0);     
  if(!I2C_WaitAck())  
  {  
    I2C_Stop();   
    return FALSE;  
  }  
  I2C_SendByte(Address);         
  I2C_WaitAck();      
  I2C_SendByte(SendByte);  
  I2C_WaitAck();     
  I2C_Stop();   
  Delay(15);                    //加個延時等待寫完

  return TRUE;  
}

bool AT24C02_ReadByte(u8* data,u8 Adress)  
{         
  if(!I2C_Start())                       //如果總線忙,則返回失敗.
    return FALSE;  
  I2C_SendByte(0xa0);            
  if(!I2C_WaitAck())                 //如果沒有得到應答,則返回失敗.
  {  
    I2C_Stop();   
    return FALSE;  
  }  
  I2C_SendByte(Adress);      
  I2C_WaitAck();  
  I2C_Start();  
  I2C_SendByte(0xa1);  
  I2C_WaitAck();  
  *data = I2C_ReadByte();     
  I2C_Stop();  
  return TRUE;  
}  


這個是我以前學I2C時的程序,和24C02的程序,不過是32的,你稍微改下,用在51也很簡單,24C02的兩個函數也就學習的時候用過下,后面基本沒碰過.但前面的I2C程序我用過好幾次,沒發現問題.你可以參考下.
回復

使用道具 舉報

12#
ID:467739 發表于 2019-8-5 21:58 | 只看該作者
Y_G_G 發表于 2019-8-3 16:24
硬件電路上傳看一下了

這是我開發板上的AT24C02電路圖

電路圖.png (44.3 KB, 下載次數: 51)

電路圖.png
回復

使用道具 舉報

13#
ID:467739 發表于 2019-8-5 22:30 | 只看該作者
Y_G_G 發表于 2019-8-3 16:22
你能寫入和讀取,就說明讀寫的函數是正確的了
A0 A1 A2 這幾個位在多個24C02并聯使用時才會用到的,在24 ...

我在面包板上接了兩個AT24C02也試了下的,兩片AT24C02芯片的硬件地址A0A1A2設置為不同,我在程序上分別向兩塊芯片發送數據,也是上面那種現象,A0A1A2隨意改變,都能向芯片正確寫入數據,并且正確讀出。   
      同時我又發現一個詭異的現象,就是向第一塊芯片的一個固定地址(程序里我選的儲存地址是0x01,比如寫個數據為0x27)寫入數據,但是我沒有向第二塊芯片的儲存地址0x01寫入數據,接下來我直接讀第二塊芯片儲存地址0x01里的數據,讀出來的數據居然和我剛剛向第一塊芯片儲存地址0x01寫入的數據相同(為了避免巧合我多次改變向第一塊芯片寫入的數據,發現實驗現象和上面相同),也就是在向一塊芯片寫入數據時,兩塊芯片的相同儲存地址里的內容都被寫入數據了(A0A1A2隨意改變也是這樣)。
回復

使用道具 舉報

14#
ID:467739 發表于 2019-8-5 22:31 | 只看該作者
cjm82 發表于 2019-8-4 02:32
#define SCK_High GPIO_SetBits(GPIOA,GPIO_Pin_1)
#define SCK_Low  GPIO_ResetBits(GPIOA,GPIO_Pin_1) ...

好的,thank you!!
回復

使用道具 舉報

15#
ID:467739 發表于 2019-8-5 22:51 | 只看該作者
Y_G_G 發表于 2019-8-3 16:22
你能寫入和讀取,就說明讀寫的函數是正確的了
A0 A1 A2 這幾個位在多個24C02并聯使用時才會用到的,在24 ...

感謝你的耐心回復喔!不準備糾結這個問題了,感覺還是我買的芯片有問題,后面有機會再換換芯片試試
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧美一区二区三区视频 | 狠狠操在线 | 超碰在线免费公开 | 国产精品欧美一区二区三区不卡 | caoporn地址| 久草视频在线播放 | 在线亚洲人成电影网站色www | 伊人伊成久久人综合网站 | 中文字幕高清 | 国产黄色av电影 | 午夜成人在线视频 | 日本在线视 | 天天搞天天操 | 91视视频在线观看入口直接观看 | 欧美视频成人 | 日韩中文视频 | 在线黄色影院 | 99热在线播放 | 激情毛片 | 亚洲精品二区 | 日本一区二区三区视频在线 | 久久午夜视频 | 九九综合 | 国产成人精品久久 | 一区| 精品欧美一区二区在线观看视频 | 亚洲成人黄色 | 国产精品一区在线 | 毛片一区| 亚洲一区二区三区久久 | 日韩av电影在线观看 | 亚洲免费网址 | 性网站免费 | 欧美伊人影院 | 欧美视频二区 | 色综合久久天天综合网 | 国产在线播 | 国产一在线观看 | 精品不卡| 亚洲欧美中文字幕在线观看 | 在线电影日韩 |