宣 慧,孙佳昊,程 实,蔡艳婧,胡传志
(1. 通富微电子股份有限公司,江苏 南通 226000;2. 江苏大学 计算机科学与通信工程学院,江苏镇江 212013;3. 南通大学 江苏省专用集成电路设计重点实验室,江苏 南通 226000;4. 南通大学 信息科学与技术学院,江苏 南通 226000;5. 江苏商贸职业技术学院 电子与信息学院,江苏 南通 226000)
I2C(inter-integrated circuit)总线,主要用于电路板内集成电路之间的连接,是由PHILIPS 公司开发的一种同步串行总线协议。I2C 总线因为协议成熟、引脚简单、传输速率高,已经成为世界性的工业标准,被大多数的芯片厂家采用。嵌入式系统中常用该总线来连接存储器[1-3]、传感器[4-5]和交互设备[6-7]等,因此I2C 总线实验就成了嵌入式系统实验教学中极重要的一个环节。I2C 总线编程要点在于掌握I2C 总线的数据帧格式,本文以TI 公司的TM4C123GH6PM 微控制器通过 I2C 总线接口读写 LM75A 温度传感器为例,以TivaWare 函数库中的I2C 总线API 函数为工具,研究I2C 总线的实验设计方法
为了使硬件效益最大和电路最简单,PHILIPS 公司开发了一个简单的双向两线总线,实现有效的 IC之间控制,该总线称为Inter IC 或I2C 总线[8],具有以下一些显著特征。
(1)只要求两条总线线路。一条串行数据线SDA,一条串行时钟线SCL。
(2)对各器件的寻址是软寻址方式,因此节点上没有必需的片选线[9]。
(3)是一个真正的多主机总线,带有冲突检测和仲裁,防止多个主机同时开始数据传输时破坏数据。
(4)串行的8 位双向数据传输,位速率在标准模式下可达100 kbit/s,快速模式下可达400 kbit/s,高速模式下可达3.4 Mbit/s。
I2C 总线上的设备分为主机(也称为主控器)和从机(也成为被控器),主机和从机都既可以是数据的发送方,也可以是数据的接收方。主机提供时钟信号,对总线时序进行控制,一般由微控制器担任主机;总线上除主机外的其他设备都是从机,一般来说是外围器件。主机通过从机地址访问从机,从机之间无法通信,任何数据传输都必须通过主机进行。在标准的I2C总线中,从机地址被定义为7 位,扩展I2C 总线允许10 位从机地址。
某一I2C 总线的系统结构如图1 所示,通过冲突检测,主机1 在查看总线空闲的情况下(即主机2 不在使用总线),发送一个开始信号,启动一次数据传输,先对从机寻址,再在总线上传输数据。数据以字节为单位,每传送一个字节后都必须跟一个应答位,由接收方回答,所以I2C 总线上的数据帧为8 加1 的格式。
图1 某一I2C 总线系统结构图
I2C 总线上的信号类型有以下5 个:
(1)开始信号(START),由主机产生,用来建立通信,从此总线将处于忙状态,直至结束通信;
(2)停止信号(STOP),由主机产生,用来结束通信,此后总线将处于空闲状态;
(3)重新开始信号(RESTART),由主机产生,用于改变上次开始时所建立的数据传输方向或目的从机;
(4)应答信号(ACK),由接收方产生,表示收到数据;
(5)非应答信号(NO ACK),由接收方产生,如果是从机作为接收方发送非应答信号,那么主机认为此次数据传输失败;如果是主机作为接收方发送非应答信号,那么从机认为数据传输结束,不再往总线上放数据。
I2C 总线上的数据帧格式如图 2 所示,一个标准的I2C 通信由4 部分组成:开始信号、从机地址传输、数据传输和停止信号。开始信号后的第一个字节为寻址字节,由7 位的从机地址加1 位方向位构成,方向位为0 表示主机写,方向位为1 表示主机读。每传送一个字节后都必须跟随一个应答位,每次通信的数据字节数没有限制,在全部数据传送结束后,由主机发送停止信号,结束通信。
图2 I2C 总线数据帧格式
实验中,以TI 公司的TM4C123GH6PM 微控制器作为主机,以LM75A 温度传感器作为从机,建立I2C总线连接,TM4C123GH6PM通过I2C 总线读取LM75A检测到的温度值。硬件电路见图3。
图3 硬件电路
TM4C123GH6PM 是 TI 公司的 TM4C123x 系列的微控制器,工作主频可达 80 MHz,采用 ARM Cortex-M4 浮点内核。配备有4 个I2C 模块,每个模块既可以作为主机,也可以作为从机,本实验中将I2C1模块用作主机,其中SDA 和SCL 为引脚PA7 和PA6的复用功能[10]。
LM75A 是一个带有I2C 总线接口的温度传感器,只能用作从机。微控制器可以通过 I2C 总线直接读写其内部寄存器:即温度寄存器、配置寄存器、THYST寄存器和TOS 寄存器[11]。
除了以上 4 个寄存器以外,LM75A 还有一个 8位的指针寄存器,高 6 位等于0,低2 位是其他4 个寄存器的指针值。指针寄存器对用户来说是不可访问的,但通过将指针数据放置到总线命令中可以用来选择需要读写的寄存器,其中00 是温度寄存器的指针,01 是配置寄存器的指针,10 是THYST 寄存器的指针,11 是TOS 寄存器的指针。
温度寄存器是16 位的只读寄存器,其中D0—D6为全零,D7—D15 保存当前温度值,这9 位以二进制补码数据的形式存放分辨率为0.5 ℃的温度值。其中D8—D15 为整数部分,D7 为小数部分。
LM75A 在总线上的7 位从机地址由两部分构成,其中低3 位由外部引脚A2、A1 和A0 的逻辑值定义,高4 位由内部硬连线预先设置为“1001”,因此地址范围是0X48—0X4F。实验中将 A2、A1 和A0 全部接地,因此地址为0X48。
通过 I2C 总线读取 LM75A 温度寄存器的过程:第1 步,MCU 发送开始信号,并寻址LM75A,写方式;第2 步,MCU 写指针寄存器(00,指向温度寄存器);第3 步,MCU 发送重新开始信号以改变数据传输方向,寻址LM75A,读方式;第4 步,MCU 读温度寄存器的高8 位;第5 步,MCU 读温度寄存器的低8 位;第6 步,MCU 发送停止信号,释放总线。读取温度寄存器见图4。
图4 读取温度寄存器
TivaWare 是一套广泛用于控制各种TM4C 系列器件外设功能的驱动包,即驱动函数库,其中的 I2C 库提供了一些用于I2C 操作的API 函数[12]。程序设计中将用到以下函数:
(1)I2CMasterSlaveAddrSet 用来发送开始信号、寻址字节;
(2)I2CMasterDataPut 将数据写入 I2C 主机数据寄存器;
(3)I2CMasterDataGet 从 I2C 主机数据寄存器读取数据;
(4)I2CMasterControl 控制主机模块的发送或接收;
(5)I2CMasterBusy 查看主机是否在忙于发送或接收数据;
参照图4 中读取温度寄存器的数据帧格式,设计函数Read_LM75A 如下:
实验中,每秒钟读一次LM75A,并将温度值(包括高位字节和低位字节)以十进制格式通过串行口发送到 PC 的超级终端。为了体现温度的变化,实验中用电吹风加热 LM75A 的周边环境,通过超级终端看到了缓慢递增的温度值,结果如图5 所示。
图5 超级终端输出的温度值
为了更清楚地表示温度,可以将温度寄存器的值转换为摄氏度,高位字节(MSB)为整数部分;低位字节的 D7 位为小数部分,所以低位字节(LSB)为128 即 0.5 ℃,为0 即 0.0 ℃,将整数部分加上小数部分即得到温度的摄氏度值。将图5 的输出结果转换为摄氏度值的结果见表1。
表1 超级终端输出的温度摄氏度值
实验结果表明,该实验实现了对I2C 总线的读写功能,该实验的设计方法对实践中I2C 总线的程序设计有一定借鉴意义。文中为了清楚阐明I2C 总线的读写时序,采用了查询等待的模式,实际应用中为了提高系统的实时性,应该采用中断模式。