#include "reg52.h"
void delay_ms(u16 x)
{
u8 i;
for(;x>0;x--)
{
for(i=217;i>0;i--);
}
}
static void set_sda(u8 lev){
if(lev)
SDA = 1;
else
SDA = 0;
}
static void set_scl(u8 lev){
if(lev)
SCL = 1;
else
SCL = 0;
}
static void sda_input_mode(void){
static void SomeNOP(void)
{
u16 i=14;
while(i--);
}
/*--------------------------------------------------------------------------------
I2C start
---------------------------------------------------------------------------------*/
static void I2CStart(void)
{
set_sda(1);
set_scl(1);
SomeNOP();//INI
set_sda(0);
SomeNOP(); //START
set_scl(0);
}
/*--------------------------------------------------------------------------------
I2C stop
---------------------------------------------------------------------------------*/
static void I2CStop(void)
{
set_sda(0);
SomeNOP(); //INI
set_scl(1);
SomeNOP();
set_sda(1); //STOP
}
/*--------------------------------------------------------------------------------
check ACK
---------------------------------------------------------------------------------*/
static u8 WaitAck(void)
{
u8 errtime=255; //ACK timeout count
set_sda(1);
SomeNOP();
set_scl(1);
SomeNOP();
sda_input_mode();
SomeNOP();
while(SDA)
{ errtime--;
if(!errtime)
{ I2CStop();
return 1;
}
}
set_scl(0);
return 0;
}
/*--------------------------------------------------------------------------------
send no ACK
---------------------------------------------------------------------------------*/
static void SendNotAck(void)
{
set_scl(1);
SomeNOP();
set_sda(1);
SomeNOP();
set_scl(0);
}
/********************************************************
send ACK
*********************************************************/
static void SendAck(void)
{
set_sda(0);
SomeNOP();
set_scl(1);
SomeNOP();
set_scl(0);
SomeNOP();
set_sda(1);
}
/*--------------------------------------------------------------------------------
write byte
---------------------------------------------------------------------------------*/
static void I2CSendByte(u8 ch)
{
u8 i=8;
while(i--)
{
set_scl(0);
SomeNOP();
if(ch&0x80)
set_sda(1);
else
set_sda(0);
ch<<=1;
SomeNOP();
set_scl(1);
SomeNOP();
}
set_scl(0);
}
/*--------------------------------------------------------------------------------
read byte, 0--read with no ack,1--read with ack
---------------------------------------------------------------------------------*/
static u8 I2CReceiveByte(u8 ack)
{
u8 i=8;
u8 dat=0;
set_sda(1);
sda_input_mode();
while(i--)
{
dat<<=1;
set_scl(0);
SomeNOP();
set_scl(1);
SomeNOP();
if(SDA)
dat|=1;
}
set_scl(0);
if(ack){
SendAck();
}else{
SendNotAck();
}
return(dat);
}
/*---------------------------------------------------------------------------------*/
set_scl(1);
}
#define SDA P1^0
#define SCL P1^1
//延时函数,根据MCU时钟不同调整到1msvoid delay_ms(u16 x)
{
u8 i;
for(;x>0;x--)
{
for(i=217;i>0;i--);
}
}
static void set_sda(u8 lev){
if(lev)
SDA = 1;
else
SDA = 0;
}
static void set_scl(u8 lev){
if(lev)
SCL = 1;
else
SCL = 0;
}
static void sda_input_mode(void){
// TODO
}static void SomeNOP(void)
{
u16 i=14;
while(i--);
}
/*--------------------------------------------------------------------------------
I2C start
---------------------------------------------------------------------------------*/
static void I2CStart(void)
{
set_sda(1);
set_scl(1);
SomeNOP();//INI
set_sda(0);
SomeNOP(); //START
set_scl(0);
}
/*--------------------------------------------------------------------------------
I2C stop
---------------------------------------------------------------------------------*/
static void I2CStop(void)
{
set_sda(0);
SomeNOP(); //INI
set_scl(1);
SomeNOP();
set_sda(1); //STOP
}
/*--------------------------------------------------------------------------------
check ACK
---------------------------------------------------------------------------------*/
static u8 WaitAck(void)
{
u8 errtime=255; //ACK timeout count
set_sda(1);
SomeNOP();
set_scl(1);
SomeNOP();
sda_input_mode();
SomeNOP();
while(SDA)
{ errtime--;
if(!errtime)
{ I2CStop();
return 1;
}
}
set_scl(0);
return 0;
}
/*--------------------------------------------------------------------------------
send no ACK
---------------------------------------------------------------------------------*/
static void SendNotAck(void)
{
set_scl(1);
SomeNOP();
set_sda(1);
SomeNOP();
set_scl(0);
}
/********************************************************
send ACK
*********************************************************/
static void SendAck(void)
{
set_sda(0);
SomeNOP();
set_scl(1);
SomeNOP();
set_scl(0);
SomeNOP();
set_sda(1);
}
/*--------------------------------------------------------------------------------
write byte
---------------------------------------------------------------------------------*/
static void I2CSendByte(u8 ch)
{
u8 i=8;
while(i--)
{
set_scl(0);
SomeNOP();
if(ch&0x80)
set_sda(1);
else
set_sda(0);
ch<<=1;
SomeNOP();
set_scl(1);
SomeNOP();
}
set_scl(0);
}
/*--------------------------------------------------------------------------------
read byte, 0--read with no ack,1--read with ack
---------------------------------------------------------------------------------*/
static u8 I2CReceiveByte(u8 ack)
{
u8 i=8;
u8 dat=0;
set_sda(1);
sda_input_mode();
while(i--)
{
dat<<=1;
set_scl(0);
SomeNOP();
set_scl(1);
SomeNOP();
if(SDA)
dat|=1;
}
set_scl(0);
if(ack){
SendAck();
}else{
SendNotAck();
}
return(dat);
}
/*---------------------------------------------------------------------------------*/
void initport(void)
{
set_sda(1);set_scl(1);
}