#include <reg51.h>
#include "delay.h"
#include "IIC.h"
sbit SDA = P2^0;
sbit SCL = P2^1;
/**********************************************************
啟動子程序
在 SCL 高電平期間 SDA 發生負跳變
**********************************************************/
void I2C_start()
{
SDA = 1;
SCL = 1;
delayNOP();
SDA = 0;
delayNOP();
SCL = 0;
}
/**********************************************************
停止子函數
在 SCL 高電平期間 SDA 發生正跳變
**********************************************************/
void I2C_stop()
{
SDA = 0;
SCL = 1;
delayNOP();
SDA = 1;
delayNOP();
}
/**********************************************************
發送應答位子函數
在 SDA 低電平期間 SCL 發生一個正脈沖
**********************************************************/
void iic_ack()
{
SDA = 0;
SCL = 1;
delayNOP();
SCL = 0;
NOP;
SDA = 1;
}
/**********************************************************
發送非應答位子函數
在 SDA 高電平期間 SCL 發生一個正脈沖
**********************************************************/
void iic_noack()
{
SDA = 1;
SCL = 1;
delayNOP();
SCL = 0;
delayNOP();
SDA = 0;
}
/**********************************************************
應答位檢測子函數
**********************************************************/
bit iic_testack()
{
bit ack_bit;
SDA = 1; //置SDA為輸入方式
SCL = 1;
delayNOP();
ack_bit = SDA;
SCL = 0;
NOP;
return ack_bit; //返回應答位
}
/**********************************************************
發送一個字節子程序
**********************************************************/
unsigned char I2C_write_byte(unsigned char indata)
{
unsigned char i, ack;
// I2C 發送8 位數據
for (i=0; i<8; i++)
{
// 高在前低在后
if (indata & 0x80)
SDA = 1;
else
SDA = 0;
// 發送左移一位
indata <<= 1;
delayNOP();
SCL = 1;
delayNOP();
SCL = 0;
}
// 設置SDA為輸入
SDA =1;;
delayNOP();
// 讀取從機應答狀態
SCL = 1;
delayNOP();
if(SDA)
{
ack = I2C_NACK;
}
else
{
ack = I2C_ACK;
}
SCL = 0;
return ack;
}
/**********************************************************
讀一個字節子程序
**********************************************************/
unsigned char I2C_read_byte(unsigned char ack)
{
unsigned char i, data1 = 0;
// SDA 設置輸入方向
SDA = 1;
// I2C 接收8位數據
for(i = 8; i > 0; i--)
{
data1 <<= 1;
SCL = 1;
delayNOP();
// 高在前低在后
if (SDA)
{
data1++;
}
SCL = 0;
delayNOP();
}
// 主機發送應答狀態
if(ack == I2C_ACK)
SDA = 0;
else
SDA = 1;
delayNOP();
SCL = 1;
delayNOP();
SCL = 0;
return data1;
}
/*********************************************************/