I2C总线普通IO口模拟编程示例
- 格式:pdf
- 大小:159.25 KB
- 文档页数:8


应用笔记494 利用MAX II CPLD 的I 2C 总线接口实现GPIO 引脚扩展引言本设计实例展示了Altera ® MAX ® II CPLD 通过工业标准I 2C 总线提供通用I/O (GPIO) 引脚扩展的能力。
为了减小封装尺寸和引脚数量,很多微处理器系统限制了通用I/O 的数量。
然而,如果系统有I 2C 接口,那么本设计可以通过I 2C 总线来加入更多的 GPIO 引脚。
借助于MAX IICPLD ,增加的这些GPIO 引脚要比微处理器的I/O 引脚功耗低。
GPIO 引脚扩展和I 2C在某些情况下,可能需要通过较长的PCB 走线来访问系统中的GPIO 引脚(例如蜂窝电话中不同部分的连接)。
I 2C 接口是2线系统,本设计通过普通的2线走线,在远端提供多个输入和输出引脚。
这提高了设计灵活性以及整个系统的物理紧凑性,还减小了封装尺寸和引脚数量。
可以通过这些通用输出引脚来连接并控制风扇控制器、LED 状态显示和状态指示器等设备。
同样的,复位引脚和按钮开关等设备可以直接连接到CPLD 的通用输入上,实现各种应用。
图1.通过I 2C 总线实现GPIO 引脚扩展2007年12月,1.0版利用MAX II CPLD的I2C总线接口实现GPIO引脚扩展GPIO引脚扩展的I2C接口MAX II CPLD用作I2C总线从机,在其I2C接口上有两个引脚:I2C时钟SCL和I2C 数据线SDA。
作为 I2C主机的主系统和MAX II(用作 I2C从机)进行通信。
CPLD为主系统提供8个通用输入端口和8个通用输出端口。
GPIO引脚并行接收 I2C总线串行发送的数据。
这样,可以同时读写所有8个通用I/O。
I2C接口对于I2C接口,CPLD(I2C从机)提供一个符合常用I2C 协议的内置7位地址。
主机发送起始信号,然后是7位地址和一个R/W位。
当I2C总线上广播的地址和从机设备的地址匹配时,根据主机发送的读或者写信号,设备发送一个ACK (应答)信号,然后是数据。
/*说明,该程序是模拟IIC的通信思想,但也不全是,首先本人设计的不是从机与主机的通信,而是两单片机是平等的,单片机A可以向B或其他任何单片机发送数据(通过各个单片机所设置的地址来加以区分),同时单片机A可以也向B或其他任何单片机读取数据。
反之单片机B或其他单片机也可以向A发送数据或读取A的数据,所以各个单片机的代码基本上是一样的,只需根据具体不同的需要调用就行。
由于本人初学单片机,代码写的并不是很好。
望各位多多指教!!!*///单片机A 的代码#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define LOC_address 0x48sbit sda=P1^0;sbit scl=P1^1;sbit STROBE = P1^2;bit R_W;bit START_flag=0;uchar DEV_address;void delay(){uint i;for(i=0;i<=100;i++);}void init(){sda=1;scl=1;STROBE=1;}void start() //启动I2C总线{sda = 1;delay();scl = 1;delay();sda = 0;delay();// 此处scl不能拉低,否则两单片机通信时时序无法保持一致}/*void start_scan(){bit PreState;bit NowState;char NN = 10;PreState = sda; //记录当前SDA状态,用作比较while(scl == 1 && NN--){NowState = sda;if(PreState == 1 && NowState == 0) //如果为下降沿则为开始信号{START_flag = 1;}}}*/void Send_Date(uchar j){unsigned char i;bit temp;scl = 1;while(STROBE);if(STROBE==0){ delay();delay();delay();for (i = 0 ;i < 8 ;i++){if((j<<i)&0x80)temp=1;else temp=0;sda = temp; 、delay();scl = 0;delay();scl = 1;delay();}scl = 0;sda = 1; //释放数据线delay();STROBE=1;}STROBE=1;}uchar Receive_Date(){uchar i,j,k=0xff;scl = 1;STROBE=0;delay();if((!scl)&&(sda)){return k;}if(STROBE==0){while(scl);for(i=0;i<8;i++){while(!scl);if(sda==1)j=1;elsej=0;k=(k<<1)|j;delay();delay();while(scl);}P2=k;return k;}return k;}/*void ChackRdd(){uchar i,j,k=0xff;scl = 1;STROBE=0;delay();if(!STROBE){while(scl);for(i=0;i<8;i++){while(!scl);if(sda==1)j=1;elsej=0;k=(k<<1)|j;delay();delay();while(scl);}P0=k;R_W=k&0x01;DEV_address=(k&0xfe);STROBE=1;}STROBE=1;}void B_work(){if(STROBE){ChackRdd();if(DEV_address==LOC_address){if(R_W){STROBE=(~STROBE);Send_Date(0x55);}else if(!R_W){STROBE=(~STROBE);Receive_Date();}}}}*/void main(){init();while(1)//以下为测试代码。