看看下面的這段,是從***的“教程”里摘錄而來,如果是筆誤當然無須吹毛求疵。
這里,無論是“接收”,還是“發送”,都是“ACK”, 其“ACK”的內容是(SCL_IC_ C ARD=1; SCL_IC_ C ARD=0;”)就這些。這樣能行嗎?這個“老師”連基本的IIC協議都沒弄懂。這大概不會是筆誤吧?
在IIC協議中,不管是主控器件還是從器件,1、向總線發送一個字節數據后,就要檢查應答信號,看看接收器件是否“字節接受完成”。
2、接收器件正確接收到一個字節的數據后,也要發送一個應答信號(1bit),告訴發送器件“字節接收完成”
如果接收器件接收不正確,則不會發送應答信號。發送器件就檢測不到“應答信號”,這時就要從“開始”步驟重來。
這里就有了這么幾個環節:“應答信號(1bit,低位)”、“非應答信號(1bit,高位)、“檢測應答信號”。
讀的流程:1發送開始信號-->2發送器件地址(含“寫”指令位)-->3檢測應答-->4發送字節地址-->5檢測應答-->6發送開始信號(含“讀”指令位)
-->7檢測應答-->8讀一個字節-->(9發送應答信號-->......(重復第8步)讀第2~N字節)-->發送非應答信號-->發送停止信號
寫的流程:1發送開始信號-->2發送器件地址(含“寫”指令位)-->3檢測應答-->4發送字節地址-->5檢測應答-->6寫一個字節-->7檢測應答信號
-->(......(重復第6步)寫第2~N字節-->(重復第7步)檢測應答信號-->)發送停止信號
上面僅就多字節讀寫做了簡單的描述,如果是單字節讀、寫括號內不用。
。
特別說明:無論哪一個“檢測應答信號”不成功,都要返回到“發送開始信號”處,重新開始。 如果是大容量的,發送地址分高位、低位2次,都要“檢測應答”。
下面就是這個“教程”的摘錄:
*****************(鄭重提醒:這是一個不正確的程序,千萬不要套用)******************
第十四講 IC卡(24C01)
在日常生活中,IC卡的使用越來越廣泛,而且還有進一步擴大的趨勢。因此
有必要掌握這方面的知識,下面以24C01 為例,簡單地介紹一般使用方法。
#include <reg52.h>
#include <intrins.h>
sb i t SC L _ IC _ C AR D= P1 ^3 ;
sb i t 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];
v o i d 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=rd_24c01(i);delay (250);}
for (i=0;i<=7;i++) {w r_24c01(i,display_buf fer);delay (250);}
while(1);
}
void start() //啟動讀寫時序
{ // 圖4-22 (c )開始、結束脈沖時序
35
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); //送出存儲器地址
36
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) // 延時函數
37
{
int i;
for (i=1;i<=n;i++){;}
}
[此貼子已經被作者于2012-10-13 14:54:07編輯過]
|