旭日东起 发表于 2014-1-10 14:25
思路是对的,但读写函数有没有对,我就不知道了
这是我写的AT24c02的读写程序:::(请高手看看)
//微秒级延时函数(晶振为11.0592MHz, 延时大概4~5微秒, 用来操作I2C总线用)
void delay()
{
;
;
}
//发送启动信号: scl为高电平期间, sda发生负跳变
void start()
{
sda = 1;
delay();
scl = 1;
delay();
sda = 0;
delay();
}
//发送停止信号: scl为高电平, sda发生正跳变
void stop()
{
sda = 0;
delay();
scl = 1;
delay();
sda = 1;
delay();
}
//应答信号: scl为高电平期间, sda被接受设备拉为低电平, 最后scl置0
void response()
{
uchar i;
scl = 1;
delay();
while((sda == 1) && (i < 250))
i++;
scl = 0;
delay();
}
//总线初始化: 将总线拉高以释放总线
void init()
{
sda = 1;
delay();
scl = 1;
delay();
}
//写字节数据: 将8位数据通过左移到CY(进位),然后赋值给数据线SDA
//每发送一位,scl出现正跳变
//发送完数据后,需要将scl置0, sda置1
void write_byte(uchar dat)
{
uchar i, temp;
temp = dat;
for (i = 0; i < 8; i++)
{
temp = temp << 1;
scl = 0;
delay();
sda = CY;
delay();
scl = 1;
delay();
}
scl = 0;
delay();
sda = 1;
delay();
}
//读字节数据: 将数据一位一位从sda中获取, 每读取一位scl出现负跳变
//通过变量k将8位数据整合为1个字节数据
//读数据前, 先将scl置0, sda置1
uchar read_byte()
{
uchar i, k;
scl = 0;
delay();
sda = 1;
delay();
for (i = 0; i < 8; i++)
{
scl = 1;
delay();
k = (k << 1) | sda;
scl = 0;
delay();
}
return k;
}
//特定地址写数据
void write_add(uchar address, uchar dat)
{
//发送启动信号
start();
//发送控制字
//at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
//1010对应16进制为a, R/W为0(写操作), 合并起来就是0xa0
write_byte(0xa0);
//写入地址后,需要响应
response();
//送一个字节存储单元的子地址
write_byte(address);
//写入地址后,需要响应
response();
//发送8为数据位
write_byte(dat);
//响应信号
response();
//发送停止信号
stop();
}
//特定地址读数据
uchar read_add(uchar address)
{
uchar dat;
//发送启动信号
start();
//发送写控制字
//at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
//1010对应16进制为a, R/W为0(写操作), 合并起来就是0xa0
write_byte(0xa0);
//写入地址后,需要响应
response();
//送一个字节存储单元的子地址
write_byte(address);
//写入地址后,需要响应
response();
//发送启动信号
start();
//发送读控制字
//at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
//1010对应16进制为a, R/W为1(读操作), 合并起来就是0xa1
write_byte(0xa1);
//读地址后,需要响应
response();
//读取数据赋值给变量dat
dat = read_byte();
//发送停止信号
stop();
return dat;
} |