IIC总线作为一种申行传输总线,其使用连线少,结构简单,是一种应用广泛的高性能总线方式。而Linux作为一个源代码公开、易于裁剪的操作系统,非常适合于嵌入式系统的应用。Linux操作系统下的嵌入式设备驱动,通过IIC总线,实现ARM与外围模块间的协同工作,有着广泛的应用。
1 IIC总线协议以及选用芯片功能
1.1 IIC总线的特点以及工作协议
IIC串行总线由两根信号线组成:一根双向传输的数据线SDA;另一根是时钟线SCL。IIC总线通过简单的结构即能实现半双工的同步数据传输。
IIC总线采用一主多从的运行机制,在同一时间只能有一台设备作为主设备,总线的运行由主设备控制,主设备控制数据的传送起始信号、发出时钟信号、从机地址信号、数据信号,由接收数据方在传送结束时发出应答信号,每个IIC总线上的设备都有一个唯一的地址,和主设备进行通信。
IIC总线时序如图1所示,在IIC总线使用过程中,传输开始和停止的条件如下:当SCL持续为“1”而SDA从“1”变为“0”时表示将要开始发送数据;而当SCL持续为“1”而SDA从“0”变为“1”表示停止发送数据。其中SDA线上的数据在时钟线SCL为“1”期间必须是稳定的,只有当SCL线上的时钟信号为低时数据线上的状态才能改变。
图1 IIC总线时序图
SDA线上的每个字节必须为8位,每次传输的字节数不限制,每发送1个字节都有1个ACK应答位。
1.2 选用ARM9芯片功能介绍
MCU采用某公司的S3C2440芯片,S3C2440A是某公司的一款基于ARM920T内核的16/32位RISC嵌入式微处理器,主要面向手持设备以及高性价比、低功耗的应用,且集成了1个IIC总线控制器,能够方便的与带有IIC接口外设的通信。
1.3 数字温度传感器DS1621的芯片功能介绍
DS1621是DALLAS公司生产的一种功能强大的数字式温度传感器和恒温控制器。接口与IIC总线兼容,一片控制器控制可控制多达8片的DS1621,工作电压为2.7~5.5 V,适用于低功耗应用系统。
DS1621可作为恒温控制器单独使用,也可通过2线接口在ARM的控制下完成温度的测量及计算。可以通过寄存器设置调整。DS1621无需外围元件即可测量温度,结果以9位数字量(两字节)给出,测量范围为-55~+155℃,精度为0.5℃:典型转换时间为1 s。
2 电路结构设计
设计采用了S3C2440作为电路中的主设备,控制IIC总线上从器件,由主设备控制IIC总线上的时钟信号以及各种数据信号。采用2片DS16 21作为IIC总线上的从设备,由于DS1621具备IIC总线接口,可直接与S3C2440的SDA和SCL脚相接,通过对DS1621的A2、A1、A0脚(5、6、7脚)组合输入不同的片选信号,可以确定其在IIC总线下工作的从机地址。因为IIC从设备一般都是MOS工艺,所以总线都有上拉电阻。工作时,通过IIC总线将DS1621设置为温度传感器功能和逐次获取数据的工作方式,电路的原理图设计如图2所示。
图2 电路的原理图
3 驱动程序设计
在Linux下的驱动程序将所有设备看作文件,驱动程序则为应用程序和硬件设备之间提供了操作访问的接口,使应用程序可以像操作普通文件一样对硬件设备操作访问。Linux内核把驱动程序划分为3种类型:字符设备、块设备和网络设备。其中,字符设备和块设备可以像文件一样被访问。DS1621的IIC驱动属于字符设备。
开始工作时,DS1621的工作方式是由片上的设置/状态寄存器来决定的:1)当通过IIC总线向DS1621写入读写设置命令ACh之后ARM发出的一字节将设置DS1621的工作方式,然后发出温度转换命令EEh,读温度命令AAh;2)DONE比特位表示工作在测温功能时,温度数据已转换完毕,保存在非易失性寄存器中;3)THF、TLF是DS1621作为恒温器时的状态标识位,当超过TH预置值或低于TL预置值时被置为1;4)1SHOT为一次模式位,该位为1时每次收到温度转换命令就执行一次温度转换,为0时将执行连续温度转换。DS1621寄存器配置如图3所示。
图3 DS1621寄存器配置
在调试过程中发现,若使用连续转换模式时,在极少数情况下出现数据明显不正确,故采用了逐次读取数据模式,即逐次配置DS1621的温度转换,逐次获取数据,并每次判断DS1621工作状态、数据范围和精度,从而获得了更加稳定、精确的实验结果。
驱动程序的功能包括:初始化以及释放硬件设备;S3C2440通过IIC总线对DS1621的控制寄存器进行配置;S3C2440读取DS1621寄存器内的温度数据,通过接口函数,将数据从内核空间发送到用户空间。驱动程序设计流程图如图4所示。
图4 驱动程序设计流程图
3.1 设备驱动的主要函数
对于字符设备,Linux内核对这些操作进行了统一的抽象,把它们定义在结构体file-operation中。通常,字符设备提供给应用程序的是一个流控制接口,主要包括open、release、read、ioctl等。
3.2 从器件,设备DS1621的初始化代码
3.3 IIC总线的初始化
对S3C2440的IIC控制器进行配置时需要用到的寄存器有:IICCON、IICSTAT、IICDS、IICADD。
IICCON:IIC总线控制寄存器;IICSTAT:IIC总线控制状态寄存器;HCDS:IIC总线接收/发送数据移位寄存器;IICADD:IIC总线地址寄存器。
1)S3C2440的GPE15为HCSDA,是串行数据线端口,GPE14为IICSCL,是串行时钟线;
2)将IICCON设置为:0xA7,表示传输过程中ACK应答使能,IIC的工作时钟为:HCCLK=fpclk/512,IlC总线中断使能,数据传输的时钟为:Tx clock=IICCLK/(IICCON[3:O]+1),约为400 k/s;
3)将IICSTAT置为:0x10,即使用从器件接收数据模式,数据输出/接收使能。
3.4 主器件从HC总线读数据
对于DS1621的寄存器配置,当通过IIC读取从器件DS1621的数据时,需要切换数据收发的方向,S3C2440先在主机发送数据模式下,向从器件DS1621发送从地址、DS1621内部寄存器的子地址和写信号位,然后在主机接收数据模式下,再次向从器件发送从地址和读信号位,并将子地址内的数据读回,其读数据操作如图5所示。
图5 IIC总线读数据操作
其中S为发送开始标志START,W为写信号位,R为读信号位,A为ACK应答信号,RS为重复开始信号REPEATED START,NA为主机收回数据后发送的NACK信号,P为停止信号STOP。
3.5 主器件向IIC总线写数据
3.6 S3C2440从DS1621获得温度数据,保存在内核空间并传送到用户空间
4 驱动的加载以及测试
应用程序将驱动从内核空间获得的数据保存下来,首先根据传回的DONE比特位判断温度传感器是否正在数据转换的过程中,如果是,则抛弃该数据,并打印数据不可用的信息;如果否,则接下来根据精度位判断小数点后的数据值,并将结果打印出来。
最后将驱动程序编译成模块,可以动态地加载、卸载设备驱动,不用重新启动系统就能查看驱动程序结果,方便了驱动的编写与调试工作。
经过动态编译后,得到目标文件iic.o、1621.o以及应用程序1621_iic_test,将文件下载到S3C2440中,通过#insmodiic.o、#insmod 1621.o加载模块,#./1621_iic_test运行测试程序,如图6所示。
图6 运行测试程序并打印信息
5 结论
本文以ARM920T内核的S3C2440为MCU与数字温度传感器模块DS1621搭建成多点数字测温电路。MCU通过IIC总线与DS1621进行通信,通过编写linux2.4版本下的IIC驱动程序,完成了S3C2440与带有IIC接口的外围芯片的通信,并实现了DS1621的配置和测温工作,正常工作中DS1621的典型温度转化时间为1 s,数据精度为0.5℃,典型的工作电压和电流值仅为3 V、10μA,具备较高的精度,且自身工作功耗小。通过增加DS1621的使用片数,还可扩展为一个低电压、低功耗的多点数字测温系统,可以广泛地应用在各种嵌入式系统中。驱动程序可使用于其他具有IlC接口的外围芯片的工作,也可将驱动应用于其他具有IIC接口的外围设备通信。