我测试OK.MCU:S3f9498 晶振: 8.4672MHz
#define I2C_SCL_H Set_P16
#define I2C_SCL_L Clr_P16
#define I2C_SDA_H Set_P17
#define I2C_SDA_L Clr_P17
#define I2C_SDA_IN {P1CONH |= 0x00; P1CONH &= 0x3f;}//00:输入.不同其它IO设置
#define I2C_SDA_OUT {P1CONH |= 0x80; P1CONH &= 0xbf;}//10:输出
#define I2C_SDA_Test Test_P17
I2CIO_GLOBAL void I2C_Init();
I2CIO_GLOBAL void I2C_Delay(unsigned char t);
I2CIO_GLOBAL unsigned char I2C_InPut(unsigned char SlaveAddr,unsigned char SonAddr,unsigned char *dat,unsigned char count);
I2CIO_GLOBAL unsigned char I2C_OutPut(unsigned char SlaveAddr,unsigned char SonAddr,unsigned char *dat,unsigned char count);
#define IIC_CLOCK_DELAY 50
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void I2C_Delay(unsigned char t)
{
while (t--)
{
Clr_WatchDog;
Clr_WatchDog;
}
}
void I2C_Init()
{
//I2C_SCL_C = 0;//P4.6输出模式
//I2C_SDA_C = 0;//P4.7输出模式
I2C_SDA_OUT;
//I2C_SCL = 1;
I2C_SCL_H;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SDA = 1;
I2C_SDA_H;
I2C_Delay(IIC_CLOCK_DELAY);
}
void I2C_Start(void)
{
//I2C_SDA = 1;
I2C_SDA_H;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SCL = 1;
I2C_SCL_H;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SDA = 0;
I2C_SDA_L;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SCL = 0;
I2C_SCL_L;
I2C_Delay(IIC_CLOCK_DELAY);
}
void I2C_Stop(void)
{
//I2C_SCL = 1;
I2C_SCL_H;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SDA = 0;
I2C_SDA_L;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SDA = 1;
I2C_SDA_H;
I2C_Delay(IIC_CLOCK_DELAY);
}
char I2C_GetAck(void)
{
char ack;
//I2C_SDA_C = 1; //检测应答信号,把信号线p4.7改为输入模式
I2C_SDA_IN;
//I2C_SCL = 1;
I2C_SCL_H;
I2C_Delay(IIC_CLOCK_DELAY);
//ack=I2C_SDA;
if (I2C_SDA_Test)
{
ack = 1;
}
else
{
ack = 0;
}
//I2C_SCL = 0;
I2C_SCL_L;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SDA_C = 0; //得到应答信号,把信号线该成输出模式
I2C_SDA_OUT;
//I2C_SDA = 0;
I2C_SDA_L;
return ack;
}
void I2C_PutAck(unsigned char ack0) //主机接收数据的应答,如果ACK0=0,应答,如果ACK0=1,不应答
{
//I2C_SDA = ack0&0x01;
if (ack0&0x01)
{
I2C_SDA_H;
}
else
{
I2C_SDA_L;
}
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SCL = 1;
I2C_SCL_H;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SCL = 0;
I2C_SCL_L;
I2C_Delay(IIC_CLOCK_DELAY);
}
void I2C_Write(unsigned char dat) //发送8位数据,高位在前
{
unsigned char i;
for(i=8;i>0;i--)
{
//I2C_SDA=0;
I2C_SDA_L;
if(dat & 0x80)
{
//I2C_SDA=1;
I2C_SDA_H;
}
dat <<= 1;
//I2C_SCL = 1;
I2C_SCL_H;
I2C_Delay(IIC_CLOCK_DELAY);
//I2C_SCL = 0;
I2C_SCL_L;
I2C_Delay(IIC_CLOCK_DELAY);
}
}
unsigned char I2C_Read(void) //接收8位数据
{
unsigned char i,dat;
//I2C_SDA_C=1; //改变数据线P4.7的模式位输入模式,
I2C_SDA_IN;
for(i=8;i>0;i--)
{
//I2C_SCL = 1;
I2C_SCL_H;
I2C_Delay(IIC_CLOCK_DELAY);
dat <<= 1;
//if(I2C_SDA)
//{
//dat++;
//}
if (I2C_SDA_Test)
{
dat++;
}
//I2C_SCL = 0;
I2C_SCL_L;
I2C_Delay(IIC_CLOCK_DELAY);
}
//I2C_SDA_C=0; //接收完毕,数据线P4.7改回输出模式
I2C_SDA_OUT;
//I2C_SDA=0;
I2C_SDA_L;
return dat;
}
/*输入从机地址,从机子地址,输入数据数组或指针,数据位数*/
unsigned char I2C_InPut(unsigned char SlaveAddr,unsigned char SonAddr,unsigned char *dat,unsigned char count)
{
SlaveAddr &= 0xfe; //从机地址最后位该为0,是写入模式
I2C_Start(); //发送开始信号
I2C_Write(SlaveAddr); //发送从机地址
if (I2C_GetAck())
{
I2C_Stop();
I2C_ASK = 1;
return 1;
} //如果有应答,继续,否则返回1结束
I2C_Write(SonAddr); //发送从机子地址,就是EEPROM的内存地址
if (I2C_GetAck()){ I2C_Stop();return 1; }
while(count--) //发送数据
{
I2C_Write(*dat++); //写入数据
if (I2C_GetAck()){ I2C_Stop();return 1; }
}
I2C_Stop();
return 0;
}
/*从EEPROMZ中读出数据*/
unsigned char I2C_OutPut(unsigned char SlaveAddr,unsigned char SonAddr,unsigned char *dat,unsigned char count)
{
SlaveAddr &= 0xfe;
I2C_Start();
I2C_Write(SlaveAddr);
if (I2C_GetAck()){ I2C_Stop();return 1; }
I2C_Write(SonAddr);
if (I2C_GetAck()){ I2C_Stop();return 1; } //前面为伪写
I2C_Start(); //重发开始信号
SlaveAddr |= 0x01; //该为读出模式
I2C_Write(SlaveAddr);
if (I2C_GetAck()){ I2C_Stop();return 1; }
while(count--)
{
*dat++=I2C_Read();
I2C_PutAck(0);
}
I2C_PutAck(1);
I2C_Stop();
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
主程序调用
DI;
I2C_InPut(0xA0,0x01,I2C_DAT_Temp,2);
DelayMs(10);
I2C_OutPut(0xA0,0x01,I2C_DAT_Temp2,2);
EI;
文章评论(0条评论)
登录后参与讨论