看看下面的这段,是从***的“教程”里摘录而来,如果是笔误当然无须吹毛求疵。
这里,无论是“接收”,还是“发送”,都是“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编辑过]
|