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

发布者:月光男孩最新更新时间:2015-05-21 来源: iianews关键字:I2C总线  C语言 手机看文章 扫描二维码
随时随地手机看文章

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

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

 

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

完整的程序如下:

 

#include
#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();  
}  
//***************************************************************************  [page]
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;//返回数据  
}

关键字:I2C总线  C语言 引用地址:I2C总线之(三)---以C语言理解IIC

上一篇:I2C总线之(二)---时序
下一篇:赛普拉斯用于USB Type-C的USB电力传送控制器获得USB-IF认证

推荐阅读最新更新时间:2024-05-02 23:43

基于NRF24L01无线模块的STC89C52单片机接收(RX)C语言程序
此程序为NRF24L01无线模块的接收程序,RevTempDate是用来存放接收到的数据,最后一位存放结束码。 #include reg52.h #define unchar unsigned char #define unint unsigned int /*******************************************************/ #define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节 #define RX_ADDR_WITDH 5//接收地址宽度设置为5个字节 #define TX_DATA_WITDH 4//发送数据宽度1个字节 #define RX_DATA_WI
[单片机]
单片机_C语言函数_中断函数(中断服务程序)
在开始写中断函数之前,我们来一起回顾一下,单片机的中断系统。 中断的意思(学习过微机原理与接口技术的同学,没学过单片机,也应该知道),我们在这里就不讲了,首先来回忆下中断系统涉及到哪些问题。 (1)中断源:中断请求信号的来源。(8051有3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1(这两个低电平有效,上面的那个横杠不知道怎么加上去)) (2)中断响应与返回:CPU采集到中断请求信号,怎样转向特定的中断服务子程序,并在执行完之后返回被中断程序继续执行。期间涉及到CPU响应中断的条件,现场保护,现场恢复。 (3)优先级控制:中断优先级的控制就形成了中断嵌套(8051允许有两级的中断嵌套
[单片机]
基于I2C总线的锅炉温度测量系统的设计与实现
单片机作为典型的嵌入式控制器,具有集成度高、处理功能强、运行速度快、体积小、扩展灵活等优势,在仪器仪表、家用电器、过程控制等领域被广泛应用。锅炉温度是工业过程中最常见的工艺参数之一,其测量过程的抗干扰能力和测量值的精度是影响对锅炉温度控制效果的重要因素。为使系统更智能化,一般选择单片机为系统控制核心。但是,传统的单片机测量系统中实现A/D转换结果输出以及各器件之间的数据传递大多采用并行的通信方式,这种数据交换方式占用了大量的I/O资源,系统结构也因此变得复杂。同时大量的硬件连线也会带来很多干扰因素,降低了锅炉温度值的测量精度。为了解决传统设计中存在的问题,本文提出使用Philips公司推出的I2C总线(Inter Integrate
[测试测量]
基于<font color='red'>I2C总线</font>的锅炉温度测量系统的设计与实现
基于单片机的温度传感器18b20的C语言程序
代码是在12M的晶振的晶振下调试出来的,希望可以给大家带来参考价值 #include reg51.h //51芯片管脚定义头文件 #include intrins.h //内部包含延时函数 _nop_(); #include stdio.h #define uchar unsigned char #define uint unsigned int uchar Flag=0; //定义一个全局的标志位 uchar Feng=0; sbit ds= P3^1; //接18B20 void delay(uint t) { uint k; while(t--) { for(k=0;
[单片机]
S3C2440 I2C总线协议 和 I2C总线下的AT24C02存储芯片分析 二十七
本节来学习I2C接口下的AT24C02存储芯片分析,本节学完后,再来学习Linux下如何使用I2C操作AT24C02 1、I2C通信介绍 它是由数据线SDA和时钟线SCL构成的串行总线,可发送和接受数据,是一个多主机的半双工通信方式。 每个挂接在总线上的器件都有个唯一的地址。 位速在标准模式下可达100kbit/s,在快速模式下可达400kbit/s,在高速模式下可达3.4Mbit/s。 2、I2C总线系统结构,如下图所示: 其中SCL时钟线的频率由主机提供,且从机不能主动来引起数据传输,必须等待主机先发信号才行,两个或多个主机同时发起数据传输时,可以通过冲突检测和仲裁来防止数据被破坏。 3、I2C时序
[单片机]
S3C2440 <font color='red'>I2C总线</font>协议 和 <font color='red'>I2C总线</font>下的AT24C02存储芯片分析 二十七
[C语言] sscanf如何实现sscanf_s?
在MCU中并不支持sscanf_s,所以我们只能通过sscanf实现。 char user = {0}; char pass = {0}; sscanf_s(buf, %s %s , user, pass); // 用 sscanf实现 sscanf(buf, %32 %32 , user, pass); C 库函数 int sscanf(const char *str, const char *format, …) 从字符串读取格式化输入。 声明 下面是 sscanf() 函数的声明。 int sscanf(const char *str, const char format, …)
[单片机]
如何写出好的单片机C语言代码
  程序能跑起来并不见得你的代码就是很好的c代码了,衡量代码的好坏应该从以下几个方面来看   1,代码稳定,没有隐患。   2,执行效率高。   3,可读性高。   4,便于移植。   下面发一些我在网上看到的技巧和自己的一些经验来和大家分享;   1、如果可以的话少用库函数,便于不同的mcu和编译器间的移植   2、选择合适的算法和数据结构   应该熟悉算法语言,知道各种算法的优缺点,具体资料请参见相应的参考资料,有很多计算机书籍上都有介绍。将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序执行的效率。.选择一种合适的数据结构也很重要,比
[单片机]
如何将汇编语言与C语言整合至DSP
本文将讨论如何将汇编语言程序代码整合到C语言中,以最大化性能以及程序设计人员生产力,内容涵盖了编译器惯例(convention)、内嵌(inlining)、内嵌函数(intrinsic)、缓存器连结(register binding)和除错策略。 随着DSP处理器性能的提升以及编译器最佳化技术的进步,曾经红极一时、仅用汇编语言编写DSP应用程序的作法已逐渐被淘汰。今天,几乎每个DSP应用程序都使用C语言程序代码和汇编程序码混合的方式。对于一些性能需求极高的关键功能,DSP工程师会继续使用高度最佳化的汇编程序码;而一些次要的功能现在也使用C语言编写,使程序代码更容易维护和移植。对于C语言和汇编程序码的结合,每位DSP
[嵌入式]
如何将汇编语言与<font color='red'>C语言</font>整合至DSP
小广播
热门活动
换一批
更多
最新嵌入式文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved