📄 i2c.c
字号:
#include "I2C.h"
void I2C_Initial( void )
{
//将SCL管脚设置为输出管脚
P1DIR |= SCL;
I2C_Set_sck_low();
I2C_STOP();
Delay_ms(10);
return;
}
void I2C_Set_sda_high( void )
{
//将SDA设置为输出模式
P1DIR |= SDA;
//SDA管脚输出为高电平
P1OUT |= SDA;
_NOP();
_NOP();
return;
}
void I2C_Set_sda_low ( void )
{
//将SDA设置为输出模式
P1DIR |= SDA;
//SDA管脚输出为低电平
P1OUT &= ~(SDA);
_NOP();
_NOP();
return;
}
void I2C_Set_sck_high( void )
{
//将SCL设置为输出模式
P1DIR |= SCL;
//SCL管脚输出为高电平
P1OUT |= SCL;
_NOP();
_NOP();
return;
}
void I2C_Set_sck_low ( void )
{
//将SCL设置为输出模式
P1DIR |= SCL;
//SCL管脚输出为低电平
P1OUT &= ~(SCL);
_NOP();
_NOP();
return;
}
int I2C_GetACK(void)
{
int nTemp = 0;
int j;
_NOP();
_NOP();
I2C_Set_sck_low();
for(j = 30;j > 0;j--);
//将SDA设置为输入方向
P1DIR &= ~(SDA);
I2C_Set_sck_high();
for(j = 30;j > 0;j--);
//获得数据
nTemp = (int)(P1IN & SDA);
I2C_Set_sck_low();
return (nTemp & SDA);
}
void I2C_SetACK(void)
{
I2C_Set_sck_low();
I2C_Set_sda_low();
I2C_Set_sck_high();
I2C_Set_sck_low();
return;
}
void I2C_SetNAk(void)
{
I2C_Set_sck_low();
I2C_Set_sda_high();
I2C_Set_sck_high();
I2C_Set_sck_low();
return;
}
void I2C_START(void)
{
int i;
I2C_Set_sda_high();
for(i = 5;i > 0;i--);
I2C_Set_sck_high();
for(i = 5;i > 0;i--);
I2C_Set_sda_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
return;
}
void I2C_STOP(void)
{
int i;
I2C_Set_sda_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_high();
for(i = 5;i > 0;i--);
I2C_Set_sda_high();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
//延迟一点时间
Delay_ms(10);
return;
}
void I2C_TxHToL(int nValue)
{
int i;
int j;
for(i = 0;i < 8;i++)
{
if(nValue & 0x80)
I2C_Set_sda_high();
else
I2C_Set_sda_low();
for(j = 30;j > 0;j--);
I2C_Set_sck_high();
nValue <<= 1;
for(j = 30;j > 0;j--);
I2C_Set_sck_low();
}
return;
}
void I2C_TxLToH(int nValue)
{
int i;
int j;
for(i = 0;i < 8;i++)
{
if(nValue & 0x01)
I2C_Set_sda_high();
else
I2C_Set_sda_low();
for(j = 30;j > 0;j--);
I2C_Set_sck_high();
nValue >>= 1;
for(j = 30;j > 0;j--);
I2C_Set_sck_low();
}
return;
}
/////////////////////////////////////////////
// 接收是从 LSB 到 MSB 的顺序
int I2C_RxByte(void)
{
int nTemp = 0;
int i;
int j;
I2C_Set_sda_high();
//将SDA管脚设置为输入方向
P1DIR &= ~(SDA);
_NOP();
_NOP();
_NOP();
_NOP();
for(i = 0;i < 8;i++)
{
I2C_Set_sck_high();
if(P1IN & SDA)
{
nTemp |= (0x01 << i);
}
for(j = 30;j > 0;j--);
I2C_Set_sck_low();
}
return nTemp;
}
///////////////////////////////////////////
// 获取时间信息,成功返回 1,错误返回 0
int I2C_Read (char *pBuf)
{
int nTemp = 0;
// 启动数据总线
I2C_START();
// 发送读时间信息命令
I2C_TxHToL(0x65);
// 等待 ACK
nTemp = I2C_GetACK();
pBuf[0] = I2C_RxByte();
I2C_SetACK();
pBuf[1] = I2C_RxByte();
I2C_SetACK();
pBuf[2] = I2C_RxByte();
I2C_SetACK();
pBuf[3] = I2C_RxByte();
I2C_SetACK();
pBuf[4] = I2C_RxByte();
I2C_SetACK();
pBuf[5] = I2C_RxByte();
I2C_SetACK();
pBuf[6] = I2C_RxByte();
I2C_SetACK();
pBuf[7] = I2C_RxByte();
I2C_SetACK();
// 停止总线
I2C_STOP();
return nTemp;
}
///////////////////////////////////////
// 写时间信息,成功返回 1,错误返回 0
int I2C_Write(char *pBuf)
{
int nTemp = 0;
// 启动数据总线
I2C_START();
// 发送写时间信息命令
I2C_TxHToL(0x64);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
I2C_TxLToH(pBuf[0]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
I2C_TxLToH(pBuf[1]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
I2C_TxLToH(pBuf[2]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
I2C_TxLToH(pBuf[3]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
I2C_TxLToH(pBuf[4]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
I2C_TxLToH(pBuf[5]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
I2C_TxLToH(pBuf[6]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
// 停止总线
I2C_STOP();
return (nTemp & SDA);
}
int I2C_Reset(void)
{
int nTemp = 0;
// 启动数据总线
I2C_START();
// 发送复位命令
I2C_TxHToL(0x60);
// 等待 ACK
nTemp = I2C_GetACK();
// 停止总线
I2C_STOP();
return (nTemp & SDA);
}
void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟
{
unsigned long nCount;
int i;
unsigned long j;
nCount = 2667;
for(i = nValue;i > 0;i--)
{
for(j = nCount;j > 0;j--);
}
return;
}
void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟
{
int nCount;
int i;
int j;
nCount = 3;
for(i = nValue;i > 0;i--)
{
for(j = nCount;j > 0;j--);
}
return;
}
int I2C_ReadSta(void)
{
unsigned char nTemp = 0;
// 启动数据总线
I2C_START();
// 发送读状态寄存器命令
I2C_TxHToL(0x63);
// 等待 ACK
nTemp = I2C_GetACK();
nTemp = I2C_RxByte();
I2C_SetACK();
// 停止总线
I2C_STOP();
return nTemp;
}
void I2C_WriteSta(int nValue)
{
int nTemp = 0;
char chrTemp = 0;
chrTemp = (char)(nValue & 0x00ff);
// 启动数据总线
I2C_START();
// 发送写时间信息命令
I2C_TxHToL(0x62);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return;
I2C_TxLToH(chrTemp);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return;
// 停止总线
I2C_STOP();
return;
}
void Set24TimeMode(void)
{
int nTemp;
nTemp = 0;
//读出状态寄存器内容
nTemp = I2C_ReadSta();
nTemp |= BIT6;
//写入状态寄存器
I2C_WriteSta(nTemp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -