
IIC(Inter-Integrated Circuit) ,简单说就是IC(芯片)之间通信的总线。总线的意思就是,各个器件都并联接到一组公共的线路上,然后共用这条线路来传输数据信息。总线的英文名字是BUS,所以这些数据的传输有点类似搭乘巴士的感觉。这样做的好处就是可以复用线路,大家都来坐巴士就好了,不用自己开车了。
IIC通信协议采用2条信号线,1条时钟线(SCL)和1条数据线(SDA),属于串行半双工通信。标准模式的传输速率为100Kb/s,快速模式为400Kb/s。总线上可以接多个从设备,从设备的地址必须不同。也可也接多个主设备,但同一时刻只能有一个主设备控制总线。最大设备数量受总线的最大负载电容400pf限制。
每个从设备有自己的设备地址,主设备发送START信号后,紧跟着发送想要通信的从设备地址字节,7位器件地址+1位读写标志位(0为写,1为读)。
START信号:当时钟线为高时,数据线下跳会产生启动信号。
STOP信号:当时钟线为高时,数据线上跳会产生停止信号。
1总线空闲时,就是总线上所有器件都释放了总线,此时SCL和SDA因为有上拉电阻都为高电平。
2主设备检测到总线当前处于空闲时,此时可以发START信号获得总线得控制权。
3主设备通信完成后,发送STOP信号释放总线,总线处于空闲状态。
1 主控检测到总线处于空闲时,首先发送一个START信号来控制总线,此时总线进入忙状态;
2 主控发送一个设备地址字节,总线上所有的从设备都会收到;
3 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
4 主控收到ACK后开始发送第一个数据字节;
5 被控器收到数据字节后发送一个ACK表示继续传送数据,发送NACK表示传送数据结束;
6 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;
1主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
2发送一个地址字节(包括7位地址码和一位R/W,最后1bit为0,表示写),将地址写入地址计数器;
3当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
4主控收到ACK后紧接着发送一个start状态,然后重复第一个地址字节(device code)最后1bit为'1',代表读。
5释放数据总线,开始接收第一个数据字节;
6主控收到数据后发送ACK表示继续传送数据,发送NACK表示传送数据结束;
应答是接收设别自动产生的,不一定是从机。在IIC上除了开始,停止和重复开始外,所有数据都在在时钟的低电平变化的,也就是为高后,数据就应该稳定了。所以如果是模拟总线,应先有下降沿,再设为输入,然后读ACK,如果是从机的应答,是自动产生的,是作为数据通信正确的判断标志,为了可靠,是要判断的。主机的应答一般是程序控制的,如果要结束总线,可以给也可以不给应答;如果要继续读数据,就必须给出应答。
此测试程序是先写后读,已经测度通过,希望对你有用!!! /
24c02测试程序 20111201 wqz
/
#include<reg52h>
#include<intrinsh>typedef unsigned char uchar;#define delay5us() _nop_();_nop_();_nop_();_nop_();_nop_();
// _nop_();_nop_();_nop_();_nop_();_nop_(); //延时sbit SDA=P2^7; //IIC总线
sbit SCL=P2^6;
sbit IO =P1^7; //595控制信号
sbit RLK =P1^6;
sbit CLK =P1^5;void my_delay1ms(int t); //晶振频率为110592时,延时为1ms
void Start(); //起始信号
void stop(); //结束信号
void ACK(); //写应答
bit test(); //测试应答信号
void nn(); //不应答
void write_1byte(uchar num);//写一字节数据
uchar read_1byte(); //读一字节数据
uchar write_data(uchar addr,uchar Data,uchar num); //将数据写入24C02中
void write_mpage(uchar addr,uchar Data,uchar num); //页写
void read_data(uchar addr,uchar p,uchar num2); //从24C02中读出数据/
主函数
/void main()
{
uchar i,j,aa; uchar dis1[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,<br> 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0--F
uchar dis2[16]; //将dis1中的数据写入24C02后读出存在dis2中
write_mpage(0,dis1,16); //写
my_delay1ms(10);
read_data(0,dis2,16); // 读
my_delay1ms(10); while(1)
{
for(j=0;j<16;j++) //将读出的数据显示在数码管上,测试正确性
{
aa=dis2[j];
RLK=0;
for(i=0;i<8;i++)
{
aa<<=1;
IO=CY;
CLK=0;
CLK=1;
}
RLK=1;
my_delay1ms(2000);
}
}
}//void my_delay1ms(int t) //晶振频率为110592时,延时为1ms
{
uchar i,j; while(t--)
{
for(i=10;i>0;i--)
for(j=41;j>0;j--);
}
}//void Start() //起始信号
{
SDA=1;
SCL=1;
delay5us();
SDA=0;
delay5us();
SCL=0;
delay5us();
SDA=1;
}//void stop() //结束信号
{
SDA=0;
delay5us();
SCL=0;
SCL=1;
delay5us();
SDA=1;
}//void ACK() //写应答
{
SDA=0;
SCL=1;
delay5us();
SCL=0;
delay5us();
SDA=1;
}//bit test() //测试应答信号
{
bit a; SDA=1;
delay5us();
SCL=1;
a=SDA;
SCL=0;
return(a);
}//void nn() //不应答
{
SDA=1;
SCL=0;
delay5us();
SCL=1;
}//void write_1byte(uchar num)//写一字节数据
{
uchar i,date; date=num;
for(i=0;i<8;i++)
{
date<<=1;
SDA=CY;
delay5us();
SCL=1;
delay5us();
SCL=0;
}
}//uchar read_1byte() //读一字节数据
{
uchar i,tember=0; for (i=0;i<8;i++)
{
tember<<=1;
if(SDA)
tember|=0x01;
SCL=1;
delay5us();
SCL=0;
}
return tember;
}//uchar write_data(uchar addr,uchar Data,uchar num) //将数据写入24C02中
{
uchar i,diz; diz=addr;
Start();
write_1byte(0xa0);
test();
write_1byte(diz);
test();
for(i=0;i<num;)
{
write_1byte(Data++);
test();
i++;
diz++;
if((diz&0x07)==0) break;
}
stop();
return (num-i);
}//void write_mpage(uchar addr,uchar Data,uchar num) //页写
{
uchar ff; ff=num;
do
{
ff=write_data( addr+(num-ff),Data+(num-ff),ff);
my_delay1ms(10);
}
while(ff);
}//void read_data(uchar addr,uchar p,uchar num2) //从24C02中读出数据
{
uchar i; Start();
write_1byte(0xa0);
test();
write_1byte(addr);
test();
Start();
write_1byte(0xa1);
test();
for(i=0;i<num2-1;i++)
{
p++=read_1byte();
ACK();
}
p=read_1byte();
nn();
stop();
}
以上就是关于IIC通信协议全部的内容,包括:IIC通信协议、C51单片机模拟IIC总线,应答函数的疑问、有没有单片机程序,是把IIC的数据读出来。是有应答的。。具体还没想到思路,还想有人执教一下等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)