IIC时序操作24C02芯片

1.心血来潮看自己能不能参考时序图重新写一个IIC驱动,加强一下时序图的理解。记录下来,以后遇到此类的IIC时序的芯片可以直接操作。

先说说自己参照手册来写AT24c02的IIC低层驱动,从写完到最后调试成功所遇到的问题:

  1.先确定SDA、SCL两根线的硬件连接。 (由于自己换了一套开发板,自己当时没有意识到,最后发现了)。

  2.先调串口便于打印调试 (但是之前调试好的代码,竟然不能用)自己也是醉了。然后把总中断关掉,就莫名其妙的变好了。这个问题自己也没搞明白。

  3.自己错在了起始信号那里,我把SCL拉高后,没有再拉低,就直接去写数据了。这肯定就悲剧了。。

  4.还有不能很频繁不断擦除、写入。不然会出错。。。

自己的想法是 写入一个字节在读出用串口发出来。

 2.模拟iic时序 

    2.1起始信号 

先是 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 }

 然后在写稍微高层(针对器件)的时序协议:

写、读一个字节的时序:

  

调用底层时序来完成就行了。

 

posted @ 2019-01-08 10:43  栀子花开fwh  阅读(1276)  评论(0编辑  收藏  举报