/i2c模块编程/
#include “i2c.h”//包含i2c.h的头文件(自建的Hex文件用双引号)
void delay()//us级函数
{
;; //晶振为11.0592MHz时,延时约为4~5us
}
/********************起始信号的触发:
SCL在高电平期间,SDA在下降沿时开始起动。
(注意:SDA由高变低之前持续的时间需>4.7us)
**********************/
void start()//起始信号
{
SDA=1;
SCL=1;
delay();
SDA=0;//SDA变为低电平之后,持续时间也要>4us
delay();
}
/********************终止信号的触发:
SCL在高电平期间,SDA一个上升沿结束通信。
(注意:SDA由低变高之前持续的时间需>4.7us)
**********************/
void stop()//终止信号
{
SDA=0;
SCL=1;
delay();
SDA=1;//SDA变为高电平之后,持续时间也要>4us
delay();
}
/********************应答信号的触发:
I2c总线的数据都是以字节(8位数据或者地址及命令)的方式传输的。
发送器每发送一个字节后(8位),在时钟的第九个脉冲期间释放SDA数据线,
由接收器发送一个应答信号(即把数据线拉低,回复一个0)来表示数据接收成功。
(注意:时间需>4.7us)
**********************/
void ack()//应答信号
{
u8 i;
SCL=1; //
delay();
while((SDA==1)&&(i<250)) //若第九个时钟脉冲后,从机无响应,则默认收到数据
i++; //因为程序不能永远停在这,故要设置一个等待时间,之后退出等待
SCL=0;
delay();
}
/********************非应答信号的触发:
非应答信号是主机给从机的一个信号,在第九个时钟脉冲的时候,需要发送非应答
信号“1”(即把SDA置高电平)以通知从机结束数据发送并释放总线,以便主机发送一个
终止信号,最终结束通信
**********************/
void nack()//非应答信号
{
SCL=1;
delay();
SDA=1;
SCL=0;
delay();
}
void write_byte(u8 date)//写一个字节到i2c总线
{
u8 temp,i;
temp=date;
for(i=0;i<8;i++) //循环8次,刚好一个字节
{
temp=temp<<1;//左移一位,让temp的最高位移到状态寄存器的CY位中
SCL=0;
delay();
SDA=CY; //把CY位的值赋给SDA,这样就实现了先传送temp的最高位
delay();
SCL=1;
delay();
}
SCL=0;
delay();
SDA=1; //把SDA数据线释放,因为我们把字节发送完之后,要读取从机的应答信号
delay(); //由于应答信号是低电平,如果不释放SDA数据线变为高电平,则无法判断是不是应答信号
}
void read_byte() //从I2c读取一个字节
{
u8 i,j,n;
SCL=0;
delay();
for(i=0;i<8;i++)//循环8次,刚好一个字节
{
SCL=1;
delay();
j=SDA; //把SDA的值赋给j
n=(n<<1)|j; //n左移一位,最低位为0,而j的数要么是0要么是1,;
SCL=0; //n和j进行或运算后,相当于把j的数放在了n的最低位了
delay();
}
return n;
}
void write_at24c02(u8 address ,u8 date)//字节写入函数
{
start(); //主机发送起始信号
write_byte(0xa0);//主机发送at24c02地址
ack(); //等待at24c02返回一个应答信号
write_byte(address)//主机发送数据的存储地址
ack();
write_byte(date);//主机发送要写入的数据
ack();
stop(); //终止信号,结束本次数据写入
}
u8 read_at24c02(u8 address)//随机读函数
{
u8 date;
start(); //主机发送起始信号
write_byte(0xa0);//主机发送at24c02地址
ack(); //等待at24c02返回一个应答信号
write_byte(address)//主机发送要读取数据的存储地址
ack();
start(); //主机重新发送一个起始信号
date=read_byte(); //读取数据
nack(); //主机发送一个非应答信号
stop(); //主机发送终止信号,结束本次数据读取
return date; //返回date值
}
/**************
i2c.h头文件代码
***************/
#ifndef _I2C_H_
#define _I2C_H_
#include "reg52.h"
#define u8 unsigned char
sbit SDA=P2^0;
sbit SCL=P2^1;
void delay();//分别声明各个函数
void start();
void stop();
void ack();
viod nack();
void write_byte(u8 date);
u8 read_byte();
void write_at24c02(u8 adress ,u8 date);
u8 read_at24c02(u8 adress);
#endif