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

標題: I2C通訊主機隨便發個AT24C02的設備地址都能讀取數據是怎么回事? [打印本頁]

作者: 張松松    時間: 2019-7-25 15:37
標題: 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的值),都能讀寫數據成功。

作者: cjm82    時間: 2019-7-25 21:58
看看你程序里應答部分是怎么寫的
作者: yzwzfyz    時間: 2019-7-26 09:18
當你序讀取每一位的時候,總會認定的一個值,非0即1!
只不過讀到的0/1是不是“目標設備”發出來的,就不好說了。
作者: 張松松    時間: 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都會被拉低。
作者: 張松松    時間: 2019-7-30 18:59
yzwzfyz 發表于 2019-7-26 09:18
當你序讀取每一位的時候,總會認定的一個值,非0即1!
只不過讀到的0/1是不是“目標設備”發出來的,就不 ...

不能確定是不是目標設備發出的0/1, 我總線上就用了一個AT24C02芯片,這樣是不是可以懷疑是芯片有問題
作者: Y_G_G    時間: 2019-7-31 08:41
芯片有問題的情況并不多
你得寫一個驗證的程序,兩個按鍵:寫入并顯示,讀取并顯示,地址可以是固定的某個地址
先向一個地址寫入一個數據并顯示
然后,斷電,開機,不要寫入,直接讀取,數據是對的話,你的IIC代碼就是對的
驗證好程序之后,其它的再說
作者: 張松松    時間: 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  也改變的話,就會讀取和寫入失敗!   >>
作者: 張松松    時間: 2019-8-3 10:09
Y_G_G 發表于 2019-7-31 08:41
芯片有問題的情況并不多
你得寫一個驗證的程序,兩個按鍵:寫入并顯示,讀取并顯示,地址可以是固定的某個 ...

對了,我用的芯片型號是,ATMEL 711 24C02 PU27 D
作者: Y_G_G    時間: 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
作者: Y_G_G    時間: 2019-8-3 16:24
硬件電路上傳看一下了
作者: cjm82    時間: 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程序我用過好幾次,沒發現問題.你可以參考下.
作者: 張松松    時間: 2019-8-5 21:58
Y_G_G 發表于 2019-8-3 16:24
硬件電路上傳看一下了

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

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

電路圖.png

作者: 張松松    時間: 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隨意改變也是這樣)。
作者: 張松松    時間: 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!!
作者: 張松松    時間: 2019-8-5 22:51
Y_G_G 發表于 2019-8-3 16:22
你能寫入和讀取,就說明讀寫的函數是正確的了
A0 A1 A2 這幾個位在多個24C02并聯使用時才會用到的,在24 ...

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




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1