- #include "./head/Head.h"
- #include <intrins.h>
- #define OP_READ 0xa1 // 器件地址以及读取操作
- #define OP_WRITE 0xa0 // 器件地址以及写入操作
- #define MAX_ADDR 0x7f // AT24C02最大地址
- #define ACK 0
- #define NACK 1
- sbit SDA = P1^0;
- sbit SCL = P1^1;
- void I2C_Start();
- void I2C_Stop();
- unsigned char I2C_Shift_In(void);
- uchar I2C_Shift_Out(unsigned char write_data);
- unsigned char Eeprom_Read_Random(unsigned char random_addr,uchar RdData);
- uchar Eeprom_Write_Byte( unsigned char addr, unsigned char write_data);
- uchar Eeprom_Write_Page(uchar Addr,uchar *pWrData,uchar Len);
- void delay_i2c(unsigned char ms);
- uchar Eeprom_Read_Sequential(uchar Addr,uchar *RdBuf,uchar Len);
- static void SomeNop(void)
- {
- uchar n;
- for(n=0;n<30;n++)
- _nop_();
- }
- /*---------------------------------------------------------
- ---------------------------------------------------------*/
- void I2C_ACK(void)
- {
- SDA = 0;
- SomeNop();
- SCL = 1;
- SomeNop();
- SCL = 0;
- _nop_();
- SDA = 1;
- }
- void I2C_NACK(void)
- {
- SDA = 1;
- SomeNop();
- SCL = 1;
- SomeNop();
- SCL = 0;
- SomeNop();
- }
- /*---------------------------------------------------------
- ---------------------------------------------------------*/
- void I2C_Start()
- // 开始位
- {
- SDA = 1;
- SomeNop();
- SCL = 1;
- SomeNop();
- SDA = 0;
- SomeNop();
- SCL = 0;
- SomeNop();
- }
- /*---------------------------------------------------------
- ---------------------------------------------------------*/
- void I2C_Stop()
- {
- SCL = 0;
- SomeNop();
- SDA = 0;
- SomeNop();
- SCL = 1;
- SomeNop();
- SDA = 1;
- }
- /*---------------------------------------------------------
- // 从AT24Cxx移入数据到MCU
- ---------------------------------------------------------*/
- unsigned char I2C_Shift_In(void)
- {
- unsigned char i,read_data;
- SomeNop();
- for(i = 0; i < 8; i++)
- {
- SCL = 1; SomeNop();
- read_data <<= 1;
- read_data |= (unsigned char)SDA;
- SCL = 0; SomeNop();
- }
- return(read_data);
- }
- /*---------------------------------------------------------
- // 从MCU移出数据到AT24Cxx
- ---------------------------------------------------------*/
- uchar I2C_Shift_Out(unsigned char write_data)
- {
- unsigned char i;
- uchar ack_bit;
- SomeNop();
- for(i = 0; i < 8; i++) // 循环移入8个位
- {
- SDA = (bit)(write_data & 0x80);
- SomeNop();
- SCL = 1;
- SomeNop();
- SCL = 0;
- write_data <<= 1;
- SomeNop();
- }
- SDA = 1; //应答已出现在数据线上,释放数据线
- SomeNop();
- SCL = 1;
- SomeNop(); //应答信号应在此SCL为高电平期间保持稳定
- ack_bit = SDA;
- SCL = 0;
- SomeNop();
- return ack_bit; // 返回AT24Cxx应答位
- }
- /*---------------------------------------------------------
- // 在指定地址addr处写入数据write_data
- ---------------------------------------------------------*/
- uchar Eeprom_Write_Byte(unsigned char addr, unsigned char write_data)
- {
- I2C_Start();
- if(NACK == I2C_Shift_Out(OP_WRITE))
- return FALSE;
- if(NACK == I2C_Shift_Out(addr))
- return FALSE;
- if(NACK == I2C_Shift_Out(write_data))
- return FALSE;
- I2C_Stop();
- delay_i2c(255); // 写入周期
- return TRUE;
- }
- /*---------------------------------------------------------
- ---------------------------------------------------------*/
- uchar Eeprom_Write_Page(uchar Addr,uchar *pWrData,uchar Len)
- {
- unsigned char i;
- I2C_Start();
- if(NACK == I2C_Shift_Out(OP_WRITE))
- return FALSE;
- if(NACK == I2C_Shift_Out(Addr))
- return FALSE;
- for(i = 0; i < Len; i++)
- {
- if(NACK == I2C_Shift_Out(*pWrData++))
- return FALSE;
- delay_i2c(255); // 写入周期
- }
- I2C_Stop();
- delay_i2c(255);
- return TRUE;
- }
- /*---------------------------------------------------------
- // 在当前地址读取
- ---------------------------------------------------------*/
- unsigned char Eeprom_Read_Current(uchar RdData)
- {
- I2C_Start();
- if(NACK == I2C_Shift_Out(OP_READ))
- return FALSE;
- RdData = I2C_Shift_In();
- I2C_NACK();
- I2C_Stop();
- return TRUE;
- }
- /*---------------------------------------------------------
- // 在指定地址读取
- ---------------------------------------------------------*/
- unsigned char Eeprom_Read_Random(unsigned char random_addr,uchar RdData)
- {
- I2C_Start();
- if(NACK == I2C_Shift_Out(OP_WRITE))
- return FALSE;
- if(NACK == I2C_Shift_Out(random_addr))
- return FALSE;
- if(FALSE == Eeprom_Read_Current(RdData))
- return FALSE;
- return TRUE;
- }
- /*---------------------------------------------------------
- ---------------------------------------------------------*/
- uchar Eeprom_Read_Sequential(uchar Addr,uchar *RdBuf,uchar Len)
- {
- I2C_Start();
- if(NACK == I2C_Shift_Out(OP_WRITE)) //a0
- return FALSE;
- if(NACK == I2C_Shift_Out(Addr))
- return FALSE;
- I2C_Start();
- if(NACK == I2C_Shift_Out(OP_READ))
- return FALSE;
- while(Len)
- {
- *RdBuf++ = I2C_Shift_In();
- Len--;
- if(Len == 0)
- I2C_NACK();
- else
- I2C_ACK();
- }
- /*
- for(n=0;n<Len;n++) //哈哈,一字之差害我找了好久!
- {
- *RdBuf++ = I2C_Shift_In();
- if(n==Len)
- I2C_NACK();
- else
- I2C_ACK();
- } */
- I2C_Stop();
- return TRUE;
- }
-
- /*---------------------------------------------------------
- //i=220,延时68us
- //i=250,延时76us
- //i=164,延时50.4us
- ---------------------------------------------------------*/
- void delay_i2c(unsigned char n)
- // 延时子程序
- {
- unsigned char i;
- while(n--)
- {
- for(i = 0; i < 164; i++);
- }
- }
C8051F340,48M系统时钟.I2C时钟速度大概35K左右.奉献给楼主拉!
|