一、iic总线介绍
	
		
	
	
		iic(inter-integrated circuit,又称iic)总线是一种由philips公司开发的串行总线,用于连接微控制器及其外围设备,它具有如下特点。
	
	
		
	
	
		(1)只有两条总线线路:一条串行数据线(sda),一条串行时钟线(scl)
	
	
		(2)每个连接到总线的器件都可以使用软件根据它的唯一的地址来识别
	
	
		(3)传输数据的设备间是简单的主/从关系
	
	
		(4)主机可以用作主机发送器或主机接收器
	
	
		(5)它是一个真正的多主机总线,两个或多个主机同时发起数据传输时,可以通过冲突检测和仲裁来防止数据被破坏
	
	
		(6)串行的8位双向数据传输,位速率在标准模式下可达100kbit/s,在快速模式下可达400kbit/s,在高速模式下可达3.4mbit/s
	
 
 
	
		注意:当多个主机试图去控制总线时,通过仲裁可以使得只有一个主机获得总线控制权,并且它传输的信息不被破坏
	
	
		
	
	
		二、iic总线的信号类型
	
	
		
	
	
		iic总线在传送数据过程中共有3种类型信号:开始信号、结束信号和响应信号
	
	
		
	
	
		(1)开始信号(s):scl 为高电平时,sda由高电平向低电平跳变,开始传送数据
	
	
		(2)结束信号(p):scl为低电平时,sda由低电平向高电平跳变,结束传送数据
	
	
		 
	
	
	
		 
	
	
		(3)响应信号(ack):接收器在接收到8位数据后,在第9个时钟周期,拉低sda电平
	
	
		 
	
	
		 
	 
	
		 
	
	
		
		
			注意:sda上传输的数据必须在scl为高电平期间保持稳定,sda上的数据只能在scl为低电平期间变化
		
		
			
		
		
			三、iic总线的数据传输格式
		
		
			
		
		
			发送到sda线上的每个字节必须是8位的,每次传输可以发送的字节数量不受限制。首先传输的是数据的最高位(msb)。
		
		
			 
		
		
		
		
		
			
				启动一个传输时,主机先发送s信号,然后发出8位数据。这8位数据中前7位为从机的地址,第8位表示传输的方向(0表示写操作,1表示读操作)。从机收到后会发出一个ack信号.
			
 
		 
		
		
		
			
				注意:主机接收器在接收到最后一个字节后,也不会发出ack信号。于是,从机发送器释放sda线,以允许主机发出p信号结束传输.
			
			
				
			
			
				四、以eeprom实例讲解
			
			
				
			
			
				先来看看原理图
			
			
				 
			
			
			
			
			
				这里使用的是at24c04型号的eeprom,原理图上标错了,正确的是下面这个 
			
			
				 
			
			
			
				 
			
			
				a.先获得eeprom的作为从设备的地址
			
			
				 
			
			
				 
			 
			
				
				
					
可以看出前4位是固定的,后三位从原理图上可以知道都接地了,所以全为0。这样其地址就为0xa0
				
				
					
				
				
					b.按字节写操作
				
				
					 
				
				
				
				
				
					
				
				
					
						
							- 
								//写eeprom
 
- 
								int write_eeprom(int memaddr,int devaddr,int data)
 
- 
								{
 
- 
								    //发送起始信号 
 
- 
								    start_iic(devaddr,master_send_mode,write);    
 
- 
								    
 
- 
								    while(!get_ack);//wait ack 
 
- 
								    get_ack = 0;
 
- 
								    
 
- 
								    //发送存储地址
 
- 
								    send_iic(memaddr);
 
- 
								    //重新生效 
 
- 
								    resume_iic(ack);
 
- 
								
 
- 
								    while(!get_ack);//wait ack 
 
- 
								    get_ack = 0;
 
- 
								    
 
- 
								    //发送数据 
 
- 
								    send_iic(data);
 
- 
								    //重启iic 
 
- 
								    resume_iic(ack);
 
- 
								
 
- 
								    while(!get_ack);//wait ack 
 
- 
								    get_ack = 0;
 
- 
								    
 
- 
								    //发送停止信号 
 
- 
								    stop_iic(master_send_mode);
 
- 
								    //重启iic 
 
- 
								    resume_iic(ack);
 
- 
								
 
- 
								    delay(100);
 
- 
								
 
- 
								    return 0;
 
- 
								}
							
 
				 
				
				
					
c.按字节读操作
				
				
					 
				
				
				
					 
				
				
					
					
						
							- 
								//读eeprom
 
- 
								int read_eeprom(int memaddr,int devaddr,char *addr)
 
- 
								{
 
- 
								    //发送起始信号 ,写
 
- 
								    start_iic(devaddr,master_send_mode,write);
 
- 
								    
 
- 
								    while(!get_ack);//wait ack 
 
- 
								    get_ack = 0;
 
- 
								    
 
- 
								    //发送存储地址 
 
- 
								    send_iic(memaddr);    
 
- 
								    resume_iic(ack);
 
- 
								    
 
- 
								    while(!get_ack);//wait ack 
 
- 
								    get_ack = 0;
 
- 
								    
 
- 
								    //发送起始信号,读
 
- 
								    start_iic(devaddr,master_recv_mode,read);
 
- 
								    resume_iic(ack);
 
- 
								
 
- 
								    while(!get_ack);//wait ack 
 
- 
								    get_ack = 0;
 
- 
								    
 
- 
								    resume_iic(nack);    
 
- 
								    //接收数据
 
- 
								    recv_iic(addr);
 
- 
								
 
- 
								    //发送停止信号 
 
- 
								    stop_iic(master_recv_mode);
 
- 
								    resume_iic(ack);
 
- 
								
 
- 
								    delay(100);
 
- 
								
 
- 
								    return 0;
 
- 
								}
							
 
					
					
						这里需要注意的是,当中断产生后,需要将iiccon控制器的第4位清0后iic才能正常工作
					
					
						
					
					
						最后附上整个实验的代码:
					
  
				 
			 
		 
	 
                                     
            
            
              
              阅读(5049) | 评论(0) | 转发(0) |