1. 代码
#include "eeprom.h"
#define SCL_H GPIO_BOP(GPIOB) = GPIO_PIN_1
#define SCL_L GPIO_BC(GPIOB) = GPIO_PIN_1
#define SDA_H GPIO_BOP(GPIOB) = GPIO_PIN_2
#define SDA_L GPIO_BC(GPIOB) = GPIO_PIN_2
#define SDA_OUT
#define SDA_IN
#define GetSDA() gpio_input_bit_get(GPIOB,GPIO_PIN_2)
#define twr_delay()
#define delay() delay_10us(1)
#define WDTFeed()
void delay_10us(uint32_t n)
{
uint32_t t;
while(n--)
{
t = 180;
while(t--)
{
}
}
}
void I2C_Init(void)
{
}
void i2cStart(void)
{
SDA_H;
delay();
SCL_H;
delay();
SDA_L;
delay();
SCL_L;
delay();
}
void i2cStop(void)
{
SDA_L;
delay();
SCL_H;
delay();
SDA_H;
delay();
}
uint8_t i2cAck(void)
{
uint8_t i;
i = 0;
SDA_H;
SDA_IN;
delay();
SCL_H;
delay();
while(GetSDA() == 1)
{
i ++;
if(i > 30)
{
i2cStop();
return 1;
}
}
SCL_L;
delay();
SDA_OUT;
SDA_L;
delay();
return 0;
}
void i2cNack(void)
{
SDA_H;
delay();
SCL_H;
delay();
SCL_L;
delay();
SDA_L;
delay();
}
void write_byte(uint8_t date)
{
uint8_t i;
SCL_L;
delay();
for(i=0;i<8;i++)
{
if(date&0x80)
{
SDA_H;
}
else
{
SDA_L;
}
delay();
SCL_H;
delay();
SCL_L;
delay();
date <<= 1;
}
i2cAck();
}
uint8_t read_byte(void)
{
uint8_t i,j,n;
n = 0;
SCL_L;
delay();
SDA_IN;
for(i=0;i<8;i++)
{
SCL_H;
delay();
j = GetSDA();
n = (n<<1) | j;
SCL_L;
delay();
}
SDA_OUT;
SDA_L;
delay();
return n;
}
void i2cMasterAck(void)
{
SDA_L;
delay();
SCL_H;
delay();
SCL_L;
delay();
SDA_L;
delay();
}
void AT24C64_W(u8 *buf,uint16_t addr,uint16_t count)
{
while(count--)
{
WDTFeed();
i2cStart();
write_byte( 0xa0 );
write_byte( (uint8_t)(addr>> 8));
write_byte( (uint8_t)(addr& 0xFF));
write_byte( *buf);
i2cStop();
twr_delay();
buf ++;
addr ++;
}
}
void AT24C64_R(uint8_t *buf,uint16_t addr,uint16_t count)
{
while(count--)
{
WDTFeed();
i2cStart();
write_byte( 0xa0 );
write_byte( (uint8_t)(addr>> 8));
write_byte( (uint8_t)(addr& 0xFF));
i2cStart();
write_byte( 0xa1 );
*buf = read_byte();
i2cNack();
i2cStop();
buf ++;
addr ++;
}
}
void AT24C64_W16(u16 data16,uint16_t addr)
{
u8 buf[2];
buf[0] = data16;
buf[1] = data16 >> 8;
AT24C64_W(buf,addr,2);
}
u16 AT24C64_R16(uint16_t addr)
{
u16 data16;
u8 buf[2];
AT24C64_R(buf,addr,2);
data16 = buf[1];
data16 <<= 8;
data16 += buf[0];
return(data16);
}
2. 实测波形
0x00-0x04地址写0x01~0x05 MCU读ACK时机,在T2前一刻,读为0,SCL拉低后,SDA即时拉高
0x1F地址写0x1F NACK
|