看看下面的這段,是從***的“教程”里摘錄而來,如果是筆誤當然無須吹毛求疵。
這里,無論是“接收”,還是“發送”,都是“ACK”, 其“ACK”的內容是(SCL_IC_ C ARD=1; SCL_IC_ C ARD=0;”)就這些。這樣能行嗎?這個“老師”連基本的IIC協議都沒弄懂。這大概不會是筆誤吧?
在IIC協議中,不管是主控器件還是從器件,A、向總線發送一個字節數據后,就要發送一個應答信號(1bit),告訴接收器件“發送完成”。B、接收器件正確接收到一個字節的數據后,也要發送一個應答信號(1bit),告訴發送器件“接收完成”
如果接收器件接收不正確,則不會發送應答信號。發送器件就檢測不到“應答信號”,這時就要從“開始”步驟重來。
這里就有了這么幾個環節:“應答信號(1bit,低位)”、“非應答信號(1bit,高位)、“檢測應答信號”。
讀的流程:發送開始信號-發送器件地址(含“寫”信息)-檢測應答-發送字節地址-檢測應答-發送開始信號(含“讀”信息)-檢測應答-讀一個字節-發送應答信號-......讀第N字節-發送非應答信號-發送停止信號
寫的流程:發送開始信號-發送器件地址(含“寫”信息)-檢測應答-發送字節地址-檢測應答-寫一個字節-檢測應答信號-......寫第N字節-檢測應答信號-發送停止信號
上面僅就多字節讀寫做了簡單的描述,單字節的類似。
特別說明:無論哪一個“檢測應答信號”不成功,都要返回到“發送開始信號”處,重新開始。 如果是大容量的,發送地址分高位、低位2次,都要“檢測應答”
下面就是這個“教程”的摘錄:
*****************(鄭重提醒:這是一個不正確的程序,千萬不要套用)******************
第十四講 IC卡(24C01)
在日常生活中,IC卡的使用越來越廣泛,而且還有進一步擴大的趨勢。因此
有必要掌握這方面的知識,下面以24C01 為例,簡單地介紹一般使用方法。
#include <reg52.h> #include <intrins.h> sbit SC L _ IC _ C AR D= P1 ^3 ; sbit SDA_ IC _ C AR D= P1 ^4 ; sbit WP_IC_CARD =P1^7; bdata char com_data; sbit m o s_bit=com_data^7; sbit low_bit=com_data^0; unsigned char data display _buf fer[8]; void d e l a y(i n t n ); unsigned char rd_24c01(char a); void w r_24c01(char a,char b); ma in() { unsigned char i; WP_IC_CARD=1; for (i=0;i<=7;i++) {display _buf fer[i]=rd_24c01(i);delay (250);} for (i=0;i<=7;i++) {w r_24c01(i,display_buf fer[i]);delay (250);} while(1); } void start() //啟動讀寫時序 { // 圖4-22 (c )開始、結束脈沖時序 SDA_IC_ C ARD=1; SCL_IC_ C ARD=1; SDA_ IC _ C AR D= 0 ; // 啟動start SCL_IC_ C ARD=0; } void stop() //停止操作 { // 圖4-22 (c )開始、結束脈沖時序 SDA_IC_ C ARD=0; SCL_IC_ C ARD=1; SDA_IC_ C ARD=1; } void ack() //應答函數 { SCL_IC_ C ARD=1; SCL_IC_ C ARD=0; } void shift8(char a) //8位移位輸出 { data unsigned char i; com _data=a; for(i=0;i<8;i++) { SDA_IC_CARD=mo s_bit; S C L _ IC _ C AR D= 1 ; S C L _ IC _ C AR D= 0 ; com _data=com_data*2; } } unsigned char rd_24c01(char a) // 讀IC 卡函數 { data unsigned char i,comma nd; SDA_IC_ C ARD=1; SCL_IC_ C ARD=0; st a rt (); // 啟動 com ma nd=0X A0 ; //160; shift8(comma nd); // 送出器件地址 第一步 a c k (); // 應答 shift8(a); //送出存儲器地址 a c k (); // 應答 st a rt (); // 啟動 com ma nd=0X A1 //161; shift8(comma nd); // 送出器件地址 第二步 a c k (); // 應答 SDA_IC_ C ARD=1; // for(i=0;i<8;i++) // 循環8 次讀取一個字節 { com _data=com_data*2; SCL_IC_ C ARD=1; lo w_b it=SDA_ IC_ C ARD; 讀取數據 SC L _ IC _ C AR D= 0 ; } st o p (); // 停止操作 return(com _data); } void w r_24c01(char a,char b) // 寫IC 卡函數 { data unsigned char comma nd; WP_IC_CARD=0; _nop_(); SDA_IC_ C ARD=1; SCL_IC_ C ARD=0; st a rt (); // 啟動 com ma nd=0X A0 ; //160; shift8(comma nd); // 送出器件地址 寫IC 卡函數 a c k (); // 應答 shift8(a); //送出存儲器地址 a c k (); // 應答 shift8(b); //送出欲寫入的數據 a c k (); // 應答 st o p (); // 停止操作 _nop_(); WP_IC_CARD=1; } void delay(int n) // 延時函數 { int i; for (i=1;i<=n;i++){;} }