ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

IIC总线--C语言实现

2019-08-02 17:03:35  阅读:300  来源: 互联网

标签:write uchar void 总线 C语言 delay IIC byte


原文链接:https://www.cnblogs.com/BitArt/archive/2013/06/01/3112042.html

为了加深对I2C总线的理解,用C语言模拟IIC总线,边看源代码边读波形:

如下图所示的写操作的时序图:

读时序的理解同理。对于时序不理解的朋友请参考“I2C总线之(二)—时序”

完整的程序如下:

复制代码
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define write_ADD 0xa0
#define read_ADD 0xa1
uchar a;
sbit SDA=P2^0;
sbit SCL=P2^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写入0xaa
delay(10); //延时,否则被坑呀!!!
P1=read_add(5); //读取地址5的值
while(1);
}

//***************************************************************************
void delay()//简单延时函数
{ ;; }
//***************************************************************************
void start() //开始信号 SCL在高电平期间,SDA一个下降沿则表示启动信号
{
sda=1; //释放SDA总线
delay();
scl=1;
delay();
sda=0;
delay();
}
//***************************************************************************
void stop() //停止 SCL在高电平期间,SDA一个上升沿则表示停止信号
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
//***************************************************************************
void respons() //应答 SCL在高电平期间,SDA被从设备拉为低电平表示应答
{
uchar i;
scl=1;
delay();
//至多等待250个CPU时钟周期
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
//***************************************************************************
void init()//总线初始化 将总线都拉高一释放总线 发送启动信号前,要先初始化总线。即总有检测到总线空闲才开始发送启动信号
{
sda=1;
delay();
scl=1;
delay();
}
//***************************************************************************
void write_byte(uchar date) //写一个字节
{
uchar i,temp;
temp=date;

for(i=0;i<8;i++)  
{  
    temp=temp<<1;  
    scl=0;//拉低SCL,因为只有在时钟信号为低电平期间按数据线上的高低电平状态才允许变化;并在此时和上一个循环的scl=1一起形成一个上升沿  
    delay();  
    sda=CY;  
    delay();  
    scl=1;//拉高SCL,此时SDA上的数据稳定  
    delay();  
}  
scl=0;//拉低SCL,为下次数据传输做好准备  
delay();  
sda=1;//释放SDA总线,接下来由从设备控制,比如从设备接收完数据后,在SCL为高时,拉低SDA作为应答信号  
delay();  

}
//***************************************************************************
uchar read_byte()//读一个字节
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;//上升沿时,IIC设备将数据放在sda线上,并在高电平期间数据已经稳定,可以接收啦
delay();
k=(k<<1)|sda;
scl=0;//拉低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();//等待从设备的响应
date=read_byte();//获取数据
stop();//停止
return date;//返回数据
}
复制代码

标签:write,uchar,void,总线,C语言,delay,IIC,byte
来源: https://blog.csdn.net/cswuhsdaz/article/details/98212114

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有