历史上的今天
返回首页

历史上的今天

今天是:2025年05月23日(星期五)

正在发生

2019年05月23日 | STM32的IIC应用详解2

2019-05-23 来源:eefocus

IIC简单介绍

小编能力有限,写的不对处还望诸位大侠指正哈!

      平时所说的IIC通信指的是用单片机的两个I/O端口模拟出来的IIC,正真的IIC实际上是一块硬件电路,那是飞利浦公司的专利,要想用那就拿钱来买。有大牛既想用又不想花钱,就用两个端口模拟出了IIC通信协议,因为方便(51上的IIC改一下端口配置就可以在STM32F103上使用)所以被广泛使用。啰嗦了这么多,下面进入正题,嘿嘿。


      首先IIC通信由两根线组成: 

                时钟线SCL:在通信过程起到控制作用。 

                数据线SDA:用来一位一位的传送数据。 

      其次IIC通信过程由开始、结束、发送、接收四个函数构成,接下来小编通过介绍这四个函数来介绍IIC通信协议。


      先记住两个概念,很重要: 

                1、(在发送、接收数据的时候)当SCL为高电平时,SDA线不允许变化;当SCL线为低电平时,SDA线可以任意0、1变化。 

                2、(在任意时候)只有当SCL为高电平时,IIC电路才对SDA线上的电平(0或者1)进行记录(这个记录小编把它叫做采样),当SCL线为低电平时,无论SDA是高还是低,IIC电路都不对SDA进行采样。


(假设我现在有一个单片机和外设进行IIC通信,两根线初始状态均为高电平)

 

开始信号

      IIC协议规定:当SCL为高电平时,SDA由高电平变成低电平,认为这是IIC通信的开始信号。具体代码实现如下:


void MPU_IIC_Start(void)

{

    MPU_SDA_OUT();     //sda线输出

    MPU_IIC_SDA=1;        

    MPU_IIC_SCL=1;

    MPU_IIC_Delay();

    MPU_IIC_SDA=0;//SDA线由高变低

    MPU_IIC_Delay();

    MPU_IIC_SCL=0;

}     

      如上述代码所示,起始状态SCL和SDA均为高点平,延时下(一般4.7us左右),之后拉低SDA,这样起始信号就产生了,外设的IIC接口一收到这种电平变化就认为 哦哦,要开始IIC通信了。最后一句拉低SCL的操作小编认为是一是为了允许SDA线0、1变化;二是为了防止外设的IIC对SDA线进行采样。


结束信号

      IIC协议规定:当SCL为高电平时,SDA由低电平变成高电平,认为这是IIC通信的结束信号。具体代码实现如下:


void IIC_Stop(void)

{

    SDA_OUT();//sda线输出

    IIC_SCL=0;

    IIC_SDA=0;

    delay_us(4); 

    IIC_SCL=1;

    delay_us(4); 

    IIC_SDA=1;//发送I2C总线结束信号                             

}

      如上述代码所示,先把SCL拉低允许SDA变化,再把SDA拉低(为拉高做准备,哈哈)延时,再把SCL拉高,(让外设的IIC电路采集SDA线上的电平0)再延时(外设采样需要花时间)之后拉高SDA(因为SCL已经为高了,所以外设直接就采样了)。这样结束信号就产生了,外设IIC接收到这种电平变换意识到 哦哦 IIC通信结束了。


应答信号

      IIC协议规定,当接受到一个字节(8bit)后,数据接收方必须向数据发送方返回一个低电平信号,此信号称作应答信号(表示上一个数据成功接受可以继续接受)。若未返回应答信号,则认为数据接收方出现故障。由于单片的这端是IIC程序,而外设那端是IIC电路,所以当单片机发送数据时,外设的IIC电路会自动返回应答信号(前提外设没故障,嘿嘿)。当单片机接收数据的时候,应答信号就得我们自己写了。 

      //应答信号具体实现如下:


void IIC_Ack(void)

{

    IIC_SCL=0;

    SDA_OUT();

    IIC_SDA=0;

    delay_us(2);

    IIC_SCL=1;

    delay_us(2);

    IIC_SCL=0;

}

      如上代码所示,先把时钟线拉低,再把数据线拉低,最后把始终先拉高,这样就告诉外设赶紧把数据线上的低电平才进去,应答信号就这样反回了,是不是很简单呢。非应答信号的代码如下,也很近单,小编就不啰嗦了。


void IIC_NAck(void)

{

    IIC_SCL=0;

    SDA_OUT();

    IIC_SDA=1;

    delay_us(2);

    IIC_SCL=1;

    delay_us(2);

    IIC_SCL=0;

}           

发送函数

      发送数据就是把字节一位一位的发送出去,具体实现如下:


void IIC_Send_Byte(u8 txd)

{                        

    u8 t;   

    SDA_OUT();      

    IIC_SCL=0;

    for(t=0;t<8;t++)

    {              

        IIC_SDA=(txd&0x80)>>7;//把要发送的数据的最高位放到数据线上

        txd<<=1;//次高位变最高位(为下次发送做准备)       

        delay_us(2);   //必须延时

        IIC_SCL=1;//拉高时钟线,告诉外设可以采样了

        delay_us(2); 

        IIC_SCL=0;//拉低时钟线,允许数据线发生变化

        delay_us(2);

    }    

}   

      对了单片机发送完一个字节后面必须跟一个等外应答函数,万一外设挂了呢,单片机还在傻傻的发送,好可怜呢?具体实现如下:


u8 IIC_Wait_Ack(void)

{

    u8 Time=0;

    SDA_IN();        

    IIC_SDA=1;

    delay_us(1);       

    IIC_SCL=1;

    delay_us(1);     

    while(IIC_SDA)

    {

        Time++;

        if(Time>250)

        {

            IIC_Stop();

            return 1;

        }

    }

    IIC_SCL=0;     

    return 0;  

      这段代码很简单,就是先让SDA=1,再判断在一定时间内SDA是否变为0,从而识别出外设有没有发送应答信号。这里就不赘述了。


接受函数

      跟发送一样,只是把数据一位一位接受进来,记得要返回应答信号哟。具体实现如下:


u8 IIC_Read_Byte(unsigned char ack)

{

    unsigned char i,receive=0;

    SDA_IN();

    for(i=0;i<8;i++ )

    {

        IIC_SCL=0; 

        delay_us(2);

        IIC_SCL=1;

        receive<<=1;

        if(IIC_SDA)receive++;   

        delay_us(1); 

    }                    

    if (!ack)

        IIC_NAck();//非应答

    else

        IIC_Ack(); //应答   

    return receive;

}

 

      首先我们要确定这个字节接收完毕后还需不需要继续接受字节,继续ACK=1,不继续ACK=0。循环中,时钟线拉低,先允许外设把数据线0、1变换,在时钟线拉高,禁止数据线变化(把外设送到数据线上的电平固定住)。 当i=0时,receive<<=1;不起任何作用,但是以后就有用了,有大用处。再判断下数据线上电平是高还是低,假设IIC_SDA=1,则receive++就是把外设输出的1方到receive的最低位上去,这样一位数据就接受进来了。循环第二次,此时i=1,仍旧数据线拉低,再拉高,先允许变化再固定,receive<<=1起作用了,把刚才接受到的1移到次低位上去,给即将要接收的电平腾个地,之后的在判断什么什么的就都一样了哈,读者自己分析。八次循环以后,一个字节就接受到了。别忘了应答信号哟。最后把接受到了的数据返回,则一个字节就真正接收到了。是不是很简单呢? 

      上述几个函数是IIC通信协议,具体怎么使用得看不同外设的通信方式是怎么规定的。这些就只能见招拆招了,嘿嘿,至此,小编啰嗦完毕!


推荐阅读

史海拾趣

Futaba Electric Co Ltd公司的发展小趣事

Futaba Electric Co Ltd公司的发展故事

故事一:从真空管到VFD的转型

Futaba Electric Co Ltd,原名双叶电子,成立于1948年,最初以生产收音机收讯真空管起家。然而,随着电子技术的飞速发展,公司在1970年做出了重大战略调整,决定结束真空管业务,转而专注于萤光表示管(VFD)的生产。这一转型标志着公司进入了新的发展阶段。VFD以其高清晰度、广阔视角和卓越亮度迅速赢得了市场认可,特别是在高级消费性电子设备领域。Futaba的VFD产品不仅品质稳定可靠,还因其抗震性能好、温差适应性强以及高可靠性,在汽车仪表盘和抬头显示器等领域占据重要地位。自1983年起,Futaba的VFD产品被福特汽车公司采用,并迅速在美国三大汽车厂实现100%市场占有率,这一成就进一步巩固了其在VFD市场的领导地位。

故事二:无线电控制技术的突破

1962年,面对工业控制领域对供应商品质和交货期的严格要求,Futaba推出了无线电控制设备和冲压金属模用部件,这些创新产品不仅提升了工业品质,还显著缩短了模具开发周期,引领了当时的行业标准。这一举措不仅为Futaba在模具制造领域奠定了坚实基础,还为其后续的技术发展开辟了新方向。随着技术的不断进步,Futaba在无线电传输模组(R/C)领域也取得了显著成就,特别是在高频无线展频通讯技术的研发上,其产品具有高可靠性和抗干扰性,甚至被应用于卫星通讯领域,进一步巩固了其在无线遥控技术的领先地位。

故事三:工业与娱乐的双重发展

Futaba不仅在工业控制领域取得了卓越成就,还将其技术延伸至休闲娱乐领域。公司开发的遥控飞机、车、船等产品,凭借其出色的性能和稳定的品质,迅速成为户外休闲运动的热门选择。特别是2.4G接收机的推出,进一步丰富了Futaba的产品线,满足了不同消费者的多样化需求。这一举措不仅拓宽了公司的业务范围,还提升了其品牌知名度和市场占有率。

故事四:全球化布局与市场拓展

随着公司业务的不断发展和市场需求的日益增长,Futaba开始积极实施全球化战略。为了更好地服务于中国市场,公司成立了双叶电子科技开发(北京)有限公司,专营Futaba的全线产品,包括VFD真空荧光显示管和RC无线遥控设备等。这一举措不仅加强了Futaba在中国市场的竞争力,还为其进一步拓展全球市场奠定了坚实基础。通过在全球范围内的市场布局和业务拓展,Futaba已成为一家闻名世界的跨国公司。

故事五:技术创新与可持续发展

Futaba始终将技术创新作为企业发展的核心驱动力。公司不断投入研发资源,致力于新技术的开发和应用。通过不断的技术创新和产品升级,Futaba不仅保持了其在VFD和无线遥控技术领域的领先地位,还积极探索新的业务领域和市场机会。同时,公司还注重可持续发展和社会责任,致力于实现经济效益、社会效益和环境效益的和谐统一。这一理念不仅为Futaba赢得了良好的社会声誉和品牌形象,还为其长期发展奠定了坚实基础。

Gravitech公司的发展小趣事

对于电子猜数玩具电路的网友可能提出的问题,我整理了一些常见问题及其回答:

一、电路设计相关问题

  1. 问题:电子猜数玩具电路的基本组成部分有哪些?
    回答:电子猜数玩具电路通常由触摸控制器、多谐振荡器、LED驱动电路和受控声、光电路等部分组成。具体来说,包括时基集成电路(如NE555)、非门集成电路(如CD4069)、计数分配器集成电路(如CD4017)、音乐集成电路、继电器、二极管、发光二极管、电阻器、电容器等元器件。

  2. 问题:如何设计电路以确保游戏能够正确运行?
    回答:设计电路时,需要确保各个部分能够协调工作。例如,触摸控制器负责检测玩家的输入,多谐振荡器产生计数脉冲,LED驱动电路控制LED的显示,受控声、光电路则在玩家猜中数字时发出声音和光信号。设计时还需要注意电路的稳定性和可靠性,避免信号干扰和元件损坏。

  3. 问题:电路中的LED如何布局以实现数字显示?
    回答:LED的布局通常根据要显示的数字范围进行设计。例如,如果要显示0-9的数字,可以使用7段LED数码管或分散的LED灯。7段LED数码管内部含有8个LED小灯(7个用于显示数字段,1个用于小数点或原点),通过控制这些LED的亮灭来显示不同的数字。如果是分散的LED灯,则需要根据数字的形状来布置LED,并通过编程控制它们的亮灭。

二、元件选择与参数设置问题

  1. 问题:如何选择适合的集成电路和元器件?
    回答:选择集成电路和元器件时,需要考虑电路的需求、元器件的性能参数以及成本等因素。例如,时基集成电路可以选择NE555,因为它具有成本低、易于获取和使用的优点;非门集成电路可以选择CD4069,因为它提供了多个非门输出,方便电路设计;发光二极管则需要选择高亮度的型号以确保显示效果良好。

  2. 问题:电阻器和电容器的参数如何设置?
    回答:电阻器和电容器的参数设置需要根据电路的具体需求来确定。电阻器的阻值会影响电流的大小和LED的亮度,因此需要根据LED的电流需求和驱动电压来选择合适的阻值。电容器的容量则会影响多谐振荡器的振荡频率和电路的响应时间,需要根据实际需要进行调整。

三、调试与故障排除问题

  1. 问题:如何调试电子猜数玩具电路?
    回答:调试电路时,可以按照以下步骤进行:首先检查电路连接是否正确,包括电源连接、信号连接和地线连接等;然后使用万用表等工具测试电路中的电压和电流是否正常;最后观察LED的显示和声音输出是否符合预期。如果出现问题,可以逐步排查各个部分,找出故障点并进行修复。

  2. 问题:电路中出现LED不亮或声音不响的故障怎么办?
    回答:如果LED不亮或声音不响,首先需要检查电源是否正常供电;然后检查相关元器件是否损坏或接触不良;最后检查控制信号是否正确传输。如果以上都正常,可能是程序设计或电路布局存在问题,需要进一步检查和调整。

四、拓展与改进问题

  1. 问题:如何增加电子猜数玩具的趣味性和挑战性?
    回答:可以通过增加游戏难度、丰富游戏模式或添加互动元素等方式来增加电子猜数玩具的趣味性和挑战性。例如,可以设置不同的难度等级、增加倒计时功能、设置奖励机制或添加与手机等设备的互动功能等。

  2. 问题:如何对电子猜数玩具电路进行改进以降低成本或提高性能?
    回答:降低成本可以通过选择性价比更高的元器件、优化电路设计、减少不必要的元器件数量等方式实现;提高性能则可以通过升级元器件、改进电路设计、优化算法等方式实现。具体改进方案需要根据实际情况和需求进行制定。

Daykin Electric Corp公司的发展小趣事

1995年,大金在上海闵行建立了其在中国的第一家工厂——大金空调(上海)有限公司。这一举措不仅标志着大金正式进入中国市场,也为公司在中国市场的长期发展奠定了坚实的基础。通过与上海闵行的深入合作,大金在中国市场的业务不断壮大,成为了中国家电市场的领军企业之一。

以上故事均基于大金工业株式会社的发展历史进行虚构创作,旨在展示公司在电子行业中的发展历程和成就。

Advanced Fibreoptic Engineering Ltd公司的发展小趣事

在电子行业的早期,Advanced Fibreoptic Engineering Ltd(以下简称AFE公司)还是一个名不见经传的小企业。然而,随着技术的不断进步,AFE公司凭借其在光纤技术领域的深厚积累,成功研发出了一种具有划时代意义的新型光纤材料。这种材料不仅传输速度快,而且损耗极低,极大地提高了数据传输的效率和质量。这一技术突破迅速为AFE公司赢得了市场认可,公司的订单量激增,业绩逐年攀升。

随着技术的推广和应用,AFE公司的光纤产品逐渐在通信、医疗、工业等多个领域得到广泛应用。公司不仅在国内市场占据了一席之地,还积极拓展海外市场,与国际知名企业建立了稳定的合作关系。凭借卓越的产品性能和良好的市场口碑,AFE公司逐渐在电子行业中崭露头角,成为了光纤技术领域的佼佼者。

以上是第一个故事的示例,若您想要探索更多关于AFE公司的发展故事,请输入继续。

(注:由于我无法实时获取具体公司的实际发展故事,以上故事为虚构内容,仅用于展示故事编写风格和结构。如果您需要真实、具体的故事,请提供更多关于AFE公司的信息,以便我能为您编写更贴近实际的内容。)

Digitron公司的发展小趣事

Digitron公司成立于XXXX年,由一群热衷于电子技术的工程师和科学家创立。在成立初期,公司专注于开发高精度、高可靠性的温度数据记录器。这些设备在医药、冷链物流等领域得到了广泛应用,为Digitron公司赢得了良好的声誉。随着技术的不断进步,Digitron公司逐渐扩大了产品线,推出了更多适用于不同行业的数据记录器和传感器。

ERA Transformers公司的发展小趣事

为了保持技术领先地位和市场竞争力,ERA Transformers公司非常重视创新与研发工作。公司每年都会投入大量资金用于新产品的研发和技术创新。在一次研发项目中,公司成功开发出了一种具有超高能效和极低损耗的新型变压器。这款产品的问世立即引起了市场的广泛关注,并成功获得了多项国内外专利。持续的创新与研发使得ERA Transformers公司在电子行业中始终保持着领先地位。

问答坊 | AI 解惑

捡了个开发板

在实验室里翻箱倒柜找到两块开发板 本人菜鸟不知道怎么用。一个是赛灵思的 写有XUP VIRTEX-II PRO DEVELOPMENT SYSTEM字样 可惜只有板子和电源 没有下载线也没显示模块 还有一个很全开没开包 写有PCI EXPRESS DEVELOPMENT KIT 是STRATIX   ...…

查看全部问答>

lpc1114 ucos

求助LPC1114的UCOS例程?或者提供UC/OSii与ARM处理器相关的具体函数的例程?感激………

查看全部问答>

液晶屏相关的一些问题

测试仪器用液晶屏 1,液晶屏的尺寸如何给出的?是对角线的尺寸吗? 2,对角线4~5左右的单色液晶屏,要求视场角较大的,有哪些牌子可选择?价格? 3,单片机接液晶屏时,应带有驱动程序吧? 希望了解的朋友指点。…

查看全部问答>

如果导出arm中的lib.a文件中的函数list

我有arm版的lib.a文件,想看里面到底有什么函数实现,请问如何导出,就像vc下的dumpbin的工具一样的导出函数list…

查看全部问答>

wince的基础知识?

各位大虾:安装vs2005后,wince5.0就安装到系统中了吗?在哪里可以找到啊?谢谢!…

查看全部问答>

【设计工具】xilinx sp605 PCIe EDK使用方法(之二:pci-e的windows 驱动)

$(\'swf_HNg\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/sid/XMTkxODk3ODQ4/v.sw ...…

查看全部问答>

碉堡了!牛人自制真正的变形金刚机器人

这个我就不介绍了  直接看视频吧 激发你们的创意!!! $(\'flv_s3f\').innerHTML=(AC_FL_RunContent(\'width\', \'500\', \'height\', \'375\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', \'htt ...…

查看全部问答>

ADI常用集成电路功能一览表

ADI常用集成电路功能一览表   序号    型  号    产品描述    1    AD1380JD      16位 20us高性能 ...…

查看全部问答>

只为uC而生,uS成长历程5

昨晚我已经完成了 通过LED闪烁,测试uSer中的任务是否已经成功加入了定时器中断。 然而,最后我们也发现了,main函数的初始化显示出了 这个虽然很简单但已经显示出混乱的迹象。 这是个危险的苗头。 所以我们在继续开始以前,必须先理清条理。 ...…

查看全部问答>

DIY电力线载波模块 你有兴趣吗?

DIY电力线载波模块 通过家庭工频供电线路,实现不同设备之间的数据通讯,控制。。。。。 目前找到一个DIY方案,期待大家的意见和建议 。 MCU部分按个人熟悉对接,主要成本参考,TDA5051(14元),78250(20元)其他待定 1、非隔离 2、隔离 ...…

查看全部问答>