IIC時序操做24C02芯片

1.心血來潮看本身能不能參考時序圖從新寫一個IIC驅動,增強一下時序圖的理解。記錄下來,之後遇到此類的IIC時序的芯片能夠直接操做。spa

先說說本身參照手冊來寫AT24c02的IIC低層驅動,從寫完到最後調試成功所遇到的問題:3d

  1.先肯定SDA、SCL兩根線的硬件鏈接。 (因爲本身換了一套開發板,本身當時沒有意識到,最後發現了)。調試

  2.先調串口便於打印調試 (可是以前調試好的代碼,居然不能用)本身也是醉了。而後把總中斷關掉,就莫名其妙的變好了。這個問題本身也沒搞明白。code

  3.本身錯在了起始信號那裏,我把SCL拉高後,沒有再拉低,就直接去寫數據了。這確定就悲劇了。。blog

  4.還有不能很頻繁不斷擦除、寫入。否則會出錯。。。開發

本身的想法是 寫入一個字節在讀出用串口發出來。it

 2.模擬iic時序 class

    2.1起始信號 date

先是 SDA和SCL都拉高 並延時(延時時間能夠參考手冊<讀寫週期那塊>) 循環

//總線初始化 
void Iic_init() { SDA=1; delay10us(); SCL=1; delay10us(); } //iic的開始信號(在時鐘線SCL爲高的時候數據線由高變低) void start() { SDA=0; delay10us(); SCL=0; delay10us(); //以前是這裏沒有把時鐘線拉低。才致使沒有正確的起始信號。 }

 

    2.2中止信號

//中止信號 (在時鐘線SCL爲高時數據線由低變高)
void stop()
{
SCL=1;
delay10us();
SDA=0;
delay10us();
SDA=1;
delay10us();
}

  2.3 寫一個字節帶應答信號:

    

 

//寫一個字節(帶應答的) 返回值爲1,成功寫入並應答。不然反之。
unsigned char Iic_write(unsigned char date)	             //高位在前
{
 unsigned char i,j=0;

 for(i=0;i<8;i++)        // 好比: data: 10011001   
   {                                                     
    SDA=date>>7;	     //第一次發送一個字節的最高位(bit7),第二次發送一個字節的bit6,
	//先送給數據線,讓他準備好
	date=date<<1;	     // 爲了方便讀取下一位       // C語言的位操做本身要特別熟悉<C語言高級專題>
    //delay10us();
	SCL=1;
	delay10us();
	SCL=0;
	delay10us();      //成功給SDA寫入一位數據。
   }
  //此時在這裏 SCL(時鐘線) 已經爲低了。
 SDA=1;				   //應答信號 acknowledge  時序是先把 數據先拉高,第九個時鐘週期,看SDA是否被拉低。
 delay10us();
 SCL=1;		           
 delay10us();
 while(SDA)								    //由時序圖知 若是發送應答 SDA由高置低 
 { 
  j++;									    //若是不該答避免死循環
  if(j>200)
   {
   	SCL=0;
   	return 0;                                    //SDA=1; SCL=0                               
   }
								  
 }
 SCL=0;
 delay10us();
 return 1;								         //SDA=0; SCL=0
}

     2.3 讀一個字節的數據 

 1 //iic讀一個字節 
 2 unsigned char Iic_read()  3 {  4  unsigned char dat=0,i;  5  SDA=1;                 //不知道爲何這裏要把數據線拉高,我感受高低都行吧!
 6  delay10us();  7  for(i=0;i<8;i++)  8  {  9     SCL=1;          // 這個時候就要準備往SDA數據線裏送數據了。
10  delay10us(); 11     dat=dat<<1; 12     dat=dat|SDA;  // 這兩句代碼的順序要注意,第八次的時候就直接把最低位的賦給dat了
13     SCL=0; 14  delay10us(); 15  } 16  return dat; 17 }

 而後在寫稍微高層(針對器件)的時序協議:

寫、讀一個字節的時序:

  

調用底層時序來完成就好了。

相關文章
相關標籤/搜索