网站注册 优帮云,网络销售培训学校,wordpress打分免插件,东莞市产品网络推广为了加深对I2C总线的理解#xff0c;用C语言模拟IIC总线#xff0c;边看源代码边读波形#xff1a;
如下图所示的写操作的时序图#xff1a; 读时序的理解同理。对于时序不理解的朋友请参考“I2C总线之(二)---时序”
完整的程序如下#xff1a; #includereg51.h…为了加深对I2C总线的理解用C语言模拟IIC总线边看源代码边读波形
如下图所示的写操作的时序图 读时序的理解同理。对于时序不理解的朋友请参考“I2C总线之(二)---时序”
完整的程序如下 #includereg51.h
#define uchar unsigned char
#define uint unsigned int
#define write_ADD 0xa0
#define read_ADD 0xa1
uchar a;
sbit SDAP2^0;
sbit SCLP2^1;
void SomeNop(); //短延时
void init(); //初始化
void check_ACK(void)
void I2CStart(void);
void I2cStop(void);
void write_byte(uchar dat);//写字节
void delay(uint z);
uchar read_byte(); //读字节
void write(uchar addr,uchar dat); //指定地址写
uchar read(uchar addr); //指定地址读
bit flag; //应答标志位
void main()
{init();write_add(5,0xaa); //向地址5写入0xaadelay(10); //延时,否则被坑呀P1read_add(5); //读取地址5的值while(1);
}//***************************************************************************
void delay()//简单延时函数
{ ;; }
//***************************************************************************
void start() //开始信号 SCL在高电平期间SDA一个下降沿则表示启动信号
{ sda1; //释放SDA总线 delay(); scl1; delay(); sda0; delay();
}
//***************************************************************************
void stop() //停止 SCL在高电平期间SDA一个上升沿则表示停止信号
{ sda0; delay(); scl1; delay(); sda1; delay();
}
//***************************************************************************
void respons() //应答 SCL在高电平期间SDA被从设备拉为低电平表示应答
{ uchar i; scl1; delay(); //至多等待250个CPU时钟周期 while((sda1)(i250))i; scl0; delay();
}
//***************************************************************************
void init()//总线初始化 将总线都拉高一释放总线 发送启动信号前要先初始化总线。即总有检测到总线空闲才开始发送启动信号
{ sda1; delay(); scl1; delay();
}
//***************************************************************************
void write_byte(uchar date) //写一个字节
{ uchar i,temp; tempdate; for(i0;i8;i) { temptemp1; scl0;//拉低SCL因为只有在时钟信号为低电平期间按数据线上的高低电平状态才允许变化并在此时和上一个循环的scl1一起形成一个上升沿 delay(); sdaCY; delay(); scl1;//拉高SCL此时SDA上的数据稳定 delay(); } scl0;//拉低SCL为下次数据传输做好准备 delay(); sda1;//释放SDA总线接下来由从设备控制比如从设备接收完数据后在SCL为高时拉低SDA作为应答信号 delay();
}
//***************************************************************************
uchar read_byte()//读一个字节
{ uchar i,k; scl0; delay(); sda1; delay(); for(i0;i8;i) { scl1;//上升沿时IIC设备将数据放在sda线上并在高电平期间数据已经稳定可以接收啦 delay(); k(k1)|sda; scl0;//拉低SCL使发送端可以把数据放在SDA上 delay(); } return k;
}
//***************************************************************************
void write_add(uchar address,uchar date)//任意地址写一个字节
{ start();//启动 write_byte(0xa0);//发送从设备地址 respons();//等待从设备的响应 write_byte(address);//发出芯片内地址 respons();//等待从设备的响应 write_byte(date);//发送数据 respons();//等待从设备的响应 stop();//停止
}
//***************************************************************************
uchar read_add(uchar address)//读取一个字节
{ uchar date; start();//启动 write_byte(0xa0);//发送发送从设备地址 写操作 respons();//等待从设备的响应 write_byte(address);//发送芯片内地址 respons();//等待从设备的响应 start();//启动 write_byte(0xa1);//发送发送从设备地址 读操作 respons();//等待从设备的响应 dateread_byte();//获取数据 stop();//停止 return date;//返回数据
}