• I2C总线之(三)---以C语言理解IIC


    I2C总线之(三)---以C语言理解IIC

    为了加深对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;//返回数据 }
  • 相关阅读:
    转 Xcode调试技巧 EXC_BAD_ACCESS
    qq web协议(转)
    iphone 调试技巧
    转Xcode 调试技巧 XCode调试技巧–设置全局断点快速定位问题代码所在行[zz]
    xcode 允许SVN管理项目文件
    mql4如何自定义画图
    mql相关知识
    iphone 使用委托(delegate)在不同的窗口之间传递数据
    关于同一工单中上万笔序号的一次性生成
    SharpDevelop使用心得
  • 原文地址:https://www.cnblogs.com/muhuacat/p/7246017.html
Copyright © 2020-2023  润新知