#include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit I2C_SCL = P2^6; //模拟I2C总线的引脚定义 sbit I2C_SDA = P2^7; #define I2C_DELAY_VALUE 12 //定义I2C总线时钟的延时值,要根据实际情况修改,取值1~255 //SCL信号周期约为(I2C_DELAY_VALUE*4+15)个机器周期 #define I2C_STOP_WAIT_VALUE 120 //定义I2C总线停止后在下一次开始之前的等待时间,取值1~65535 //等待时间约为(I2C_STOP_WAIT_VALUE*8)个机器周期 #define I2C_Delay() // 延时,模拟I2C总线专用 { I2C_Delay_t = (I2C_DELAY_VALUE); while ( --I2C_Delay_t != 0 ); } unsigned char data I2C_Delay_t; void I2C_Init() { I2C_SCL = 1; I2C_Delay(); I2C_SDA = 1; I2C_Delay(); } void I2C_Start() //SCL处于高电平期间,当SDA出现下降沿时启动I2C总线 { I2C_SDA = 1; //不论SDA和SCL处于什么电平状态,本函数总能正确产生起始状态 I2C_Delay(); //本函数也可以用来产生重复起始状态 I2C_SCL = 1; //本函数执行后,I2C总线处于忙状态 I2C_Delay(); I2C_SDA = 0; I2C_Delay(); I2C_SCL = 0; I2C_Delay(); } void I2C_Write(char dat) //向I2C总线写1个字节的数据 { unsigned char t = 8; //dat:要写到总线上的数据 do { I2C_SCL = 1; I2C_Delay(); I2C_SCL = 0; I2C_Delay(); I2C_SDA = (bit)(dat & 0x80); dat <<= 1; } while ( --t != 0 ); } bit I2C_GetAck() //读取从机应答位 { bit ack; //从机在收到每个字节的数据后,要产生应答位 I2C_SDA = 1; //从机在收到最后1个字节的数据后,一般要产生非应答位 I2C_Delay(); I2C_SCL = 1; I2C_Delay(); ack = I2C_SDA; I2C_SCL = 0; I2C_Delay(); return ack; //0:从机应答 //1:从机非应答 } void I2C_Stop() //产生I2C总线的停止状态 { unsigned int t = I2C_STOP_WAIT_VALUE; I2C_SDA = 0; I2C_Delay(); //SCL处于高电平期间,当SDA出现上升沿时停止I2C总线 I2C_SCL = 1; //不论SDA和SCL处于什么电平状态,本函数总能正确产生停止状态 I2C_Delay(); //本函数执行后,I2C总线处于空闲状态 I2C_SDA = 1; I2C_Delay(); while ( --t != 0 ); //在下一次产生Start之前,要加一定的延时 } bit I2C_Puts( uchar SlaveAddr, uint SubAddr, uchar SubMod, char *dat, uint Size) { //I2C总线综合发送函数,向从机发送多个字节的数据 unsigned char i; //*dat:要发送的数据 char a[3]; //Size:数据的字节数 if ( Size == 0 ) return 0; //检查长度 a[0] = (SlaveAddr << 1); //SlaveAddr:从机地址(7位纯地址,不含读写位) if ( SubMod > 2 ) SubMod = 2; //SubMod:子地址模式,0-无子地址,1-单字节子地址,2-双字节子地址 switch ( SubMod ) //确定子地址 { case 0: break; case 1: a[1] = (char)(SubAddr); //SubAddr:从机的子地址 break; case 2: a[1] = (char)(SubAddr >> 8); a[2] = (char)(SubAddr); break; default: break; } SubMod++; //发送从机地址,接着发送子地址(如果有子地址的话) I2C_Start(); for ( i=0; i<SubMod; i++ ) { I2C_Write(a[i]); if ( I2C_GetAck() ) { I2C_Stop(); return 1; } } do //发送数据 { I2C_Write(*dat++); if ( I2C_GetAck() ) break; } while ( --Size != 0 ); I2C_Stop(); //发送完毕,停止I2C总线,并返回结果 if ( Size == 0 ) { return 0; } else { return 1; //0:发送成功 1:在发送过程中出现异常 } } #define MAX517_I2C_ADDR 0X58 //MAX517 器件地址 unsigned char num_v ; //MAX517 输出数字量 bit complete_flag; //I2C 通信成功标志 void Delay(unsigned int t) reentrant //延时子程序 { while(--t) { unsigned int j = 110; while(--j); } } char code DX516[3] _at_ 0x3b; //保留0x3b开始的3个字节 main(void) { I2C_Init(); Delay(1000); num_v = 0; complete_flag = I2C_Puts(MAX517_I2C_ADDR,0,1,&num_v,1); Delay(1000); while(1) { num_v ++; complete_flag = I2C_Puts(MAX517_I2C_ADDR,0,1,&num_v,1); Delay(100); } }http://blog.csdn.net/muyexuanwo/article/details/6230431