#define I2CDelay() {_nop_();_nop_();_nop_();_nop_();} sbit I2C_SCL = P3^7; sbit I2C_SDA = P3^6; /*产生总线起始信号*/ void I2CStart() { I2C_SDA = 1; //首先确保SDA,SCL都是高电平 I2C_SCL = 1; I2CDelay(); I2C_SDA = 0; //首先拉低SDA I2CDelay(); I2C_SCL = 0; //再拉低SCL } /*产生总线停止信号*/ void I2CStop() { I2C_SCL = 0; //首先确保SDA,SCL都是低电平 I2C_SDA = 0; I2CDelay(); I2C_SCL = 1; //首先拉高SCL I2CDelay(); I2C_SDA = 1; //再拉高SDA I2CDelay(); } /*I2C总线写操作,dat为待写入字节,返回值为从机应答位的值*/ bit I2CWrite(unsigned char dat) { bit ack; //用于暂存应答位的值 unsigned char mask; //用于探测字节内某一位值得掩码变量 for(mask = 0x80; mask != 0; mask >>= 1) //从高位到低位一次进行 { if((mask & dat) == 0) //该位的值输出到SDA上 I2C_SDA = 0; else I2C_SDA = 1; I2CDelay(); I2C_SCL = 1; //拉高SCL I2CDelay(); I2C_SCL = 0; //再拉低SCL,完成一个位周期 } I2C_SDA = 1; //8位数据发送完成后,主机释放SDA,以检测从机应答 I2CDelay(); I2C_SCL = 1; //拉高SCL ack = I2C_SDA; //读取此时的SDA值,既为从机的应答位 I2CDelay(); I2C_SCL = 0; //再次拉低SCL完成应答位,并保持住总线 return ack; //返回从机应答值 } /*I2C总线读操作*/ unsigned char I2CRead(bit ack) { unsigned char mask; unsigned char dat; I2C_SDA = 1; for(mask = 0x80; mask != 0; mask >>= 1) { I2CDelay(); I2C_SCL = 1; if(I2C_SDA == 0) dat &= ~mask; else dat |= mask; I2CDelay(); I2C_SCL = 0; } I2C_SDA = ~ ack; I2CDelay(); I2C_SCL = 1; I2CDelay(); I2C_SCL = 0; return dat; }
此代码为学习《手把手教你学51单片机》后编写
版权说明
文章采用: 《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权。版权声明:未标注转载均为本站原创,转载时请以链接形式注明文章出处。如有侵权、不妥之处,请联系站长删除。敬请谅解!