历史上的今天
返回首页

历史上的今天

今天是:2025年03月19日(星期三)

正在发生

2021年03月19日 | 飞思卡尔16位单片机(十二)—— IIC模块测试

2021-03-19 来源:eefocus

一、IIC模块介绍

        目前市场上很多单片机都已经具有硬件IIC总线控制单元,这类单片机在工作时,IIC总线状态由硬件监测,无需用户介入,操作方便。


        IIC总线是双线、双向的串行总线,是与其它芯片交换数据的有效手段。XEP100单片机的IIC模块的功能框图如下图所示。

       IIC总线由一个双向的时钟线SCL和一个双向的数据线SDA组成。该实验通过IIC总线对片外EEPROM进行通信。可以向EEPROM写入和读取数据。单片机通信的对象是AT24C02,它是一个IIC接口的存储器,电路图如下图所示。AT24C02的存储空间的大小为2kbit。即为250字节。可以用于存储一些重要数据。在AT24C02中存储的数据,当系统掉电之后,依然可以存在。而不像程序中的变量,在掉电之后,数值就没了。

        IIC总线系统为数据传输使用串行数据线(SDA)和串行时钟线(SCL)。与其连接的所有器件必须具有开漏或开极输出。逻辑与功能通过外部上拉电阻在两条线上执行。这些电阻的值与系统相关。


一般地,标准通信由以下四部分组成:


· 启动信号


· 从机地址发送


· 数据传输


· 停止信号


停止信号不应与CPU停止指令相混淆。相应的信号见下图:

(1)启动信号


        当总线空闲时,没有主机占用总线(SCL和SDA线处于逻辑高电平),主机可以通过发送启动信号发起通信。启动信号定义为,当SCL在高电平时,SDA从高到低的跳变。该信号表示开始新的数据传输(每次数据传输可能包含几个字节的数据),并使所有从机退出空闲状态。


(2)从机地址发送


         启动信号发出后传输的第一个字节数据是主机发送的从机地址。这是R/W位之前的7位主叫地址。R/W位告知从机数据传输的方向。


1 = 读取传输,从机向主机传输数据


0 = 写入传输,主机向从机传输数据


当主机发送的地址与某从机地址匹配时,此从机发回应答位进行响应。通过将SDA第9个时钟拉低实现。系统中不能有两个地址相同的从机。如果IIC模块是主机,它就不能发送与其自己的从机地址相同的地址。IIC不能同时既是主机又是从机。但是,如果仲裁在寻址周期中丢失,IIC就重新返回到从机模式并正确运行,即便它正被另一个主机寻址。


(3)数据传输


        成功实现从机寻址之前,就可以按照主叫主机发送的R/W位指定的方向逐字节地进行数据传输。地址周期后的所有传输都被称为数据传输,即使它们包含从机的子地址报文。每个数据字节的长度均为8位。只有当SCL处于低时数据才可以更改,如果SCL处于高位,那么它必须保持稳定。SCL的一个时钟脉冲传输一个数据位,最高位被首先传输。每个数据字节后面都有一个第9(确认)位,该位由从机发出信号,通过把SDA拉低到第9个时钟实现。总之,一个完整数据传输需要9个时钟脉冲。如果从机在第9个位时间时未应答主机,从机必须保留SDA线在高电平。主机将未接收应答信号解释为不成功的数据传输。如果主机接收器在一个数据字节传输后未应答从机发送器,从机把这种情况理解为数据传输结束,并释放SDA 线。对于这两种情况,数据传输都被中止,主机会进行以下两种操作之一:


• 发送停止信号,放弃总线


• 发送重复启动信号,开始新呼叫


(4)停止信号


主机可以通过发送停止信号终止通信,以释放总线。然而,主机可以直接发送启动信号和呼叫命令,而无需首先发送停止信号。这被称为重复启动。停止信号的定义是SCL在逻辑1 位置时的从低到高的SDA 跳变。即便从机发出一个应答,主机也可以发送停止信号,此时从机必须释放总线。


(5)重复启动信号


        如上图所示,重复启动信号是在无需首先生成停止信号以终止通信的情况下发送的信号。该信号由主机用来与另外一个从机进行通信,或者在不同模式(传输/接收模式)中与同一从机进行通信,而不需要释放总线。


(6)仲裁程序


         IIC总线是真正的多主控总线,允许一个以上的主机连接到IIC上。如果两个甚至多个主机试图同时控制总线,那么就由时钟同步过程来决定总线时钟,总线低周期等于最长的时钟低段,总线高周期等于最短的时钟高段。竞争主机的相对优先级由数据仲裁过程确定,如果一个总线主机发出逻辑1,而另一个发出逻辑0,那么前者就丢失仲裁。失败的一方立即切换到从机接收模式,停止驱动SDA输出。在这种情况下,从主模式到从模式的转换不会生成停止条件。与此同时,会通过硬件设置一个状态位,表示仲裁丢失。


(7)时钟同步


        因为线与逻辑在SCL线上执行,所以SCL上的从高到低的跳变会影响连接到总线上的所有器件。节点开始计数它们的低态周期,当节点的时钟进入低态后,它将一直保持SCL线的低态,直到达到时钟高态。然而,如果另一个节点时钟仍处于低态时段,这时此节点时钟从低到高的变化就不会改变SCL线的状态。因此,经过同步的时钟SCL由具有最长低态周期的节点保持。低态周期较短的节点在该时段进入高态等待。当所有有关节点均已完成它们的低态周期时,同步时钟SCL线被释放和拉高。这样,节点时钟和SCL 线的状态之间就没有任何差异,所有节点开始计数它们的高态周期。第一个完成其高态周期的节点再次拉低SCL线。


        单片机向AT24C02写入一个字节的数据的操作如下图所示。

        单片机首先第一个字节向从器件发送访问的从器件的地址,和读写方式。这里为写入模式,则单片机接下来发送的字节为需要访问的存储器的地址,即数据需要写入的地址。第三个字节是需要向存储器写入的数据。


        单片机由AT24C02读取一个字节的数据的操作如下图所示。

        单片机首先第一个字节向从器件发送访问的从器件的地址,和读写方式。这里为写入数据模式,单片机接下来发送的字节为需要访问的存储器的地址,即单片机需要读取的地址。之后单片机再次产生一个开始信号,第三个字节单片机再次写入从器件地址,这次访问模式为读模式,第四个字节是存储器向单片机发送的数据。


二、例程测试

        在这个实验中,我们向AT24C02芯片中写入一个字节的数据,并读取,验证。代码主要部分是IIC模块的初始化,IIC发送和IIC读取的函数,初始化函数如下所示。


void INIT_IIC(void) 

{

  IIC0_IBFD = 0x94;   //总线时钟32MHz,设置SCL主频为100KHz

  IIC0_IBCR = 0x80;   //使能IIC模块,禁止中断

  IIC0_IBSR_IBAL = 1; //清除IBAL标志位  

}

这段代码主要是设置了IIC通信的频率,以及禁止了中断。


单片机通过IIC向AT24C02写入数据的函数如下所示。


void IIC_send(unsigned char addr,unsigned char data) 

{

  IIC0_IBCR_TXAK = 0;        //接收到数据后有应答

  IIC0_IBCR_TX_RX= 1;           //设置单片机为发送模式

  IIC0_IBCR_MS_SL = 1;         //设置单片机为主机模式,产生开始信号

  IIC0_IBSR_IBIF = 1;        //清除标志位

 

  IIC0_IBDR = 0b10100000;     //发送数据

  while(IIC0_IBSR_IBIF == 0) //等待发送完毕

  {   

  }

  IIC0_IBSR_IBIF = 1;

  while(IIC0_IBSR_RXAK)       //等待应答

  {   

  }

  

  IIC0_IBDR = addr;

  while(IIC0_IBSR_IBIF == 0) 

  {   

  }

  IIC0_IBSR_IBIF = 1;

  while(IIC0_IBSR_RXAK)

  {   

  }

  

  IIC0_IBDR = data;

  while(IIC0_IBSR_IBIF == 0) 

  {   

  }

  IIC0_IBSR_IBIF = 1;

  while(IIC0_IBSR_RXAK)

  {   

  }

 

  IIC0_IBSR_IBIF = 1;

  IIC0_IBCR_MS_SL = 0;         //设置单片机为从机模式,产生停止信号

}

在这个函数中,addr为需要写入的AT24C02内部的存储器地址,data为需要写入的数据。对照着上一节的AT24C02的通讯协议,可以看到通讯过程分为3个阶段,分别是发送从机地址、发送存储器地址、发送待写入数据。每一步都需要等待从机的应答。


        单片机通过IIC从AT24C02读取数据的函数如下所示。


unsigned char IIC_receive(unsigned char addr) 

{

  unsigned char data;

  IIC0_IBCR_TXAK = 0;             //接收到数据后有应答

  IIC0_IBCR_TX_RX = 1;               //设置单片机为发送模式

  IIC0_IBCR_MS_SL = 1;              //设置单片机为主机模式,产生开始信号

 

  IIC0_IBDR = 0b10100000;

 

  while(IIC0_IBSR_IBIF == 0) 

  {   

  }

  IIC0_IBSR_IBIF = 1;

 

  while(IIC0_IBSR_RXAK)

  {   

  }

 

  IIC0_IBDR = addr;

  while(IIC0_IBSR_IBIF == 0) 

  {   

  }

  IIC0_IBSR_IBIF = 1;

  while(IIC0_IBSR_RXAK)

  {   

  }

 

  IIC0_IBCR_RSTA = 1;             //产生重复开始信号

 

  IIC0_IBDR = 0b10100001;

  while(IIC0_IBSR_IBIF == 0) 

  {   

  }

  IIC0_IBSR_IBIF = 1;

  while(IIC0_IBSR_RXAK)

  {   

  }

 

  IIC0_IBCR_TX_RX = 0;               //设置单片机为发送模式

  IIC0_IBCR_TXAK = 1;             //接收到数据后无应答

 

  data = IIC0_IBDR;                //清空IICD寄存器,准备接收

 

  while(IIC0_IBSR_IBIF == 0) 

  {   

  }

  IIC0_IBSR_IBIF = 1;

  IIC0_IBCR_MS_SL = 0;

  

  data = IIC0_IBDR;                //读取接收到的数据

  return(data);

}

大家也可以对照着上面的AT24C02的通讯协议对代码进行分析,其中,addr是读取的地址,函数的返回值为读取到的数据。


这个程序的主函数,如下所示。


void main(void) {

  DisableInterrupts; 

  INIT_PLL();

  INIT_IIC();

  LEDCPU_dir=1;

  LEDCPU=0;

  EnableInterrupts; 

    

  LEDCPU = 1;                //熄灭指示灯

  

  delay();

  IIC_send(0x00,'A');

  

  delay();

 

  receivedata = IIC_receive(0x00);

  

  if(receivedata == 'A'); 

  {

    LEDCPU = 0;               //点亮指示灯

  }

  

  for(;;) 

  {

  }

}

在主函数中,单片机向AT24C02的0地址写入一个字节‘A’,然后读取0地址,判断读出来的数据是否为‘A’,如果正确,则点亮LED灯。  


将程序下载到单片机中,观看现象,与描述一致。

推荐阅读

史海拾趣

安普康(AMPCOM)公司的发展小趣事

在电子行业竞争日益激烈的背景下,安普康深知创新是企业发展的核心动力。因此,公司始终将研发投入作为重要战略之一。通过引进先进的生产设备和技术,安普康不断提升产品的品质和性能。同时,公司还积极与国内外知名企业和研究机构合作,共同开展技术研发和创新。这些努力使得安普康在光纤产品、布线产品等领域取得了多项专利,并成功推出了一系列具有市场竞争力的新产品。

CHIMEI(奇美)公司的发展小趣事

随着电子行业的快速发展,市场竞争也日益激烈。奇美公司深知创新是企业发展的核心动力,因此不断加大研发投入,推动技术创新和产品升级。公司研发团队积极探索新技术、新工艺和新材料的应用,推出了一系列具有创新性和竞争力的产品。这些产品不仅满足了客户的需求,还为公司开拓了新的市场领域。

驰兴电感(Coilank)公司的发展小趣事

驰兴电感始终坚持“品质第一”的原则,对产品的每一个细节都进行严格把控。公司引进了先进的生产设备和检测仪器,确保产品从原材料到成品的每一个环节都符合高标准的质量要求。这种对品质的执着追求,使得驰兴电感的产品在市场上赢得了良好的口碑,树立了高品质的品牌形象。

Avic公司的发展小趣事

Avic公司注重提升自主创新能力,不断加大在航空电子技术领域的研发投入。公司建立了一支高素质的研发团队,并积极引进国内外先进的研发设备和技术。这些措施有效提升了公司的创新能力,为公司在航空电子领域的持续发展提供了有力保障。

Greenliant公司的发展小趣事

GPS公司成立于2010年,初期专注于可再生能源存储解决方案的研发。随着全球对清洁能源需求的增长,GPS开发了一款高效能的锂离子电池储能系统,该系统能够在电力需求高峰时自动释放电能,平衡电网负载。这一技术突破迅速吸引了投资者的关注,并在几年内成为市场上的领先产品。GPS通过不断优化电池管理系统和智能控制算法,进一步提升了储能系统的效率和安全性,逐步在全球范围内建立了稳定的客户群体。

Gespac Inc公司的发展小趣事

GPS公司成立于2010年,初期专注于可再生能源存储解决方案的研发。随着全球对清洁能源需求的增长,GPS开发了一款高效能的锂离子电池储能系统,该系统能够在电力需求高峰时自动释放电能,平衡电网负载。这一技术突破迅速吸引了投资者的关注,并在几年内成为市场上的领先产品。GPS通过不断优化电池管理系统和智能控制算法,进一步提升了储能系统的效率和安全性,逐步在全球范围内建立了稳定的客户群体。

问答坊 | AI 解惑

飞利浦车灯 闪亮广州国际照明展

近日,飞利浦汽车照明在广州国际照明展上,展示了其最新技术成果及研究方向。   作为汽车照明的全球领袖,飞利浦的一举一动都让人关注。在这次展会上,飞利浦全方位的展示了其所驾驭汽车照明领域的各项技术,除了汽车头灯以外,产品系列涵盖了汽 ...…

查看全部问答>

成品LED摇摇棒电路图

1.这是一款浙江地区生产的摇摇棒成品电路图,根据实物绘出,单片机型号打磨掉了。 此款产品附带软件,可以在电脑上很方便的更改文字或者图片(COM口),10来元的产品,还算超值。 …

查看全部问答>

哪个片内AD转换的电压数值跳动很大?

本信息来自合作QQ群:AVR单片机学习与交流群(17727270) 群管理员在坛子里的ID:铜河   哪个片内AD转换的电压数值跳动很大,怎么处理下…

查看全部问答>

wince 软件分辨率问题,各位帮忙,谢谢

开发了一款软件,可是开发的时候模拟器的分辨率是640X480的,但最后公司拿来的硬件分辨率是320x240的,软件运行后只显示一个角,怎么办呢?…

查看全部问答>

执行到oeminit done就停止了。

遇到的问题,我加入一个驱动,执行到oeminit done就死了。 之后恢复到原来没有加入驱动之前的,仍然不行。重新编译也不行,重新安装wince,不行。 重新安装windows,不行。太奇怪了。哪位朋友了解的话,能否回复介绍一下?谢谢了。…

查看全部问答>

基于CAN控制电机转速——只用两个按键就可以实现电机的正反转

经过一段时间的学习,终于把CAN基本的东西给搞定,还有许多东西还要去学,在此先发一部分这段时间的学习内容,希望高手拍砖,让讨论抵御这大冷的冬天!! 在刚开始申请板子的时候是想采用232通信来完成电机的控制,但是拿到板子后发现该板子有好多 ...…

查看全部问答>

关于12864液晶显示

本帖最后由 paulhyde 于 2014-9-15 09:05 编辑 我的12864液晶屏不知道怎么的当显示“学”“电”时候就会出现一块黑点,字也显示不出来,求大侠赐教啊,其他的字都能正常显示,目前就发现这两个字显示不出来,就一块黑的。  …

查看全部问答>

数字PFC 控制方法----之 占空比

以前想了想,下午推导半天,开始想着占空比肯定与正弦波的相位有关,但是推导过后发现,占空的式中没有正弦波的影子。不知道是对是错,请大家指出。 注,推导适用于断续及临界模式。     [ 本帖最后由 dontium 于 2012-3-24 23:5 ...…

查看全部问答>

资深DSP软件工程师招聘

美国某知名上市公司招聘资深DSP软件工程师,工作地点在上海,要求有TI DSP音频算法经验以及TI OMAP和双核SoC软件开发经验,如有Linux的研发经验更好,年薪15-25W,如有兴趣,可以加qq447801729,或者msn帐号anqingqianjing2008@hotmail.com。…

查看全部问答>