摘要:在嵌入式应用领域,需要测量周围环境的质量对生产和工作进行监控和预警。通过比较设计方案,提出在嵌入式linux下,基于pxa310平台温湿度传感器的设计与实现方法。在linux操作系统下通过对驱动程序接口调用,完成温湿度数据读取和预警,并对linux驱动程序编写进行比较。实验表明,本方案硬件和软件设计切实可行,提高了环境测量的准确度和系统性能的实时性。
1、引言
在工业控制和工业生产领域中,传感器对于工业控制和生产环境的监控作用不言而喻。传统的传感器监控系统大都采用单片机控制,其监控的准确度和实时性不太令人满意。本文寻找到一套切实可行的传感器设计方案,其利用温湿度传感器芯片,基于pxa310硬件平台和linux操作系统,能有效监控现场温湿度变化。在周围环境发生变化,不能满足工作要求时,可以获取监控数据并提出预警,提高生产和工作环境检测的可靠性及实时性。
2、温湿度传感器电路设计
比较了一些传感器应用设计方案后,选用sht10芯片为嵌入式温湿度传感器的核心部件。它外围电路简便,相比其他传感器芯片(ds18b20)有其独到优势。
sth10每秒可进行3次温湿度测量,数据精度14bit并且工作稳定。其测量采用cmosens,所以在测量效率和精度上要好于ds18b20.ds18b20采用单总线控制方案(1-wire),大约每秒测量一次,9位数字式温度数据;只提供温度测量。其在生产环境检测要求严格时,就显得精度和功能有些不足。
2.1sht10简介
sht10是一款高度集成的温湿度传感器芯片,提供全量程标定数字输出。传感器包括一个电容性聚合体湿度敏感元件和一个用能隙材料制成的温度敏感元件,他们与一个14位a/d转换器以及一个串行接口电路设计在同一个芯片上面。其通过标定得到校准系数以程序形式储存在芯片otp内存中,并利用两线制串行接口与内部电压调整,使外围系统集成变得快速而简单。
2.2sht10工作原理
sht10芯片电源3.3v.传感器上电后,等待11ms来完成休眠状态。通信复位和启动传输命令后,发送一组测量命令('00000101'表示相对湿度rh,'00000011'表示温度t),控制器要等待测量结束。这个过程需要大约11/55/210ms,分别对应8/12/14bit测量。sht10通过下拉data至低电平,表示测量结束。控制器触发sck时钟前,必须等待这个数据备妥信号才能将测量数据正确读入。
测量和通讯结束后,sht10自动转入休眠模式。数据传送采用两线制串行接口(与i2c接口不兼容)。
2.3sht10电路原理图
sht10采用lcc封装,其data和sck引脚分别连接到pxa310的gpio78和gpio79.pxa310通过模拟时序方式实现对外围温湿度传感器的控制和数据读写操作。由于sht10对于温湿度灵敏度很高,在系统集成时应尽量远离发热源(如mcu、lcd等),否则测量结果会有所偏离;为sht10布线时,周围应尽量铺地减少周围器件对其的干扰。sht10电路原理图如图1所示。
图1sht10电路原理图
3、linux温湿度传感器驱动程序实现
单片机控制的传感器设备中,单片机通常是单线程运行。在进行温湿度测量时,单片机需要等待测试结果返回,其方法阻碍了其他测试和操作的同步执行。
在嵌入式linux系统中,驱动程序将测试任务送入任务队列,交出cpu控制权,继而进行其他实时任务运行,待内核空闲再进入任务队列完成传感器的测量,以此提高系统执行的效率和实时性。
3.1linux温湿度传感器设备加载
温湿度传感器使用linux内核的miscdevice数据结构在驱动程序初始化时将设备注册到内核。
miscdevice是字符设备,其主设备号为10,设备及设备接口函数定义如下所示。
驱动程序加载设备时将调用内核的注册函数。在linux2.4和2.6内核中,几乎所有linux驱动程序都依靠如下函数加载模块。
驱动程序初始化完成后,上层应用程序可以调用sht10_fops中的sht10_read函数进行温湿度的读取操作。
3.2linux温湿度传感器设备操作
进行数据读取前,首先要在驱动程序中开辟4个字节的数据空间,用于存放温度和湿度测量值。这里定义全局变量数据缓冲区为unsignedcharbuf[4].
读取sht10温湿度数据前,需要进行端口初始化和sht10复位操作,然后将任务送于任务队列并阻塞线程,当任务完成返回后再唤醒线程,将读到数据传递给上层应用程序做进一步处理。程序流程图和实现函数如图2所示。
图2驱动程序流程图。
上述函数中start_trans;write_byte;read_data;read_byte分别利用pxa310引脚模拟时序完成启动传输、写字节,读一位数据和读字节的操作。
内核tasklet_schedule()调度执行的tasklet,在获得运行机会之前只会调度一次,如果在运行时被调度,则完成后会被再次运行。
wait_for_completion()这个函数进行一个不可打断的等待,如果有代码调用它,并且没有完成这个任务,结果会是一个不可杀死的进程。copy_to_user()将内核空间数据传向上层用户空间,并让上层测试程序做进一步处理。
3.3linux温湿度传感器设备阻塞操作
由于温湿度传感器测量需要一定时间,为提高系统运行效率和实时性,在驱动程序中阻塞线程,交出内核控制权,等待操作完成后唤醒线程,提高系统利用率。complete()在函数中就是唤醒一个等待的读取线程。任务队列实现函数如下所示。
tasklet可以使测量操作在系统负荷不重时被调用,或是被立即执行,但始终不会晚于下一个cpuclock.
tasklet始终在中断期间运行,并且在调度他的同一cpu上运行。对比单片机系统,在单线程情况下,一般在sht10_read()中调用2次measure_sht10()来等待测量完成,测量效率依赖2次测量消耗的时间;但在linux驱动程序中,使用tasklet方式操作,2次测量过程不会对其他线程产生影响,在有其他实时事件需要及时处理时(如网络,视频),可以更有效提高驱动运行效率,降低对其他实时处理产生的影响。
4、温湿度传感器测试与验证
驱动程序完成以后,需要相应测试程序验证驱动程序编写的正确性。由于驱动程序中不能对数据进行浮点数运算,所以测试程序必须将驱动程序传递来的数据进行浮点数运算才能得到相应的温湿度值。
4.1温湿度传感器测试环境
在实验室常温下,测试程序多次调用驱动程序中读温湿度的函数接口获得测试数据,来验证设计的正确和可靠。并考虑实验室内常温下,相对湿度与温度具有非线性关系,计算湿度值时需要考虑温度的补偿关系,其关系如图3所示。
图3sorh转换到相对湿度。
为补偿湿度传感器的非线性以获取准确数据,并考虑实际温度与测试参考温度(25℃)不同,使用如下公式修正读数。
rhlinear是温度修正系数,rhtrue是相对湿度,sorh是传感器返回的湿度值。进行12bit湿度检测时,参数取值如下表所示。
表1湿度转换系数与温度补偿系数
由于能隙材料研发的温度传感器具有*线性,14bit温度值参考如下公式。
temperature=d1+d2xsot
温度转换系数取值如下表所示,sot是传感器返回的温度值。
表2温度转换系数
利用上述温湿度转换公式和系数可以得出温湿度测量值。
4.2温湿度传感器测试途径与效率验证
在测试程序中,考虑上述测量环境下温湿度之间的非线性,调用驱动程序的sht10_read函数将读到的温湿度数据返回上层测试程序进行浮点数运算,将计算值通过串口输出,达到测试验证的目的。测试程序的实现如下所示。
staticvoidcalc_sht10(float*humi,float*temp)
{
floatrh=*humi;
floatt=*temp;
floatrh_line;
floatrh_true;
t=t*d2+d1;//温度转换公式
rh_line=c3*rh*rh+c2*rh+c1;//相对湿度转换公式
rh_true=(t-25)*(t1+t2*rh)+rh_line;
//相对湿度温度补偿
if(rh_true>100)rh_true=100;//超出范围
if(rh_true<0.1)rh_true=0.1;
printf(humidityis:%.2f%rhn,rh_true);
printf(temperatureis:%.2f'cn,t);
}
intmain(intargc,char*argv[])//主函数
{
intfd;
floattemp,humi;//温湿度数据
charbuffer[4];//数据缓冲
fd=open(/dev/sht10,0);//打开文件
if(fd<0){//打开失败,退出
perror(opendevice/dev/sht10);
exit(1);
}
read(fd,buffer,sizeof(buffer));//读取温湿度值
temp=(float)((buffer[0]《8)|buf