yanniwang

如何实现ADuC7026主从机IIC通信

0
阅读(4847)

ADuC7026支持两个I2C总线接口,I2C(Inter-Integrated Circuit)总线是由飞利浦公司开发的两线式串行总线,用于连接MCU及其外围设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。

ADuC7026I2C总线协议基于主从工作模式。在总线上建立数据传输、生成同步时钟信号并结束数据传输的设备为主机。被主控机寻址的设备为从机。主控机和从控机都可以作为发送端(向总线发送数据的设备)或接收端(从总线接收数据的设备),但是主控机一直控制着数据的传输方向。

I2C总线最主要的优点是其简单性和有效性。由于接口直接连接在外围组件上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。ADuC7026总线最大长度可达7.6m,最大传输速率可达400kpbs。

 

在I2C总线的实现中包含两条传输线,即串行时钟传输线(SCL)和串行数据传输线(SDA)。这两条传输线都可以双向传输,应用时必须经过电阻上拉,考虑到系统的稳定性和抗干扰能力,其上拉电阻的选择与总线速率有关。

下面是分别是I2C通讯中主机和从机的程序。在这个程序运行中,主机和从机都有两种状态,即发送和接收。在I2C传送开始时,主机发送出一个地址,这个地址的最低位决定主机的发送或接收状态,LSB=0,主机发送;LSB=1,主机接收。

I2C主机程序
#include				   //头文件包含

void delay(int);                       //延时子程序
void IRQ_Handler() __irq;             //常规中断服务子程序

#define count 0x4;					
int i = 0, dat[5];					

int main()
{
 	
 	GP1CON = 0x22;					// 设置I2C各功能引脚
	I2C0CFG = 0x82;		  			// 使能I2C0主机及其串行时钟
 // I2C主机设置
 	I2C0DIV = 0xCFCF;				// 设置I2C0串行时钟频率,0xCFCF对应100kHz
	IRQEN = 0x400;					// 使能I2C0主机中断  
	// 发送
	I2C0ADR = 0xA0;	 			    // 设定I2C地址	 (LSB = 0, 主机发送)
	I2C0MTX = 0x55;				    //发送 I2C 字节地址
	 
	delay(4000);	 
		 
	// 接收
	i = 0;
	I2C0CNT = 	count;				// 从从机接收的字节数
	I2C0ADR = 	0xA1;	 			// 设定I2C地址(LSB = 1, 主机接收)	
	
	while (1)
	{
	};

 	return 0;
}

void delay (int length)
{
	while (length >0)
    	length--;
}

void IRQ_Handler() __irq
{
	if(((I2C0MSTA & 0x4) == 0x4) && (i < 8))	//主机发送
	{
		i++;							    // 发送数据1-8
		I2C0MTX = i;
	}		
	if((I2C0MSTA & 0x8) == 0x8)		    // 主机接收
	{
		dat[i] = I2C0MRX;
		i++;
	}
}
I2C从机程序
#include
void IRQ_Handler() __irq;
int i = 0, dat[9];

int main()
{
	
 	GP1CON = 0x22;                  // 设置I2C功能引脚
	IRQEN = 0x200;					// 12C0从机中断
	I2C0CFG = 0x01;		  			// 从机使能
	I2C0ID0 = 0xA0;					//从机设备ID
	I2C0STX = 0x77;
	
	while (1)
	{
	}; 
 	return 0;
}

/*常规中断服务子程序*/
void IRQ_Handler() __irq
{
		if ((I2C0SSTA & 0x08)==0x08)  //从机接收
	{
	 	   dat[i] = I2C0SRX;
		   i++;
	}
	if ((I2C0SSTA & 0x04)==0x04)   	// 从机发送
	{
		 if(i > 4) 			      
		 {
		 	i = 0;
		 }
		 i++;
		 switch (i)
		 {
			case 1:
				I2C0STX = 0x55;
			break;
			case 2:						
				I2C0STX = 0x33;
			break;
			case 3:						
				I2C0STX = 0xAA;
			break;
			case 4:						
				I2C0STX = 0x11;
			break;
		};
	}
}