如何实现ADuC7026主从机IIC通信
0赞
发表于 12/14/2011 12:41:21 PM
阅读(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; }; } }
