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 }
而後在寫稍微高層(針對器件)的時序協議:
寫、讀一個字節的時序:
調用底層時序來完成就好了。