- #include "I2C.h"
- void I2C_Initial( void )
- {
- P1DIR |= BIT2; //将SCL管脚(P1.2)设置为输出管脚
- I2C_Set_sck_low();
- I2C_STOP();
- Delay_ms(10);
- return;
- }
- void I2C_Set_sda_high( void )
- {
- P1DIR |= SDA; //将SDA设置为输出模式
- P1OUT |= SDA; //SDA管脚输出为高电平
- _NOP();
- _NOP();
- return;
- }
- void I2C_Set_sda_low ( void )
- {
- P1DIR |= SDA; //将SDA设置为输出模式
- P1OUT &= ~(SDA); //SDA管脚输出为低电平
- _NOP();
- _NOP();
- return;
- }
- void I2C_Set_sck_high( void )
- {
- P1DIR |= SCL; //将SCL设置为输出模式
- P1OUT |= SCL; //SCL管脚输出为高电平
- _NOP();
- _NOP();
- return;
- }
- void I2C_Set_sck_low ( void )
- {
- P1DIR |= SCL; //将SCL设置为输出模式
- P1OUT &= ~(SCL); //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--);
- P1DIR &= ~(SDA); //将SDA设置为输入方向
- //I2C_Set_sda_high();
- 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_TxByte(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;
- }
- /////////////////////////////////////////////
- // 接收是从 LSB 到 MSB 的顺序
- int I2C_RxByte(void)
- {
- int nTemp = 0;
- int i;
- int j;
- I2C_Set_sda_high();
- P1DIR &= ~(SDA); //将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;
- }
- int WriteSingleByte(char nAddr,char nValue)
- {
- int nTemp = 0xA0;//写命令
- // 启动数据总线
- I2C_START();
- // 发送控制字节
- I2C_TxByte(nTemp);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 发送地址字节
- I2C_TxByte(nAddr);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 发送数据字节
- I2C_TxByte(nValue);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 停止总线
- I2C_STOP();
- return (nTemp & SDA);
- }
- int PageWrite(char nAddr,char pBuf[])
- {
- int i;
- int nTemp = 0xA0;//写命令
- // 启动数据总线
- I2C_START();
- // 发送控制字节
- I2C_TxByte(nTemp);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 发送地址字节
- I2C_TxByte(nAddr);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 发送数据字节
- for(i = 0; i < 8;i++)
- {
- I2C_TxByte(pBuf[0]);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- }
- // 停止总线
- I2C_STOP();
- return (nTemp & SDA);
- }
- int ReadRandom(char nAddr, char *nValue)
- {
- //写命令
- int nTemp = 0xA0;
- // 启动数据总线
- I2C_START();
- // 发送控制字节
- I2C_TxByte(nTemp);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 发送地址字节
- I2C_TxByte(nAddr);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 启动数据总线
- I2C_START();
- // 发送控制字节
- nTemp = 0xA1;
- I2C_TxByte(nTemp);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- //读取数据
- *nValue = I2C_RxByte();
- // 停止总线
- I2C_STOP();
- //成功返回
- return 1;
- }
- int ReadSeq(char nAddr, char nValue[], int nLen)
- {
- int i;
- //写命令
- int nTemp = 0xA0;
- // 启动数据总线
- I2C_START();
- // 发送控制字节
- I2C_TxByte(nTemp);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 发送地址字节
- I2C_TxByte(nAddr);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- // 启动数据总线
- I2C_START();
- // 发送控制字节
- nTemp = 0xA1;
- I2C_TxByte(nTemp);
- // 等待 ACK
- nTemp = I2C_GetACK();
- if(nTemp & BIT3) return 0;
- //读取数据
- for(i = 0; i < nLen; i++)
- {
- //读一个字节数据
- nValue[i] = I2C_RxByte();
- //发送ACK
- I2C_SetACK();
- }
- // 停止总线
- I2C_STOP();
- //成功返回
- return 1;
- }
- 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;
- }
- void Init_CLK(void)
- {
- unsigned int i;
- BCSCTL1 = 0X00; //将寄存器的内容清零
- //XT2震荡器开启
- //LFTX1工作在低频模式
- //ACLK的分频因子为1
- do
- {
- // 清除OSCFault标志
- IFG1 &= ~OFIFG;
- for (i = 0x20; i > 0; i--);
- }
- while ((IFG1 & OFIFG) == OFIFG);// 如果OSCFault =1
- //将寄存器的内容清零
- BCSCTL2 = 0X00;
- //MCLK的时钟源为TX2CLK,分频因子为1
- BCSCTL2 += SELM1;
- //SMCLK的时钟源为TX2CLK,分频因子为1
- BCSCTL2 += SELS;
- }
- void main(void)
- {
- char pTime[7];
- int i;
- int nTemp;
- //初始化时钟
- Init_CLK();
- //初始化I2C
- I2C_Initial();
- return ;
- }